Skip to content

Commit

Permalink
support newlines in repl
Browse files Browse the repository at this point in the history
  • Loading branch information
mattvr committed Jul 24, 2023
1 parent d8e16be commit 1037163
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/data.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChatCompletionRequest } from "./ai-types.ts";
import { genDescriptiveNameForChat } from "./prompts.ts";

export const VERSION = "0.3.1";
export const VERSION = "0.3.2";
export const AUTO_UPDATE_PROBABILITY = 0.1;

export type Config = {
Expand Down
2 changes: 1 addition & 1 deletion lib/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export const install = async (config: Config, isUpdate = false): Promise<{
}
}
else {
console.log(`Would you like to run the above command to install ShellGPT?\n%c(y)es [default]\n%c(n)o\n%cleave blank to use default`, 'color: green', 'color: unset', 'color: gray')
console.log(`Would you like to run the above command to complete ShellGPT installation?\n%c(y)es [default]\n%c(n)o\n%cleave blank to use default`, 'color: green', 'color: unset', 'color: gray')
const result = prompt('>')

if (result && (result.toLowerCase() === 'n' || result.toLowerCase() === 'no')) {
Expand Down
107 changes: 106 additions & 1 deletion mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,109 @@ if (repl && messageWasEmpty) {
await doStreamResponse();
}

let nextBuffer = "";
async function readInput() {
let strBuffer = "";
let arrayBuffer = new Uint8Array(1); // Buffer to hold byte data from stdin

let done = false;
let newline = false;

const updateFn = async () => {
// read from stdin
const n = await Deno.stdin.read(arrayBuffer)

let curBuffer = ""
const wasDone = done

if (n != null && n > 0) {
const text = new TextDecoder().decode(arrayBuffer)

for (const char of text) {
const code = char.charCodeAt(0);
if (code === 13 || code === 10) {
// carriage return or newline
newline = true
curBuffer += "\n";
await Deno.stdout.write(new TextEncoder().encode("\n"));
}
else if (code === 127) {
// backspace
const wasEmpty = strBuffer.length === 0;
curBuffer = curBuffer.slice(0, -1);
strBuffer = strBuffer.slice(0, -1);

if (!wasEmpty) {
await Deno.stdout.write(new TextEncoder().encode("\b \b"));
}
}
else {
// any other character
// console.warn("Z", char)
await Deno.stdout.write(arrayBuffer);
curBuffer += char;
newline = false;
}
}

if (wasDone) {
// We already finished reading this stream, so push to next reader
nextBuffer = curBuffer
}
else {
strBuffer += curBuffer
}

}
else {
done = true;
newline = true;
return;
}
};

nextBuffer = ""
Deno.stdin.setRaw(false)
Deno.stdin.setRaw(true, { cbreak: true })

await new Promise((resolve) => {
(
async () => {
strBuffer = ""
arrayBuffer = new Uint8Array(1)
while (!done) {
if (nextBuffer) {
// HACK: there may be another stdin reader which we want to push results from
// Use this instead of AbortController for now
strBuffer = `${nextBuffer}${strBuffer}`
nextBuffer = ""
}
const wasNewline = newline;
if (wasNewline) {
// wait for a moment for typing
setTimeout(() => {
if (!newline) {
return
}
done = true
resolve(true)
}, 250)
}
await updateFn();
if (wasNewline && newline) {
done = true;
}
}
resolve(true)
}
)()
})

Deno.stdin.setRaw(false)

return strBuffer
}

// Done, write it out
const flush = async () => {
streamResponse = null;
Expand Down Expand Up @@ -549,7 +652,9 @@ const flush = async () => {
await printCtrlSequence("blue");
await printCtrlSequence("bold");

const promptValue = prompt(`\n>`);
await Deno.stdout.write(new TextEncoder().encode(`\n> `));

const promptValue = await readInput();

// print reset ctrl sequence
await printCtrlSequence("reset");
Expand Down

0 comments on commit 1037163

Please sign in to comment.