Basic deletion functionality

This commit is contained in:
Timothy Warren 2023-11-22 11:07:33 -05:00
parent a7f5fed9a3
commit b665ce8ce7
5 changed files with 68 additions and 32 deletions

View File

@ -18,6 +18,12 @@ const {
testSuite,
} = await getTestRunner();
const testKeyMap = (codes: string[], expected: string) => {
codes.forEach((code) => {
assertEquals(readKey(code), expected);
});
};
testSuite({
'ANSI::ANSI utils': {
'Ansi.moveCursor': () => {
@ -39,27 +45,21 @@ testSuite({
assertEquals(readKey(KeyCommand.ArrowUp), KeyCommand.ArrowUp);
assertEquals(readKey(KeyCommand.Home), KeyCommand.Home);
assertEquals(readKey(KeyCommand.Delete), KeyCommand.Delete);
// And pass through whatever else
assertEquals(readKey('foobaz'), 'foobaz');
},
'readKey Esc': () => {
['\x1b', Util.ctrlKey('l')].forEach((code) => {
assertEquals(readKey(code), KeyCommand.Escape);
});
},
'readKey Backspace': () => {
[Util.ctrlKey('h'), String.fromCodePoint(127)].forEach((code) => {
assertEquals(readKey(code), KeyCommand.Backspace);
});
},
'readKey Home': () => {
['\x1b[1~', '\x1b[7~', '\x1b[H', '\x1bOH'].forEach((code) => {
assertEquals(readKey(code), KeyCommand.Home);
});
},
'readKey End': () => {
['\x1b[4~', '\x1b[8~', '\x1b[F', '\x1bOF'].forEach((code) => {
assertEquals(readKey(code), KeyCommand.End);
});
},
'readKey Esc': () =>
testKeyMap(['\x1b', Util.ctrlKey('l')], KeyCommand.Escape),
'readKey Backspace': () =>
testKeyMap(
[Util.ctrlKey('h'), '\x7f'],
KeyCommand.Backspace,
),
'readKey Home': () =>
testKeyMap(['\x1b[1~', '\x1b[7~', '\x1b[H', '\x1bOH'], KeyCommand.Home),
'readKey End': () =>
testKeyMap(['\x1b[4~', '\x1b[8~', '\x1b[F', '\x1bOF'], KeyCommand.End),
},
Buffer: {
'Buffer exists': () => {
@ -137,6 +137,12 @@ testSuite({
assertEquals(doc.numRows, 2);
assertTrue(doc.dirty);
},
'Document.delete': () => {
const doc = Document.empty();
doc.insert(Position.default(), 'foobar');
doc.delete(Position.at(3, 0));
assertEquals(doc.row(0)?.toString(), 'fooar');
},
},
Editor: {
'new Editor': () => {

View File

@ -76,7 +76,7 @@ export function readKey(parsed: string): string {
return KeyCommand.Escape;
case ctrlKey('h'):
case String.fromCodePoint(127):
case '\x7f':
return KeyCommand.Backspace;
default:

View File

@ -1,7 +1,6 @@
import { chars } from './utils.ts';
import Row from './row.ts';
import { getRuntime } from './runtime.ts';
import { Position, SCROLL_TAB_SIZE } from './mod.ts';
import { Position } from './mod.ts';
export class Document {
#filename: string | null;
@ -61,12 +60,22 @@ export class Document {
this.appendRow(c);
} else {
this.#rows[at.y].insertChar(at.x, c);
this.updateRow(this.#rows[at.y]);
this.#rows[at.y].updateRender();
}
this.dirty = true;
}
public delete(at: Position): void {
const row = this.row(at.y);
if (row === null) {
return;
}
row.delete(at.x);
row.updateRender();
}
public row(i: number): Row | null {
return this.#rows[i] ?? null;
}
@ -74,15 +83,11 @@ export class Document {
public appendRow(s: string): void {
const at = this.numRows;
this.#rows[at] = new Row(s);
this.updateRow(this.#rows[at]);
this.#rows[at].updateRender();
this.dirty = true;
}
private updateRow(r: Row): void {
r.render = chars(r.toString().replace('\t', ' '.repeat(SCROLL_TAB_SIZE)));
}
private rowsToString(): string {
return this.#rows.map((r) => r.toString()).join('\n');
}

View File

@ -113,9 +113,17 @@ class Editor {
}
break;
case KeyCommand.Backspace:
case KeyCommand.Delete:
// TODO
this.#document.delete(this.#cursor);
break;
case KeyCommand.Backspace:
{
if (this.#cursor.x > 0 || this.#cursor.y > 0) {
this.moveCursor(KeyCommand.ArrowLeft);
this.#document.delete(this.#cursor);
}
}
break;
case KeyCommand.PageUp:

View File

@ -1,4 +1,4 @@
import { SCROLL_TAB_SIZE } from './mod.ts';
import { chars, SCROLL_TAB_SIZE } from './mod.ts';
import * as Util from './utils.ts';
/**
@ -44,6 +44,14 @@ export class Row {
}
}
public delete(at: number): void {
if (at >= this.size) {
return;
}
this.chars.splice(at, 1);
}
public cxToRx(cx: number): number {
let rx = 0;
let j = 0;
@ -60,6 +68,15 @@ export class Row {
public toString(): string {
return this.chars.join('');
}
public updateRender(): void {
const newString = this.chars.join('').replace(
'\t',
' '.repeat(SCROLL_TAB_SIZE),
);
this.render = chars(newString);
}
}
export default Row;