This commit is contained in:
parent
501f5e10d5
commit
8b44e250e2
@ -13,5 +13,6 @@
|
||||
"semiColons": true,
|
||||
"singleQuote": true
|
||||
},
|
||||
"nodeModulesDir": true
|
||||
"nodeModulesDir": true,
|
||||
"exclude": ["src/bun/"]
|
||||
}
|
||||
|
2
justfile
2
justfile
@ -14,7 +14,7 @@ check: deno-check bun-check
|
||||
|
||||
# Generate source docs
|
||||
docs:
|
||||
deno doc --html --name="Scroll" ./src/scroll.ts ./src/common/*.ts ./src/deno/mod.ts ./src/bun/mod.ts ./src/tsx/mod.ts
|
||||
deno doc --html --name="Scroll" ./src/common/*.ts ./src/common/**/*.ts
|
||||
|
||||
# Generate source docs and open in default browser
|
||||
open-docs: docs
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* The main entrypoint when using Bun as the runtime
|
||||
*/
|
||||
import { CommonRuntime, IRuntime, RunTimeType } from '../common/runtime/mod.ts';
|
||||
import { CommonRuntime, IRuntime, RunTimeType } from '../common/runtime.ts';
|
||||
|
||||
/**
|
||||
* The Bun Runtime implementation
|
||||
|
@ -2,17 +2,16 @@ import Ansi, * as _Ansi from './ansi.ts';
|
||||
import Buffer from './buffer.ts';
|
||||
import Document from './document.ts';
|
||||
import Editor from './editor.ts';
|
||||
import { FileLang } from './filetype/mod.ts';
|
||||
import { highlightToColor, HighlightType } from './highlight.ts';
|
||||
import { FileLang } from './filetype.ts';
|
||||
import Option, { None, Some } from './option.ts';
|
||||
import Position from './position.ts';
|
||||
import Row from './row.ts';
|
||||
|
||||
import FileType, * as FT from './filetype/mod.ts';
|
||||
import FileType, * as FT from './filetype.ts';
|
||||
import * as Fn from './fns.ts';
|
||||
import { defaultTerminalSize, SCROLL_TAB_SIZE } from './config.ts';
|
||||
import { getTestRunner } from './runtime/mod.ts';
|
||||
import { SearchDirection } from './types.ts';
|
||||
import { getTestRunner } from './runtime.ts';
|
||||
import { HighlightType, SearchDirection } from './types.ts';
|
||||
|
||||
import fs from 'node:fs';
|
||||
|
||||
@ -51,6 +50,7 @@ const fnTest = () => {
|
||||
isAsciiDigit,
|
||||
strlen,
|
||||
truncate,
|
||||
highlightToColor,
|
||||
} = Fn;
|
||||
|
||||
return {
|
||||
@ -78,6 +78,21 @@ const fnTest = () => {
|
||||
assertExists(noop);
|
||||
assertEquals(noop(), undefined);
|
||||
},
|
||||
'highlightToColor()': () => {
|
||||
[
|
||||
HighlightType.Number,
|
||||
HighlightType.Match,
|
||||
HighlightType.String,
|
||||
HighlightType.SingleLineComment,
|
||||
HighlightType.MultiLineComment,
|
||||
HighlightType.Keyword1,
|
||||
HighlightType.Keyword2,
|
||||
HighlightType.Operator,
|
||||
HighlightType.None,
|
||||
].forEach((type) => {
|
||||
assertTrue(highlightToColor(type).length > 0);
|
||||
});
|
||||
},
|
||||
'posSub()': () => {
|
||||
assertEquals(posSub(14, 15), 0);
|
||||
assertEquals(posSub(15, 1), 14);
|
||||
@ -201,24 +216,6 @@ const readKeyTest = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const highlightToColorTest = {
|
||||
'highlightToColor()': () => {
|
||||
[
|
||||
HighlightType.Number,
|
||||
HighlightType.Match,
|
||||
HighlightType.String,
|
||||
HighlightType.SingleLineComment,
|
||||
HighlightType.MultiLineComment,
|
||||
HighlightType.Keyword1,
|
||||
HighlightType.Keyword2,
|
||||
HighlightType.Operator,
|
||||
HighlightType.None,
|
||||
].forEach((type) => {
|
||||
assertTrue(highlightToColor(type).length > 0);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tests by module
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -708,7 +705,6 @@ const RowTest = {
|
||||
|
||||
testSuite({
|
||||
fns: fnTest(),
|
||||
highlightToColorTest,
|
||||
'readKey()': readKeyTest(),
|
||||
'ANSI utils': ANSITest(),
|
||||
Buffer: BufferTest,
|
||||
|
@ -117,6 +117,9 @@ const rgb = (
|
||||
ground: Ground = Ground.Fore,
|
||||
): string => textFormat([ground, AnsiColor.TypeRGB, r, g, b]);
|
||||
|
||||
/**
|
||||
* Ansi terminal codes and helper functions
|
||||
*/
|
||||
export const Ansi = {
|
||||
ClearLine: code('K'),
|
||||
ClearScreen: code('2J'),
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { strlen, truncate } from './fns.ts';
|
||||
import { getRuntime } from './runtime/mod.ts';
|
||||
import { getRuntime } from './runtime.ts';
|
||||
|
||||
/**
|
||||
* A simple string buffer
|
||||
*/
|
||||
class Buffer {
|
||||
#b = '';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Ansi from './ansi.ts';
|
||||
import { HighlightType, ITerminalSize } from './types.ts';
|
||||
|
||||
export const SCROLL_VERSION = '0.0.1';
|
||||
export const SCROLL_VERSION = '0.1.0';
|
||||
export const SCROLL_QUIT_TIMES = 3;
|
||||
export const SCROLL_TAB_SIZE = 4;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Row from './row.ts';
|
||||
import { FileType } from './filetype/mod.ts';
|
||||
import { FileType } from './filetype.ts';
|
||||
import { arrayInsert } from './fns.ts';
|
||||
import Option, { None, Some } from './option.ts';
|
||||
import { getRuntime, logWarning } from './runtime/mod.ts';
|
||||
import { getRuntime, logWarning } from './runtime.ts';
|
||||
import { Position, SearchDirection } from './types.ts';
|
||||
|
||||
export class Document {
|
||||
@ -52,7 +52,7 @@ export class Document {
|
||||
|
||||
const rawFile = await file.openFile(filename);
|
||||
rawFile.split(/\r?\n/)
|
||||
.forEach((row) => {
|
||||
.forEach((row: string) => {
|
||||
this.#rows.push(Row.from(row));
|
||||
});
|
||||
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
truncate,
|
||||
} from './fns.ts';
|
||||
import Option, { None, Some } from './option.ts';
|
||||
import { getRuntime, logDebug, logWarning } from './runtime/mod.ts';
|
||||
import { getRuntime, logDebug, logWarning } from './runtime.ts';
|
||||
import { ITerminalSize, Position, SearchDirection } from './types.ts';
|
||||
|
||||
/**
|
||||
|
5
src/common/filetype.ts
Normal file
5
src/common/filetype.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './filetype/base.ts';
|
||||
export * from './filetype/filetype.ts';
|
||||
|
||||
import FileType from './filetype/filetype.ts';
|
||||
export default FileType;
|
@ -1,4 +1,4 @@
|
||||
import { node_path as path } from '../runtime/mod.ts';
|
||||
import { node_path as path } from '../runtime.ts';
|
||||
import { AbstractFileType } from './base.ts';
|
||||
import { CFile } from './c.ts';
|
||||
import { CSSFile } from './css.ts';
|
||||
|
@ -1,5 +0,0 @@
|
||||
export * from './base.ts';
|
||||
export * from './filetype.ts';
|
||||
|
||||
import FileType from './filetype.ts';
|
||||
export default FileType;
|
@ -1,4 +1,6 @@
|
||||
import { KeyCommand } from './ansi.ts';
|
||||
import Ansi, { KeyCommand } from './ansi.ts';
|
||||
import { SCROLL_COLOR_SCHEME } from './config.ts';
|
||||
import { HighlightType } from './types.ts';
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
@ -57,6 +59,16 @@ export function readKey(raw: Uint8Array): string {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured ANSI formatting escape codes for the
|
||||
* type of syntax specified
|
||||
*
|
||||
* @param type The type of syntax to highlight
|
||||
*/
|
||||
export function highlightToColor(type: HighlightType): string {
|
||||
return SCROLL_COLOR_SCHEME.get(type) ?? Ansi.ResetFormatting;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Array manipulation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -1,38 +0,0 @@
|
||||
import Ansi from './ansi.ts';
|
||||
import { SCROLL_COLOR_SCHEME } from './config.ts';
|
||||
|
||||
/**
|
||||
* The type of Syntax being highlighted
|
||||
*/
|
||||
export enum HighlightType {
|
||||
/** No highlighting */
|
||||
None,
|
||||
/** Number literals */
|
||||
Number,
|
||||
/** Search results */
|
||||
Match,
|
||||
/** Character literals */
|
||||
Character,
|
||||
/** String literals */
|
||||
String,
|
||||
/** Single line comments */
|
||||
SingleLineComment,
|
||||
/** Multi-line comments */
|
||||
MultiLineComment,
|
||||
/** Primary keywords */
|
||||
Keyword1,
|
||||
/** Secondary keywords */
|
||||
Keyword2,
|
||||
/** Math/logic operators */
|
||||
Operator,
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured ANSI formatting escape codes for the
|
||||
* type of syntax specified
|
||||
*
|
||||
* @param type The type of syntax to highlight
|
||||
*/
|
||||
export function highlightToColor(type: HighlightType): string {
|
||||
return SCROLL_COLOR_SCHEME.get(type) ?? Ansi.ResetFormatting;
|
||||
}
|
@ -4,10 +4,15 @@ import {
|
||||
logError,
|
||||
logWarning,
|
||||
node_process as process,
|
||||
} from './runtime/mod.ts';
|
||||
} from './runtime.ts';
|
||||
import Editor from './editor.ts';
|
||||
|
||||
export async function main() {
|
||||
/**
|
||||
* The main runtime loop
|
||||
*
|
||||
* Only returns on error or quit
|
||||
*/
|
||||
export async function main(): Promise<void> {
|
||||
const rt = await getRuntime();
|
||||
const { term } = rt;
|
||||
|
||||
@ -18,7 +23,7 @@ export async function main() {
|
||||
});
|
||||
|
||||
// Setup error handler to log to file
|
||||
rt.onEvent('error', (error) => {
|
||||
rt.onEvent('error', (error: any) => {
|
||||
process.stdin.setRawMode(false);
|
||||
logError(JSON.stringify(error, null, 2));
|
||||
});
|
||||
|
@ -4,14 +4,23 @@
|
||||
export class Position {
|
||||
private constructor(public x: number = 0, public y: number = 0) {}
|
||||
|
||||
/**
|
||||
* Create a new `Position` at the specified location
|
||||
*/
|
||||
public static at(x: number, y: number): Position {
|
||||
return new Position(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new `Position` from an existing one
|
||||
*/
|
||||
public static from(p: Position): Position {
|
||||
return new Position(p.x, p.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new `Position` at the origin (0, 0)
|
||||
*/
|
||||
public static default(): Position {
|
||||
return new Position();
|
||||
}
|
||||
|
@ -3,16 +3,16 @@ import Ansi from './ansi.ts';
|
||||
import { SCROLL_TAB_SIZE } from './config.ts';
|
||||
import {
|
||||
arrayInsert,
|
||||
highlightToColor,
|
||||
isAsciiDigit,
|
||||
isSeparator,
|
||||
strChars,
|
||||
strlen,
|
||||
substr,
|
||||
} from './fns.ts';
|
||||
import { FileType } from './filetype/mod.ts';
|
||||
import { highlightToColor, HighlightType } from './highlight.ts';
|
||||
import { FileType } from './filetype.ts';
|
||||
import Option, { None, Some } from './option.ts';
|
||||
import { SearchDirection } from './types.ts';
|
||||
import { HighlightType, SearchDirection } from './types.ts';
|
||||
|
||||
const SINGLE_QUOTE = "'";
|
||||
const DOUBLE_QUOTE = '"';
|
||||
|
11
src/common/runtime.ts
Normal file
11
src/common/runtime.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export * from './runtime/file_io.ts';
|
||||
export * from './runtime/helpers.ts';
|
||||
export * from './runtime/log.ts';
|
||||
export * from './runtime/node.ts';
|
||||
export * from './runtime/runtime.ts';
|
||||
export * from './runtime/terminal_io.ts';
|
||||
export * from './runtime/test_base.ts';
|
||||
export { RunTimeType } from './types.ts';
|
||||
|
||||
import { CommonRuntime } from './runtime/runtime.ts';
|
||||
export default CommonRuntime;
|
@ -1,8 +1,11 @@
|
||||
import { appendFile, readFile, writeFile } from 'node:fs/promises';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
import { IFileIO } from './mod.ts';
|
||||
import { IFileIO } from './runtime.ts';
|
||||
|
||||
/**
|
||||
* File IO implementation using shared node APIs
|
||||
*/
|
||||
export const CommonFileIO: IFileIO = {
|
||||
openFile: async function (path: string): Promise<string> {
|
||||
const filePath = resolve(path);
|
||||
|
@ -3,8 +3,9 @@
|
||||
*/
|
||||
import { logError, logWarning } from './log.ts';
|
||||
import { node_path as path, node_process as process } from './node.ts';
|
||||
import { RunTimeType } from './runtime.ts';
|
||||
import { IRuntime, ITestBase } from '../types.ts';
|
||||
import { IRuntime } from './runtime.ts';
|
||||
import { ITestBase } from './test_base.ts';
|
||||
import { RunTimeType } from '../types.ts';
|
||||
|
||||
let scrollRuntime: IRuntime | null = null;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { noop } from '../fns.ts';
|
||||
import { SCROLL_LOG_FILE_PREFIX, SCROLL_LOG_FILE_SUFFIX } from '../config.ts';
|
||||
import { getRuntime } from './mod.ts';
|
||||
import { getRuntime } from './helpers.ts';
|
||||
|
||||
/**
|
||||
* The label for type/severity of the log entry
|
||||
@ -14,7 +14,11 @@ export enum LogLevel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic logging -
|
||||
* Basic logging
|
||||
*
|
||||
* @param s The string or data to display first
|
||||
* @param level The log severity
|
||||
* @param data Any additional data to display with the log entry
|
||||
*/
|
||||
export function log(
|
||||
s: unknown,
|
||||
@ -34,12 +38,31 @@ export function log(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a log entry of `LogLevel.Debug` severity
|
||||
*/
|
||||
export const logDebug = (s: unknown, data?: any) =>
|
||||
log(s, LogLevel.Debug, data);
|
||||
|
||||
/**
|
||||
* Make a log entry of `LogLevel.Info` severity
|
||||
*/
|
||||
export const logInfo = (s: unknown, data?: any) => log(s, LogLevel.Info, data);
|
||||
|
||||
/**
|
||||
* Make a log entry of `LogLevel.Notice` severity
|
||||
*/
|
||||
export const logNotice = (s: unknown, data?: any) =>
|
||||
log(s, LogLevel.Notice, data);
|
||||
|
||||
/**
|
||||
* Make a log entry of `LogLevel.Warning` severity
|
||||
*/
|
||||
export const logWarning = (s: unknown, data?: any) =>
|
||||
log(s, LogLevel.Warning, data);
|
||||
|
||||
/**
|
||||
* Make a log entry of `LogLevel.Error` severity
|
||||
*/
|
||||
export const logError = (s: unknown, data?: any) =>
|
||||
log(s, LogLevel.Warning, data);
|
||||
|
@ -1,10 +0,0 @@
|
||||
export * from './file_io.ts';
|
||||
export * from './helpers.ts';
|
||||
export * from './log.ts';
|
||||
export * from './node.ts';
|
||||
export * from './runtime.ts';
|
||||
export * from './terminal_io.ts';
|
||||
export * from './test_base.ts';
|
||||
|
||||
import { CommonRuntime } from './runtime.ts';
|
||||
export default CommonRuntime;
|
@ -1,6 +1,7 @@
|
||||
import { node_process as process } from './node.ts';
|
||||
import CommonFileIO from './file_io.ts';
|
||||
import CommonTerminalIO from './terminal_io.ts';
|
||||
import { RunTimeType } from '../types.ts';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Runtime adapter interfaces
|
||||
@ -14,16 +15,6 @@ export interface ITerminalSize {
|
||||
cols: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Which Typescript runtime is currently being used
|
||||
*/
|
||||
export enum RunTimeType {
|
||||
Bun = 'bun',
|
||||
Deno = 'deno',
|
||||
Tsx = 'tsx',
|
||||
Unknown = 'common',
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime-specific terminal functionality
|
||||
*/
|
||||
@ -131,6 +122,9 @@ export interface IRuntime {
|
||||
exit(code?: number): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base runtime using shared Node APIs
|
||||
*/
|
||||
export const CommonRuntime: IRuntime = {
|
||||
name: RunTimeType.Unknown,
|
||||
term: CommonTerminalIO,
|
||||
|
@ -2,6 +2,9 @@ import { node_process as process } from './node.ts';
|
||||
import { readKey } from '../fns.ts';
|
||||
import { ITerminal, ITerminalSize } from '../types.ts';
|
||||
|
||||
/**
|
||||
* Terminal IO using shared Node APIs
|
||||
*/
|
||||
export const CommonTerminalIO: ITerminal = {
|
||||
argv: (process.argv.length > 2) ? process.argv.slice(2) : [],
|
||||
inputLoop: async function* (): AsyncGenerator<Uint8Array, null> {
|
||||
|
@ -4,6 +4,10 @@
|
||||
import { deepStrictEqual, notStrictEqual, strictEqual } from 'node:assert';
|
||||
import Option from '../option.ts';
|
||||
|
||||
/**
|
||||
* The shared interface for tests, running on a different test
|
||||
* runner for each runtime
|
||||
*/
|
||||
export interface ITestBase {
|
||||
assertEquivalent(actual: unknown, expected: unknown): void;
|
||||
assertExists(actual: unknown): void;
|
||||
@ -20,6 +24,9 @@ export interface ITestBase {
|
||||
testSuite(testObj: any): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base testing implementation using Node assert API
|
||||
*/
|
||||
export abstract class AbstractTestBase implements Partial<ITestBase> {
|
||||
/**
|
||||
* The values (often objects) have all the same property values
|
||||
|
@ -1,13 +1,42 @@
|
||||
export { HighlightType } from './highlight.ts';
|
||||
export { Position } from './position.ts';
|
||||
export type { ITestBase } from './runtime/test_base.ts';
|
||||
export type {
|
||||
IFileIO,
|
||||
IRuntime,
|
||||
ITerminal,
|
||||
ITerminalSize,
|
||||
RunTimeType,
|
||||
} from './runtime/mod.ts';
|
||||
export type { IFileIO, IRuntime, ITerminal, ITerminalSize } from './runtime.ts';
|
||||
|
||||
/**
|
||||
* Which Typescript runtime is currently being used
|
||||
*/
|
||||
export enum RunTimeType {
|
||||
Bun = 'bun',
|
||||
Deno = 'deno',
|
||||
Tsx = 'tsx',
|
||||
Unknown = 'unknown',
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of Syntax being highlighted
|
||||
*/
|
||||
export enum HighlightType {
|
||||
/** No highlighting */
|
||||
None,
|
||||
/** Number literals */
|
||||
Number,
|
||||
/** Search results */
|
||||
Match,
|
||||
/** Character literals */
|
||||
Character,
|
||||
/** String literals */
|
||||
String,
|
||||
/** Single line comments */
|
||||
SingleLineComment,
|
||||
/** Multi-line comments */
|
||||
MultiLineComment,
|
||||
/** Primary keywords */
|
||||
Keyword1,
|
||||
/** Secondary keywords */
|
||||
Keyword2,
|
||||
/** Math/logic operators */
|
||||
Operator,
|
||||
}
|
||||
|
||||
/**
|
||||
* Which direction to search in the current document
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IFileIO } from '../common/runtime/mod.ts';
|
||||
import { IFileIO } from '../common/runtime.ts';
|
||||
|
||||
const DenoFileIO: IFileIO = {
|
||||
openFile: async function (path: string): Promise<string> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* The main entrypoint when using Deno as the runtime
|
||||
*/
|
||||
import { CommonRuntime, IRuntime, RunTimeType } from '../common/runtime/mod.ts';
|
||||
import { CommonRuntime, IRuntime, RunTimeType } from '../common/runtime.ts';
|
||||
import DenoTerminalIO from './terminal_io.ts';
|
||||
import DenoFileIO from './file_io.ts';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* The main entrypoint when using Tsx as the runtime
|
||||
*/
|
||||
import { CommonRuntime, IRuntime, RunTimeType } from '../common/runtime/mod.ts';
|
||||
import { CommonRuntime, IRuntime, RunTimeType } from '../common/runtime.ts';
|
||||
|
||||
/**
|
||||
* The Tsx Runtime implementation
|
||||
|
Loading…
Reference in New Issue
Block a user