blots-editor 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type CursorCoordinates = {
|
|
2
|
+
line: number;
|
|
3
|
+
column: number;
|
|
4
|
+
};
|
|
5
|
+
export type TextCalcOptions = {
|
|
6
|
+
numberOfIndentationSpaces?: number;
|
|
7
|
+
cursorOffset?: number;
|
|
8
|
+
cursorHeightOffset?: number;
|
|
9
|
+
lineNumberRightSpacing?: number;
|
|
10
|
+
};
|
|
11
|
+
type ChangeListener = () => void;
|
|
12
|
+
export declare class TextCalculation {
|
|
13
|
+
private _lines;
|
|
14
|
+
private _cursor;
|
|
15
|
+
private _scrollTop;
|
|
16
|
+
private _listeners;
|
|
17
|
+
readonly numberOfIndentationSpaces: number;
|
|
18
|
+
readonly cursorOffset: number;
|
|
19
|
+
readonly cursorHeightOffset: number;
|
|
20
|
+
readonly lineNumberRightSpacing: number;
|
|
21
|
+
constructor(text: string, options?: TextCalcOptions);
|
|
22
|
+
onChange(listener: ChangeListener): () => void;
|
|
23
|
+
private _notify;
|
|
24
|
+
get lines(): string[];
|
|
25
|
+
get cursor(): CursorCoordinates;
|
|
26
|
+
get lineCount(): number;
|
|
27
|
+
getLineNumberWidth(): number;
|
|
28
|
+
getCurrentLineText(): string;
|
|
29
|
+
getCursorX(lineNumberWidth: number): number;
|
|
30
|
+
updateScroll(height: number): number;
|
|
31
|
+
insertChar(char: string): void;
|
|
32
|
+
newLine(): void;
|
|
33
|
+
moveRight(): void;
|
|
34
|
+
moveLeft(): void;
|
|
35
|
+
moveUp(): void;
|
|
36
|
+
moveDown(): void;
|
|
37
|
+
backspace(): void;
|
|
38
|
+
indent(): void;
|
|
39
|
+
outdent(): void;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import stringWidth from "string-width";
|
|
2
|
+
export class TextCalculation {
|
|
3
|
+
_lines;
|
|
4
|
+
_cursor;
|
|
5
|
+
_scrollTop;
|
|
6
|
+
_listeners = new Set();
|
|
7
|
+
numberOfIndentationSpaces;
|
|
8
|
+
cursorOffset;
|
|
9
|
+
cursorHeightOffset;
|
|
10
|
+
lineNumberRightSpacing;
|
|
11
|
+
constructor(text, options = {}) {
|
|
12
|
+
this._lines = text ? text.split(/\r?\n/) : [];
|
|
13
|
+
this._cursor = { line: 0, column: 0 };
|
|
14
|
+
this._scrollTop = 0;
|
|
15
|
+
this.numberOfIndentationSpaces = options.numberOfIndentationSpaces ?? 2;
|
|
16
|
+
this.cursorOffset = options.cursorOffset ?? 0;
|
|
17
|
+
this.cursorHeightOffset = options.cursorHeightOffset ?? 2;
|
|
18
|
+
this.lineNumberRightSpacing = Math.max(0, options.lineNumberRightSpacing ?? 1);
|
|
19
|
+
}
|
|
20
|
+
onChange(listener) {
|
|
21
|
+
this._listeners.add(listener);
|
|
22
|
+
return () => {
|
|
23
|
+
this._listeners.delete(listener);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
_notify() {
|
|
27
|
+
this._listeners.forEach((fn) => fn());
|
|
28
|
+
}
|
|
29
|
+
get lines() {
|
|
30
|
+
return this._lines;
|
|
31
|
+
}
|
|
32
|
+
get cursor() {
|
|
33
|
+
return this._cursor;
|
|
34
|
+
}
|
|
35
|
+
get lineCount() {
|
|
36
|
+
return this._lines.length;
|
|
37
|
+
}
|
|
38
|
+
getLineNumberWidth() {
|
|
39
|
+
return Math.max(stringWidth(String(this._lines.length - 1)), 1);
|
|
40
|
+
}
|
|
41
|
+
getCurrentLineText() {
|
|
42
|
+
return this._lines[this._cursor.line] ?? "";
|
|
43
|
+
}
|
|
44
|
+
getCursorX(lineNumberWidth) {
|
|
45
|
+
const text = this.getCurrentLineText();
|
|
46
|
+
const clamped = Math.max(0, Math.min(text.length, this._cursor.column));
|
|
47
|
+
const visual = stringWidth(text.slice(0, clamped));
|
|
48
|
+
return (visual + lineNumberWidth + this.lineNumberRightSpacing + this.cursorOffset);
|
|
49
|
+
}
|
|
50
|
+
updateScroll(height) {
|
|
51
|
+
const effectiveH = height > 0 ? height : this._lines.length;
|
|
52
|
+
let vs = this._scrollTop;
|
|
53
|
+
if (this._cursor.line < vs) {
|
|
54
|
+
vs = this._cursor.line;
|
|
55
|
+
}
|
|
56
|
+
else if (this._cursor.line >= vs + effectiveH) {
|
|
57
|
+
vs = this._cursor.line - effectiveH + 1;
|
|
58
|
+
}
|
|
59
|
+
const maxScroll = Math.max(0, this._lines.length - effectiveH);
|
|
60
|
+
vs = Math.max(0, Math.min(vs, maxScroll));
|
|
61
|
+
this._scrollTop = vs;
|
|
62
|
+
return vs;
|
|
63
|
+
}
|
|
64
|
+
insertChar(char) {
|
|
65
|
+
const { line, column } = this._cursor;
|
|
66
|
+
this._lines[line] =
|
|
67
|
+
this._lines[line].slice(0, column) +
|
|
68
|
+
char +
|
|
69
|
+
this._lines[line].slice(column);
|
|
70
|
+
this._cursor = { line, column: column + char.length };
|
|
71
|
+
this._notify();
|
|
72
|
+
}
|
|
73
|
+
newLine() {
|
|
74
|
+
const { line, column } = this._cursor;
|
|
75
|
+
const current = this._lines[line];
|
|
76
|
+
this._lines[line] = current.slice(0, column);
|
|
77
|
+
this._lines.splice(line + 1, 0, current.slice(column));
|
|
78
|
+
this._cursor = { line: line + 1, column: 0 };
|
|
79
|
+
this._notify();
|
|
80
|
+
}
|
|
81
|
+
moveRight() {
|
|
82
|
+
const maxCol = this._lines[this._cursor.line]?.length ?? 0;
|
|
83
|
+
this._cursor = {
|
|
84
|
+
line: this._cursor.line,
|
|
85
|
+
column: Math.min(this._cursor.column + 1, maxCol),
|
|
86
|
+
};
|
|
87
|
+
this._notify();
|
|
88
|
+
}
|
|
89
|
+
moveLeft() {
|
|
90
|
+
this._cursor = {
|
|
91
|
+
line: this._cursor.line,
|
|
92
|
+
column: Math.max(this._cursor.column - 1, 0),
|
|
93
|
+
};
|
|
94
|
+
this._notify();
|
|
95
|
+
}
|
|
96
|
+
moveUp() {
|
|
97
|
+
const newLine = Math.max(this._cursor.line - 1, 0);
|
|
98
|
+
const maxCol = this._lines[newLine]?.length ?? 0;
|
|
99
|
+
this._cursor = {
|
|
100
|
+
line: newLine,
|
|
101
|
+
column: Math.min(maxCol, this._cursor.column),
|
|
102
|
+
};
|
|
103
|
+
this._notify();
|
|
104
|
+
}
|
|
105
|
+
moveDown() {
|
|
106
|
+
const newLine = Math.min(this._cursor.line + 1, this._lines.length - 1);
|
|
107
|
+
const maxCol = this._lines[newLine]?.length ?? 0;
|
|
108
|
+
this._cursor = {
|
|
109
|
+
line: newLine,
|
|
110
|
+
column: Math.min(maxCol, this._cursor.column),
|
|
111
|
+
};
|
|
112
|
+
this._notify();
|
|
113
|
+
}
|
|
114
|
+
backspace() {
|
|
115
|
+
const { line, column } = this._cursor;
|
|
116
|
+
if (column === 0 && line !== 0) {
|
|
117
|
+
const prevLen = this._lines[line - 1].length;
|
|
118
|
+
this._lines[line - 1] += this._lines[line];
|
|
119
|
+
this._lines.splice(line, 1);
|
|
120
|
+
this._cursor = { line: line - 1, column: prevLen };
|
|
121
|
+
}
|
|
122
|
+
else if (column > 0) {
|
|
123
|
+
this._lines[line] =
|
|
124
|
+
this._lines[line].slice(0, column - 1) +
|
|
125
|
+
this._lines[line].slice(column);
|
|
126
|
+
this._cursor = { line, column: column - 1 };
|
|
127
|
+
}
|
|
128
|
+
this._notify();
|
|
129
|
+
}
|
|
130
|
+
indent() {
|
|
131
|
+
const { line } = this._cursor;
|
|
132
|
+
const spaces = " ".repeat(this.numberOfIndentationSpaces);
|
|
133
|
+
this._lines[line] = spaces + this._lines[line];
|
|
134
|
+
this._cursor = {
|
|
135
|
+
line,
|
|
136
|
+
column: this._cursor.column + this.numberOfIndentationSpaces,
|
|
137
|
+
};
|
|
138
|
+
this._notify();
|
|
139
|
+
}
|
|
140
|
+
outdent() {
|
|
141
|
+
const { line } = this._cursor;
|
|
142
|
+
const current = this._lines[line];
|
|
143
|
+
const leadingSpaces = current.match(/^ */)?.[0].length || 0;
|
|
144
|
+
const n = this.numberOfIndentationSpaces;
|
|
145
|
+
if (leadingSpaces >= n) {
|
|
146
|
+
this._lines[line] = current.slice(n);
|
|
147
|
+
this._cursor = {
|
|
148
|
+
line,
|
|
149
|
+
column: Math.max(0, this._cursor.column - n),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
else if (leadingSpaces > 0) {
|
|
153
|
+
this._lines[line] = current.slice(leadingSpaces);
|
|
154
|
+
this._cursor = {
|
|
155
|
+
line,
|
|
156
|
+
column: Math.max(0, this._cursor.column - leadingSpaces),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
this._notify();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -1,42 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
export type EditorContext = {
|
|
3
|
-
/**
|
|
4
|
-
* Used to externally get all current text, etc.
|
|
5
|
-
*/
|
|
6
3
|
onChance: () => void;
|
|
7
|
-
/**
|
|
8
|
-
* Original text, including some special symbols
|
|
9
|
-
*/
|
|
10
4
|
value: string;
|
|
11
|
-
/**
|
|
12
|
-
* What is the right margin of the left line number,
|
|
13
|
-
* which also affects the cursor position
|
|
14
|
-
*/
|
|
15
5
|
lineNumberRightSpacing?: number;
|
|
16
|
-
/**
|
|
17
|
-
* Cursor offset. The default value is 1.
|
|
18
|
-
* It is also recommended to be 1. Otherwise,
|
|
19
|
-
* it will cause the cursor visual position to exceed the limit.
|
|
20
|
-
*/
|
|
21
6
|
cursorOffset?: number;
|
|
22
|
-
/**
|
|
23
|
-
* Cursor height offset, default is 2
|
|
24
|
-
*/
|
|
25
7
|
cursorHeightOffset?: number;
|
|
26
|
-
/**
|
|
27
|
-
* Number of indentation spaces
|
|
28
|
-
* default is 2
|
|
29
|
-
*/
|
|
30
8
|
numberOfIndentationSpaces?: number;
|
|
31
9
|
};
|
|
32
|
-
export type CursorCoordinates
|
|
33
|
-
|
|
34
|
-
* How many rows are currently in
|
|
35
|
-
*/
|
|
36
|
-
line: number;
|
|
37
|
-
/**
|
|
38
|
-
* How many columns are currently in
|
|
39
|
-
*/
|
|
40
|
-
column: number;
|
|
41
|
-
};
|
|
42
|
-
export declare function Editor({ value: line, lineNumberRightSpacing, cursorOffset, cursorHeightOffset, numberOfIndentationSpaces, }: EditorContext): React.JSX.Element;
|
|
10
|
+
export type { CursorCoordinates } from "../text/text-based-calculation.js";
|
|
11
|
+
export declare function Editor({ value: initialText, lineNumberRightSpacing, cursorOffset, cursorHeightOffset, numberOfIndentationSpaces, }: EditorContext): React.JSX.Element;
|
package/dist/core/view/editor.js
CHANGED
|
@@ -1,192 +1,55 @@
|
|
|
1
|
-
import { Box, Text, useCursor } from "ink";
|
|
1
|
+
import { Box, Text, useBoxMetrics, useCursor } from "ink";
|
|
2
2
|
import { useKeyboard } from "ink-cartridge";
|
|
3
|
-
import React, { useEffect,
|
|
4
|
-
import
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const [value, setValue] = useState(() => {
|
|
21
|
-
const lines = splitTextByLines(line);
|
|
22
|
-
return lines;
|
|
23
|
-
});
|
|
24
|
-
const [cursor, setCursor] = useState({
|
|
25
|
-
line: 0,
|
|
26
|
-
column: 0,
|
|
27
|
-
});
|
|
28
|
-
const checkedLineNumberRightSpacing = useMemo(() => {
|
|
29
|
-
return Math.max(0, lineNumberRightSpacing);
|
|
30
|
-
}, [lineNumberRightSpacing]);
|
|
31
|
-
const currentLineNumberLength = useMemo(() => {
|
|
32
|
-
return Math.max(stringWidth(String(value.length - 1)), 1);
|
|
33
|
-
}, [stringWidth, cursor.line]);
|
|
3
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { TextCalculation } from "../text/text-based-calculation.js";
|
|
5
|
+
export function Editor({ value: initialText, lineNumberRightSpacing, cursorOffset, cursorHeightOffset, numberOfIndentationSpaces, }) {
|
|
6
|
+
const calcRef = useRef(null);
|
|
7
|
+
if (!calcRef.current) {
|
|
8
|
+
calcRef.current = new TextCalculation(initialText, {
|
|
9
|
+
lineNumberRightSpacing,
|
|
10
|
+
cursorOffset,
|
|
11
|
+
cursorHeightOffset,
|
|
12
|
+
numberOfIndentationSpaces,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const calc = calcRef.current;
|
|
16
|
+
const [, forceUpdate] = useState(0);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
return calc.onChange(() => forceUpdate((n) => n + 1));
|
|
19
|
+
}, [calc]);
|
|
34
20
|
const { setCursorPosition } = useCursor();
|
|
35
|
-
const boxRef = useRef(null);
|
|
36
21
|
const { boundKeyboard, enableWildcardPriority } = useKeyboard();
|
|
37
22
|
useEffect(() => {
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
line: prev.line,
|
|
51
|
-
column: prev.column + input.length,
|
|
52
|
-
};
|
|
53
|
-
});
|
|
54
|
-
}));
|
|
55
|
-
unBinds.push(boundKeyboard(["return"], () => {
|
|
56
|
-
const cur = cursor;
|
|
57
|
-
setValue((prev) => {
|
|
58
|
-
const newLine = [...prev];
|
|
59
|
-
const newStr = splitString(newLine[cur.line], cur.column);
|
|
60
|
-
newLine.splice(cur.line, 1);
|
|
61
|
-
newLine.splice(cur.line, 0, newStr[0]);
|
|
62
|
-
newLine.splice(cur.line + 1, 0, newStr[1]);
|
|
63
|
-
return newLine;
|
|
64
|
-
});
|
|
65
|
-
setCursor((prev) => {
|
|
66
|
-
return {
|
|
67
|
-
line: prev.line + 1,
|
|
68
|
-
column: 0,
|
|
69
|
-
};
|
|
70
|
-
});
|
|
71
|
-
}));
|
|
72
|
-
unBinds.push(boundKeyboard(["right"], () => {
|
|
73
|
-
setCursor((prev) => ({
|
|
74
|
-
line: prev.line,
|
|
75
|
-
column: Math.min(prev.column + 1, value[cursor.line].length),
|
|
76
|
-
}));
|
|
77
|
-
}));
|
|
78
|
-
unBinds.push(boundKeyboard(["left"], () => {
|
|
79
|
-
setCursor((prev) => ({
|
|
80
|
-
line: prev.line,
|
|
81
|
-
column: Math.max(prev.column - 1, 0),
|
|
82
|
-
}));
|
|
83
|
-
}));
|
|
84
|
-
unBinds.push(boundKeyboard(["backspace", "delete"], () => {
|
|
85
|
-
let wrap = false;
|
|
86
|
-
let lastLineLenth = null;
|
|
87
|
-
setValue((prev) => {
|
|
88
|
-
const newValue = [...prev];
|
|
89
|
-
if (cursor.column === 0 && cursor.line !== 0) {
|
|
90
|
-
wrap = true;
|
|
91
|
-
lastLineLenth = newValue[cursor.line - 1].length;
|
|
92
|
-
const newStr = insertStr(newValue[cursor.line - 1], newValue[cursor.line - 1].length, newValue[cursor.line]);
|
|
93
|
-
newValue[cursor.line - 1] = newStr;
|
|
94
|
-
newValue.splice(cursor.line, 1);
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
const newStr = cursor.column === 0
|
|
98
|
-
? newValue[cursor.line]
|
|
99
|
-
: deleteCharAt(newValue[cursor.line], cursor.column - 1);
|
|
100
|
-
newValue[cursor.line] = newStr;
|
|
101
|
-
}
|
|
102
|
-
return newValue;
|
|
103
|
-
});
|
|
104
|
-
setCursor((prev) => {
|
|
105
|
-
return {
|
|
106
|
-
line: wrap ? prev.line - 1 : prev.line,
|
|
107
|
-
column: lastLineLenth
|
|
108
|
-
? lastLineLenth
|
|
109
|
-
: Math.max(prev.column - 1, 0),
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
}));
|
|
113
|
-
unBinds.push(boundKeyboard(["up"], () => {
|
|
114
|
-
setCursor((prev) => {
|
|
115
|
-
return {
|
|
116
|
-
line: Math.max(prev.line - 1, 0),
|
|
117
|
-
column: Math.min(value[Math.max(prev.line - 1, 0)].length, prev.column),
|
|
118
|
-
};
|
|
119
|
-
});
|
|
120
|
-
}));
|
|
121
|
-
unBinds.push(boundKeyboard(["down"], () => {
|
|
122
|
-
setCursor((prev) => {
|
|
123
|
-
return {
|
|
124
|
-
line: Math.min(prev.line + 1, value.length - 1),
|
|
125
|
-
column: Math.min(value[Math.min(prev.line + 1, value.length - 1)].length, prev.column),
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
}));
|
|
129
|
-
unBinds.push(boundKeyboard(["tab"], () => {
|
|
130
|
-
setValue((prev) => {
|
|
131
|
-
const newValue = [...prev];
|
|
132
|
-
newValue[cursor.line] = insertStr(newValue[cursor.line], cursor.column, " ".repeat(numberOfIndentationSpaces));
|
|
133
|
-
return newValue;
|
|
134
|
-
});
|
|
135
|
-
setCursor((prev) => ({
|
|
136
|
-
line: prev.line,
|
|
137
|
-
column: prev.column + numberOfIndentationSpaces,
|
|
138
|
-
}));
|
|
139
|
-
}));
|
|
140
|
-
unBinds.push(boundKeyboard(["shift+tab"], () => {
|
|
141
|
-
setValue((prev) => {
|
|
142
|
-
const newValue = [...prev];
|
|
143
|
-
const currentLine = newValue[cursor.line];
|
|
144
|
-
const leadingSpaces = currentLine.match(/^ */)?.[0].length || 0;
|
|
145
|
-
if (leadingSpaces >= numberOfIndentationSpaces) {
|
|
146
|
-
newValue[cursor.line] = deleteCharAt(currentLine, 0, numberOfIndentationSpaces);
|
|
147
|
-
setCursor((prevCursor) => ({
|
|
148
|
-
line: prevCursor.line,
|
|
149
|
-
column: Math.max(0, prevCursor.column - numberOfIndentationSpaces),
|
|
150
|
-
}));
|
|
151
|
-
}
|
|
152
|
-
else if (leadingSpaces > 0) {
|
|
153
|
-
newValue[cursor.line] = deleteCharAt(currentLine, 0, leadingSpaces);
|
|
154
|
-
setCursor((prevCursor) => ({
|
|
155
|
-
line: prevCursor.line,
|
|
156
|
-
column: Math.max(0, prevCursor.column - leadingSpaces),
|
|
157
|
-
}));
|
|
158
|
-
}
|
|
159
|
-
return newValue;
|
|
160
|
-
});
|
|
161
|
-
}));
|
|
23
|
+
const removeWildcard = enableWildcardPriority();
|
|
24
|
+
const unbinds = [];
|
|
25
|
+
unbinds.push(boundKeyboard(["*"], (input) => calc.insertChar(input)));
|
|
26
|
+
unbinds.push(boundKeyboard(["return"], () => calc.newLine()));
|
|
27
|
+
unbinds.push(boundKeyboard(["right"], () => calc.moveRight()));
|
|
28
|
+
unbinds.push(boundKeyboard(["left"], () => calc.moveLeft()));
|
|
29
|
+
unbinds.push(boundKeyboard(["backspace", "delete"], () => calc.backspace()));
|
|
30
|
+
unbinds.push(boundKeyboard(["up"], () => calc.moveUp()));
|
|
31
|
+
unbinds.push(boundKeyboard(["down"], () => calc.moveDown()));
|
|
32
|
+
unbinds.push(boundKeyboard(["tab"], () => calc.indent()));
|
|
33
|
+
unbinds.push(boundKeyboard(["shift+tab"], () => calc.outdent()));
|
|
162
34
|
return () => {
|
|
163
|
-
|
|
164
|
-
|
|
35
|
+
removeWildcard();
|
|
36
|
+
unbinds.forEach((fn) => fn());
|
|
165
37
|
};
|
|
166
|
-
}, [boundKeyboard,
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
// It could also be due to a specific device.
|
|
182
|
-
// On arm64-based devices—such as when running in Termux—this causes cursor misalignment.
|
|
183
|
-
// The cursor works normally everywhere else.
|
|
184
|
-
// I also don't know how to solve this problem elegantly.
|
|
185
|
-
setCursorPosition({ x: x, y: y });
|
|
186
|
-
return (React.createElement(Box, { ref: boxRef, height: "100%", width: "100%", backgroundColor: "#1e1e1e", flexDirection: "column" }, value.map((each, number) => {
|
|
187
|
-
return (React.createElement(Box, { key: number, flexDirection: "row" },
|
|
188
|
-
React.createElement(Box, { width: currentLineNumberLength, justifyContent: "flex-end", marginRight: checkedLineNumberRightSpacing },
|
|
189
|
-
React.createElement(Text, { bold: true }, number)),
|
|
38
|
+
}, [boundKeyboard, enableWildcardPriority, calc]);
|
|
39
|
+
const ref = useRef(null);
|
|
40
|
+
const { height } = useBoxMetrics(ref);
|
|
41
|
+
const lineNumberWidth = calc.getLineNumberWidth();
|
|
42
|
+
const visibleStart = calc.updateScroll(height);
|
|
43
|
+
const effectiveH = height > 0 ? height : calc.lineCount;
|
|
44
|
+
const visibleLines = calc.lines.slice(visibleStart, visibleStart + effectiveH);
|
|
45
|
+
const cursorX = calc.getCursorX(lineNumberWidth);
|
|
46
|
+
const cursorY = calc.cursor.line - visibleStart + calc.cursorHeightOffset;
|
|
47
|
+
setCursorPosition({ x: cursorX, y: cursorY });
|
|
48
|
+
return (React.createElement(Box, { ref: ref, height: "100%", width: "100%", backgroundColor: "#1e1e1e", flexDirection: "column" }, visibleLines.map((each, i) => {
|
|
49
|
+
const lineNumber = visibleStart + i;
|
|
50
|
+
return (React.createElement(Box, { key: lineNumber, flexDirection: "row" },
|
|
51
|
+
React.createElement(Box, { width: lineNumberWidth, justifyContent: "flex-end", marginRight: calc.lineNumberRightSpacing },
|
|
52
|
+
React.createElement(Text, { bold: calc.cursor.line === lineNumber }, lineNumber)),
|
|
190
53
|
React.createElement(Text, null, each)));
|
|
191
54
|
})));
|
|
192
55
|
}
|