33 lines
1.4 KiB
TypeScript
33 lines
1.4 KiB
TypeScript
export interface StatementDelimiterDocument {
|
|
readonly length: number;
|
|
sliceString(from: number, to: number): string;
|
|
}
|
|
|
|
type StatementDelimiterSource = string | StatementDelimiterDocument;
|
|
|
|
export function trailingStatementDelimiterPosition(source: StatementDelimiterSource, rangeTo: number): number | null {
|
|
let delimiterPos = rangeTo;
|
|
let lineBreakCount = 0;
|
|
while (delimiterPos < source.length) {
|
|
const char = sliceSource(source, delimiterPos, delimiterPos + 1);
|
|
if (!/\s/u.test(char)) break;
|
|
if (char === "\n" && ++lineBreakCount > 1) return null;
|
|
delimiterPos += 1;
|
|
}
|
|
return sliceSource(source, delimiterPos, delimiterPos + 1) === ";" ? delimiterPos : null;
|
|
}
|
|
|
|
export function cursorBelongsToTrailingStatementDelimiter(source: StatementDelimiterSource, rangeTo: number, cursorPos: number): boolean {
|
|
if (cursorPos < rangeTo) return false;
|
|
const delimiterPos = trailingStatementDelimiterPosition(source, rangeTo);
|
|
if (delimiterPos === null) return false;
|
|
if (cursorPos <= delimiterPos + 1) return true;
|
|
|
|
const afterDelimiter = sliceSource(source, delimiterPos + 1, cursorPos);
|
|
return !afterDelimiter.includes("\n") && afterDelimiter.trim() === "";
|
|
}
|
|
|
|
function sliceSource(source: StatementDelimiterSource, from: number, to: number): string {
|
|
return typeof source === "string" ? source.slice(from, to) : source.sliceString(from, to);
|
|
}
|