Partially implement SaveAs prompt (need to fix Deno)

This commit is contained in:
Timothy Warren 2023-11-27 10:25:30 -05:00
parent 820d383c3a
commit 759450222f
5 changed files with 54 additions and 19 deletions

View File

@ -110,20 +110,20 @@ testSuite({
}, },
Document: { Document: {
'Document.empty': () => { 'Document.empty': () => {
const doc = Document.empty(); const doc = Document.default();
assertEquals(doc.numRows, 0); assertEquals(doc.numRows, 0);
assertTrue(doc.isEmpty()); assertTrue(doc.isEmpty());
assertEquals(doc.row(0), null); assertEquals(doc.row(0), null);
}, },
'Document.insertRow': () => { 'Document.insertRow': () => {
const doc = Document.empty(); const doc = Document.default();
doc.insertRow(undefined, 'foobar'); doc.insertRow(undefined, 'foobar');
assertEquals(doc.numRows, 1); assertEquals(doc.numRows, 1);
assertFalse(doc.isEmpty()); assertFalse(doc.isEmpty());
assertInstanceOf(doc.row(0), Row); assertInstanceOf(doc.row(0), Row);
}, },
'Document.insert': () => { 'Document.insert': () => {
const doc = Document.empty(); const doc = Document.default();
assertFalse(doc.dirty); assertFalse(doc.dirty);
doc.insert(Position.at(0, 0), 'foobar'); doc.insert(Position.at(0, 0), 'foobar');
assertEquals(doc.numRows, 1); assertEquals(doc.numRows, 1);
@ -146,7 +146,7 @@ testSuite({
assertTrue(doc.dirty); assertTrue(doc.dirty);
}, },
'Document.delete': () => { 'Document.delete': () => {
const doc = Document.empty(); const doc = Document.default();
doc.insert(Position.default(), 'foobar'); doc.insert(Position.default(), 'foobar');
doc.delete(Position.at(3, 0)); doc.delete(Position.at(3, 0));
assertEquals(doc.row(0)?.toString(), 'fooar'); assertEquals(doc.row(0)?.toString(), 'fooar');

View File

@ -33,7 +33,7 @@ export const Ansi = {
GetCursorLocation: ANSI_PREFIX + '6n', GetCursorLocation: ANSI_PREFIX + '6n',
InvertColor: ANSI_PREFIX + '7m', InvertColor: ANSI_PREFIX + '7m',
ResetFormatting: ANSI_PREFIX + 'm', ResetFormatting: ANSI_PREFIX + 'm',
moveCursor: function moveCursor(row: number, col: number): string { moveCursor: (row: number, col: number): string => {
// Convert to 1-based counting // Convert to 1-based counting
row++; row++;
col++; col++;

View File

@ -3,13 +3,11 @@ import { getRuntime } from './runtime.ts';
import { arrayInsert, Position } from './mod.ts'; import { arrayInsert, Position } from './mod.ts';
export class Document { export class Document {
#filename: string | null;
#rows: Row[]; #rows: Row[];
dirty: boolean; dirty: boolean;
private constructor() { private constructor() {
this.#rows = []; this.#rows = [];
this.#filename = null;
this.dirty = false; this.dirty = false;
} }
@ -17,7 +15,7 @@ export class Document {
return this.#rows.length; return this.#rows.length;
} }
public static empty(): Document { public static default(): Document {
return new Document(); return new Document();
} }
@ -37,20 +35,15 @@ export class Document {
rawFile.split(/\r?\n/) rawFile.split(/\r?\n/)
.forEach((row) => this.insertRow(this.numRows, row)); .forEach((row) => this.insertRow(this.numRows, row));
this.#filename = filename;
this.dirty = false; this.dirty = false;
return this; return this;
} }
public async save() { public async save(filename: string) {
if (this.#filename === null) {
return;
}
const { file } = await getRuntime(); const { file } = await getRuntime();
await file.saveFile(this.#filename, this.rowsToString()); await file.saveFile(filename, this.rowsToString());
this.dirty = false; this.dirty = false;
} }

View File

@ -2,6 +2,7 @@ import Ansi, { KeyCommand } from './ansi.ts';
import Buffer from './buffer.ts'; import Buffer from './buffer.ts';
import Document from './document.ts'; import Document from './document.ts';
import { import {
getRuntime,
isControl, isControl,
ITerminalSize, ITerminalSize,
logToFile, logToFile,
@ -74,7 +75,7 @@ class Editor {
this.#cursor = Position.default(); this.#cursor = Position.default();
this.#offset = Position.default(); this.#offset = Position.default();
this.#document = Document.empty(); this.#document = Document.default();
} }
private get numRows(): number { private get numRows(): number {
@ -92,6 +93,20 @@ class Editor {
return this; return this;
} }
public async save(): Promise<void> {
if (this.#filename === '') {
const filename = await this.prompt('Save as: ');
if (filename === null) {
return;
}
this.#filename = filename;
}
await this.#document.save(this.#filename);
this.setStatusMessage(`${this.#filename} was saved to disk.`);
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Command/input mapping // Command/input mapping
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -106,8 +121,7 @@ class Editor {
// Ctrl-key chords // Ctrl-key chords
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
case ctrlKey('s'): case ctrlKey('s'):
await this.#document.save(); await this.save();
this.setStatusMessage(`${this.#filename} was saved to disk.`);
break; break;
case ctrlKey('q'): case ctrlKey('q'):
@ -210,6 +224,33 @@ class Editor {
return true; return true;
} }
public async prompt(p: string): Promise<string | null> {
const { term } = await getRuntime();
let res = '';
while (true) {
this.setStatusMessage(`${p}${res}`);
await this.refreshScreen();
const chunk = await term.inputLoop().next();
const char = chunk.value!;
// End the prompt
if (char === KeyCommand.Enter) {
this.setStatusMessage('');
if (res.length === 0) {
return null;
}
return res;
}
// Add to the prompt result
if (!isControl(char)) {
res += char;
}
}
}
/** /**
* Filter out any additional unwanted keyboard input * Filter out any additional unwanted keyboard input
* @param input * @param input

View File

@ -23,7 +23,6 @@ export async function main() {
// Create the editor itself // Create the editor itself
const editor = new Editor(terminalSize); const editor = new Editor(terminalSize);
editor.setStatusMessage('HELP: Ctrl-S = save | Ctrl-Q = quit');
// Process cli arguments // Process cli arguments
if (term.argv.length > 0) { if (term.argv.length > 0) {
@ -33,6 +32,8 @@ export async function main() {
} }
} }
editor.setStatusMessage('HELP: Ctrl-S = save | Ctrl-Q = quit');
// Clear the screen // Clear the screen
await editor.refreshScreen(); await editor.refreshScreen();