Skip to content
This repository has been archived by the owner on Apr 13, 2024. It is now read-only.

Commit

Permalink
Add transient history
Browse files Browse the repository at this point in the history
  • Loading branch information
KernelDeimos committed May 16, 2023
1 parent 115e8e2 commit 0594ac0
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 41 deletions.
61 changes: 29 additions & 32 deletions src/ansi-shell/readline.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@ const ReadlineProcessorBuilder = builder => builder
result: { value: '' },
cursor: { value: 0 },
},
// TODO: dormant configuration; waiting on ContextSignature
imports: {
out: {},
in_: {}
in_: {},
history: {}
}
}))
.variable('result', { getDefaultValue: () => '' })
.variable('cursor', { getDefaultValue: () => 0 })
.external('out', { required: true })
.external('in_', { required: true })
.external('history', { required: true })
.beforeAll('get-byte', async ctx => {
const { locals, externs } = ctx;

Expand Down Expand Up @@ -162,7 +165,7 @@ const ReadlineProcessorBuilder = builder => builder
const finalByte = locals.byte;
const controlSequence = vars.controlSequence.toArray();

// Log.log('controlSequence', controlSequence);
// Log.log('controlSequence', finalByte, controlSequence);

if ( ! CSI_HANDLERS.hasOwnProperty(finalByte) ) {
return;
Expand All @@ -187,10 +190,27 @@ const ReadlineProcessor = ReadlineProcessorBuilder(
new StatefulProcessorBuilder()
);

class HistoryManager {
constructor () {
this.items = [];
this.index = 0;
}

get () {
return this.items[this.index];
}

save (data) {
this.items[this.index] = data;
}
}

class Readline {
constructor (params) {
this.internal_ = {};
for ( const k in params ) this.internal_[k] = params[k];

this.history = new HistoryManager();
}

async readline (prompt) {
Expand All @@ -201,39 +221,16 @@ class Readline {

const {
result
} = await ReadlineProcessor.run({ out, in_ });
} = await ReadlineProcessor.run({
out, in_,
history: this.history
});

this.history.save(result);
this.history.index++;

return result;
}

// async readline (prompt) {
// const out = this.internal_.out;
// const in_ = this.internal_.in;

// out.write(prompt);

// let text = '';

// const decoder = new TextDecoder();

// while ( true ) {
// const byteBuffer = new Uint8Array(1);
// await in_.read(byteBuffer);

// const byte = byteBuffer[0];
// if ( byte === CHAR_LF ) {
// out.write('\n');
// break;
// }

// out.write(byteBuffer);
// const part = decoder.decode(byteBuffer);
// text += part;
// }

// // const text = await in_.readLine({ stream: out });
// return text;
// }
}

export default class ReadlineLib {
Expand Down
74 changes: 65 additions & 9 deletions src/ansi-shell/rl_csi_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,71 @@ export const PC_FN_HANDLERS = {
}
};

const save_history = ctx => {
const { history } = ctx.externs;
history.save(ctx.vars.result);
};

const correct_cursor = (ctx, oldCursor) => {
// TODO: make this work differently if oldCursor is not defined

const amount = ctx.vars.cursor - oldCursor;
ctx.vars.cursor = ctx.vars.result.length;
const L = amount < 0 ? 'D' : 'C';
if ( amount === 0 ) return;
const moveSequence = new Uint8Array([
consts.CHAR_ESC, consts.CHAR_CSI,
...(new TextEncoder().encode('' + Math.abs(amount))),
cc(L)
]);
ctx.externs.out.write(moveSequence);
};

const home = ctx => {
const amount = ctx.vars.cursor;
ctx.vars.cursor = 0;
const moveSequence = new Uint8Array([
consts.CHAR_ESC, consts.CHAR_CSI,
...(new TextEncoder().encode('' + amount)),
cc('D')
]);
if ( amount !== 0 ) ctx.externs.out.write(moveSequence);
};

const select_current_history = ctx => {
const { history } = ctx.externs;
home(ctx);
ctx.vars.result = history.get();
ctx.vars.cursor = ctx.vars.result.length;
const clearToEndSequence = new Uint8Array([
consts.CHAR_ESC, consts.CHAR_CSI,
...(new TextEncoder().encode('0')),
cc('K')
]);
ctx.externs.out.write(clearToEndSequence);
ctx.externs.out.write(history.get());
};

// --- CSI handlers: this is the last definition in this file ---
export const CSI_HANDLERS = {
[cc('A')]: CSI_INT_ARG(ctx => {
save_history(ctx);
const { history } = ctx.externs;

if ( history.index === 0 ) return;

history.index--;
select_current_history(ctx);
}),
[cc('B')]: CSI_INT_ARG(ctx => {
save_history(ctx);
const { history } = ctx.externs;

if ( history.index === history.items.length - 1 ) return;

history.index++;
select_current_history(ctx);
}),
// cursor back
[cc('D')]: CSI_INT_ARG(ctx => {
if ( ctx.vars.cursor === 0 ) {
Expand Down Expand Up @@ -115,14 +178,7 @@ export const CSI_HANDLERS = {
}),
// Home
[cc('H')]: ctx => {
const amount = ctx.vars.cursor;
ctx.vars.cursor = 0;
const moveSequence = new Uint8Array([
consts.CHAR_ESC, consts.CHAR_CSI,
...(new TextEncoder().encode('' + amount)),
cc('D')
]);
ctx.externs.out.write(moveSequence);
home(ctx);
},
// End
[cc('F')]: ctx => {
Expand All @@ -133,6 +189,6 @@ export const CSI_HANDLERS = {
...(new TextEncoder().encode('' + amount)),
cc('C')
]);
ctx.externs.out.write(moveSequence);
if ( amount !== 0 ) ctx.externs.out.write(moveSequence);
},
};

0 comments on commit 0594ac0

Please sign in to comment.