Files
cinny/src/app/plugins/text-area/mods/Intent.ts
T

103 lines
3.4 KiB
TypeScript
Raw Normal View History

import { Cursor } from '../Cursor';
import { Operations } from '../Operations';
import { TextArea } from '../TextArea';
export class Intent {
public readonly textArea: TextArea;
public readonly operations: Operations;
public readonly size: number;
public readonly str: string;
private intentReg: RegExp;
constructor(size: number, textArea: TextArea, operations: Operations) {
this.textArea = textArea;
this.operations = operations;
this.size = size;
this.intentReg = /^\s*/;
this.str = '';
for (let i = 0; i < size; i += 1) this.str += ' ';
}
private lineIntent(cursor: Cursor): string {
const lines = this.textArea.cursorLines(cursor);
const selection = this.textArea.selection(lines);
const match = selection.match(this.intentReg);
if (!match) return '';
return match[0];
}
public moveForward(cursor: Cursor): Cursor {
const linesCursor = this.textArea.cursorLines(cursor);
const selection = this.textArea.selection(linesCursor);
const lines = selection.split('\n');
const intentLines = lines.map((line) => `${this.str}${line}`);
this.operations.insert(linesCursor, intentLines.join('\n'));
const addedIntentLength = lines.length * this.str.length;
return new Cursor(
cursor.start === linesCursor.start ? cursor.start : cursor.start + this.str.length,
cursor.end + addedIntentLength,
cursor.direction
);
}
public moveBackward(cursor: Cursor): Cursor {
const linesCursor = this.textArea.cursorLines(cursor);
const selection = this.textArea.selection(linesCursor);
const lines = selection.split('\n');
const intentLines = lines.map((line) => {
if (line.startsWith(this.str)) return line.substring(this.str.length);
return line.replace(this.intentReg, '');
});
const intentCursor = this.operations.insert(linesCursor, intentLines.join('\n'));
const firstLineTrimLength = lines[0].length - intentLines[0].length;
const lastLine = this.textArea.cursorLines(
new Cursor(intentCursor.end, intentCursor.end, 'none')
);
const start = Math.max(cursor.start - firstLineTrimLength, linesCursor.start);
const trimmedContentLength = linesCursor.length - intentCursor.length;
const end = Math.max(lastLine.start, cursor.end - trimmedContentLength);
return new Cursor(start, end, cursor.direction);
}
public addNewLine(cursor: Cursor): Cursor {
const lineIntent = this.lineIntent(cursor);
const line = `\n${lineIntent}`;
const insertCursor = this.operations.insert(cursor, line);
return new Cursor(insertCursor.end, insertCursor.end, 'none');
}
public addNextLine(cursor: Cursor): Cursor {
const lineIntent = this.lineIntent(cursor);
const line = `\n${lineIntent}`;
const currentLine = this.textArea.cursorLines(cursor);
const lineCursor = new Cursor(currentLine.end, currentLine.end, 'none');
const insertCursor = this.operations.insert(lineCursor, line);
return new Cursor(insertCursor.end, insertCursor.end, 'none');
}
public addPreviousLine(cursor: Cursor): Cursor {
const lineIntent = this.lineIntent(cursor);
const line = `\n${lineIntent}`;
const prevLine = this.textArea.prevLine(cursor);
const insertIndex = prevLine?.end ?? 0;
const lineCursor = new Cursor(insertIndex, insertIndex, 'none');
const insertCursor = this.operations.insert(lineCursor, line);
return new Cursor(insertCursor.end, insertCursor.end, 'none');
}
}