ink-mini-code-editor 0.0.1 → 0.0.4
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.
- package/build/demo.d.ts +1 -0
- package/build/demo.js +114 -0
- package/build/demo.js.map +1 -0
- package/build/index.d.ts +38 -1
- package/build/index.js +141 -3
- package/build/index.js.map +1 -1
- package/package.json +2 -2
- package/readme.md +23 -0
package/build/demo.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/build/demo.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React, { useState, useMemo } from 'react';
|
|
2
|
+
import { render, Box, Text } from 'ink';
|
|
3
|
+
import TextInput from './index.js';
|
|
4
|
+
const sqlCommands = [
|
|
5
|
+
'select * from users',
|
|
6
|
+
'select * from orders',
|
|
7
|
+
'select id, name from users',
|
|
8
|
+
'insert into users values',
|
|
9
|
+
'update users set',
|
|
10
|
+
'delete from users where',
|
|
11
|
+
'create table',
|
|
12
|
+
'drop table',
|
|
13
|
+
'alter table',
|
|
14
|
+
];
|
|
15
|
+
// Common SQL typos/errors to detect
|
|
16
|
+
const sqlErrors = [
|
|
17
|
+
{ pattern: /\bselct\b/gi, replacement: 'select' },
|
|
18
|
+
{ pattern: /\bfrom\s+form\b/gi, replacement: 'from' },
|
|
19
|
+
{ pattern: /\bwher\b/gi, replacement: 'where' },
|
|
20
|
+
{ pattern: /\binsrt\b/gi, replacement: 'insert' },
|
|
21
|
+
{ pattern: /\bupdat\b/gi, replacement: 'update' },
|
|
22
|
+
{ pattern: /\bdelet\b/gi, replacement: 'delete' },
|
|
23
|
+
{ pattern: /\btabel\b/gi, replacement: 'table' },
|
|
24
|
+
];
|
|
25
|
+
// Deprecated SQL patterns to warn about
|
|
26
|
+
const sqlWarnings = [
|
|
27
|
+
{ pattern: /\bselect\s+\*\b/gi, message: 'Consider specifying columns' },
|
|
28
|
+
{ pattern: /\bdelete\s+from\s+\w+\s*$/gi, message: 'Missing WHERE clause' },
|
|
29
|
+
];
|
|
30
|
+
function Demo() {
|
|
31
|
+
const [value, setValue] = useState('');
|
|
32
|
+
const [submitted, setSubmitted] = useState([]);
|
|
33
|
+
const getSuggestion = (input) => {
|
|
34
|
+
if (input.length === 0)
|
|
35
|
+
return undefined;
|
|
36
|
+
const lower = input.toLowerCase();
|
|
37
|
+
return sqlCommands.find(cmd => cmd.startsWith(lower) && cmd !== lower);
|
|
38
|
+
};
|
|
39
|
+
// Generate decorations based on SQL validation
|
|
40
|
+
const decorations = useMemo(() => {
|
|
41
|
+
const decs = [];
|
|
42
|
+
// Check for typos/errors
|
|
43
|
+
for (const { pattern } of sqlErrors) {
|
|
44
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
45
|
+
let match;
|
|
46
|
+
while ((match = regex.exec(value)) !== null) {
|
|
47
|
+
decs.push({
|
|
48
|
+
start: match.index,
|
|
49
|
+
end: match.index + match[0].length,
|
|
50
|
+
style: 'error',
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Check for warnings
|
|
55
|
+
for (const { pattern } of sqlWarnings) {
|
|
56
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
57
|
+
let match;
|
|
58
|
+
while ((match = regex.exec(value)) !== null) {
|
|
59
|
+
decs.push({
|
|
60
|
+
start: match.index,
|
|
61
|
+
end: match.index + match[0].length,
|
|
62
|
+
style: 'warning',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return decs;
|
|
67
|
+
}, [value]);
|
|
68
|
+
const handleSubmit = (val) => {
|
|
69
|
+
if (val.trim()) {
|
|
70
|
+
setSubmitted(prev => [...prev, val]);
|
|
71
|
+
setValue('');
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
// Get error/warning messages for display
|
|
75
|
+
const errorMessages = useMemo(() => {
|
|
76
|
+
const messages = [];
|
|
77
|
+
for (const { pattern, replacement } of sqlErrors) {
|
|
78
|
+
if (pattern.test(value)) {
|
|
79
|
+
messages.push({
|
|
80
|
+
type: 'error',
|
|
81
|
+
text: `Typo: did you mean "${replacement}"?`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (const { pattern, message } of sqlWarnings) {
|
|
86
|
+
if (pattern.test(value)) {
|
|
87
|
+
messages.push({ type: 'warning', text: message });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return messages;
|
|
91
|
+
}, [value]);
|
|
92
|
+
return (React.createElement(Box, { flexDirection: "column", padding: 1 },
|
|
93
|
+
React.createElement(Text, { bold: true, color: "cyan" }, "SQL Editor Demo (with autocomplete + decorations)"),
|
|
94
|
+
React.createElement(Text, { dimColor: true }, "Type a SQL command - suggestions appear in grey. Press right arrow to accept."),
|
|
95
|
+
React.createElement(Text, { dimColor: true }, "Try typos like \"selct\" (error) or \"select *\" (warning)."),
|
|
96
|
+
React.createElement(Text, { dimColor: true }, "Press Enter to submit. Ctrl+C to exit."),
|
|
97
|
+
React.createElement(Box, { marginTop: 1 },
|
|
98
|
+
React.createElement(Text, { color: "green" }, `> `),
|
|
99
|
+
React.createElement(TextInput, { value: value, placeholder: "Enter SQL query...", language: "sql", getSuggestion: getSuggestion, decorations: decorations, onChange: setValue, onSubmit: handleSubmit, onSuggestionAccept: s => {
|
|
100
|
+
setValue(s);
|
|
101
|
+
} })),
|
|
102
|
+
errorMessages.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 }, errorMessages.map(msg => (React.createElement(Text, { key: `${msg.type}-${msg.text}`, color: msg.type === 'error' ? 'red' : 'yellow' },
|
|
103
|
+
msg.type === 'error' ? '✗' : '⚠',
|
|
104
|
+
" ",
|
|
105
|
+
msg.text))))),
|
|
106
|
+
submitted.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
107
|
+
React.createElement(Text, { bold: true }, "History:"),
|
|
108
|
+
submitted.map((cmd, idx) => (React.createElement(Text, { key: cmd, dimColor: true },
|
|
109
|
+
idx + 1,
|
|
110
|
+
". ",
|
|
111
|
+
cmd)))))));
|
|
112
|
+
}
|
|
113
|
+
render(React.createElement(Demo, null));
|
|
114
|
+
//# sourceMappingURL=demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../source/demo.tsx"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Except } from 'type-fest';
|
|
3
|
+
/**
|
|
4
|
+
* Decoration style preset names.
|
|
5
|
+
*/
|
|
6
|
+
export type DecorationStyle = 'error' | 'warning' | 'info' | 'highlight';
|
|
7
|
+
/**
|
|
8
|
+
* A decoration that highlights a range of text with custom styles.
|
|
9
|
+
*/
|
|
10
|
+
export type Decoration = {
|
|
11
|
+
/**
|
|
12
|
+
* Start character index (0-indexed, inclusive).
|
|
13
|
+
*/
|
|
14
|
+
start: number;
|
|
15
|
+
/**
|
|
16
|
+
* End character index (exclusive).
|
|
17
|
+
*/
|
|
18
|
+
end: number;
|
|
19
|
+
/**
|
|
20
|
+
* Preset style to apply.
|
|
21
|
+
*/
|
|
22
|
+
style: DecorationStyle;
|
|
23
|
+
};
|
|
3
24
|
export type Props = {
|
|
4
25
|
/**
|
|
5
26
|
* Text to display when `value` is empty.
|
|
@@ -39,8 +60,24 @@ export type Props = {
|
|
|
39
60
|
* When not specified, no syntax highlighting is applied.
|
|
40
61
|
*/
|
|
41
62
|
readonly language?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Function that returns an autocomplete suggestion based on the current value.
|
|
65
|
+
* The suggestion should be the complete text (including what's already typed).
|
|
66
|
+
* A grey ghost text will appear showing the remainder of the suggestion.
|
|
67
|
+
*/
|
|
68
|
+
readonly getSuggestion?: (value: string) => string | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Callback when a suggestion is accepted (via right arrow key).
|
|
71
|
+
*/
|
|
72
|
+
readonly onSuggestionAccept?: (accepted: string) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Array of decorations to apply to the text.
|
|
75
|
+
* Each decoration highlights a range of text with a preset style.
|
|
76
|
+
* Decorations only work when `language` is specified (syntax highlighting mode).
|
|
77
|
+
*/
|
|
78
|
+
readonly decorations?: Decoration[];
|
|
42
79
|
};
|
|
43
|
-
declare function TextInput({ value: originalValue, placeholder, focus, mask, highlightPastedText, showCursor, onChange, onSubmit, language, }: Props): React.JSX.Element;
|
|
80
|
+
declare function TextInput({ value: originalValue, placeholder, focus, mask, highlightPastedText, showCursor, onChange, onSubmit, language, getSuggestion, onSuggestionAccept, decorations, }: Props): React.JSX.Element;
|
|
44
81
|
export default TextInput;
|
|
45
82
|
type UncontrolledProps = {
|
|
46
83
|
/**
|
package/build/index.js
CHANGED
|
@@ -2,7 +2,80 @@ import React, { useState, useEffect } from 'react';
|
|
|
2
2
|
import { Text, useInput } from 'ink';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import SyntaxHighlight from 'ink-syntax-highlight';
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Style mappings for decoration presets.
|
|
7
|
+
*/
|
|
8
|
+
const decorationStyles = {
|
|
9
|
+
error: { color: 'red', underline: true },
|
|
10
|
+
warning: { color: 'yellow', underline: true },
|
|
11
|
+
info: { color: 'blue', underline: true },
|
|
12
|
+
highlight: { backgroundColor: 'yellow' },
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Merges multiple decoration styles into a single style object.
|
|
16
|
+
* Later decorations in the array take precedence for conflicting properties.
|
|
17
|
+
*/
|
|
18
|
+
function mergeDecorationStyles(decorations) {
|
|
19
|
+
if (decorations.length === 0)
|
|
20
|
+
return undefined;
|
|
21
|
+
const merged = {};
|
|
22
|
+
for (const dec of decorations) {
|
|
23
|
+
const style = decorationStyles[dec.style];
|
|
24
|
+
Object.assign(merged, style);
|
|
25
|
+
}
|
|
26
|
+
return merged;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates segments of text based on cursor position and decorations.
|
|
30
|
+
* Each segment has a unique combination of styling needs.
|
|
31
|
+
*/
|
|
32
|
+
function createSegments(value, cursorOffset, decorations, showCursor) {
|
|
33
|
+
// Clamp decorations to valid bounds
|
|
34
|
+
const clampedDecorations = decorations.map(dec => ({
|
|
35
|
+
...dec,
|
|
36
|
+
start: Math.max(0, Math.min(dec.start, value.length)),
|
|
37
|
+
end: Math.max(0, Math.min(dec.end, value.length)),
|
|
38
|
+
}));
|
|
39
|
+
// Collect all split points
|
|
40
|
+
const splitPoints = new Set([0, value.length]);
|
|
41
|
+
// Add cursor position as split point
|
|
42
|
+
if (showCursor) {
|
|
43
|
+
splitPoints.add(cursorOffset);
|
|
44
|
+
if (cursorOffset < value.length) {
|
|
45
|
+
splitPoints.add(cursorOffset + 1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Add decoration boundaries
|
|
49
|
+
for (const dec of clampedDecorations) {
|
|
50
|
+
if (dec.start < dec.end) {
|
|
51
|
+
splitPoints.add(dec.start);
|
|
52
|
+
splitPoints.add(dec.end);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Sort and filter valid points
|
|
56
|
+
const points = [...splitPoints]
|
|
57
|
+
.sort((a, b) => a - b)
|
|
58
|
+
.filter(p => p >= 0 && p <= value.length);
|
|
59
|
+
// Create segments
|
|
60
|
+
const segments = [];
|
|
61
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
62
|
+
const start = points[i];
|
|
63
|
+
const end = points[i + 1];
|
|
64
|
+
const text = value.slice(start, end);
|
|
65
|
+
const isCursor = showCursor && start === cursorOffset && end === cursorOffset + 1;
|
|
66
|
+
// Find decorations that overlap with this segment
|
|
67
|
+
const appliedDecorations = clampedDecorations.filter(dec => dec.start < end && dec.end > start);
|
|
68
|
+
segments.push({
|
|
69
|
+
text,
|
|
70
|
+
start,
|
|
71
|
+
end,
|
|
72
|
+
isCursor,
|
|
73
|
+
decorations: appliedDecorations,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return segments;
|
|
77
|
+
}
|
|
78
|
+
function TextInput({ value: originalValue, placeholder = '', focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit, language, getSuggestion, onSuggestionAccept, decorations = [], }) {
|
|
6
79
|
const [state, setState] = useState({
|
|
7
80
|
cursorOffset: (originalValue || '').length,
|
|
8
81
|
cursorWidth: 0,
|
|
@@ -46,6 +119,20 @@ function TextInput({ value: originalValue, placeholder = '', focus = true, mask,
|
|
|
46
119
|
renderedValue += chalk.inverse(' ');
|
|
47
120
|
}
|
|
48
121
|
}
|
|
122
|
+
// Compute ghost text for autocomplete suggestion
|
|
123
|
+
let ghostText = '';
|
|
124
|
+
if (getSuggestion && focus && cursorOffset === originalValue.length) {
|
|
125
|
+
const suggestion = getSuggestion(originalValue);
|
|
126
|
+
if (suggestion &&
|
|
127
|
+
suggestion.startsWith(originalValue) &&
|
|
128
|
+
suggestion !== originalValue) {
|
|
129
|
+
ghostText = suggestion.slice(originalValue.length);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Append ghost text in dim styling
|
|
133
|
+
if (ghostText) {
|
|
134
|
+
renderedValue += chalk.dim(ghostText);
|
|
135
|
+
}
|
|
49
136
|
useInput((input, key) => {
|
|
50
137
|
if (key.upArrow ||
|
|
51
138
|
key.downArrow ||
|
|
@@ -70,7 +157,24 @@ function TextInput({ value: originalValue, placeholder = '', focus = true, mask,
|
|
|
70
157
|
}
|
|
71
158
|
else if (key.rightArrow) {
|
|
72
159
|
if (showCursor) {
|
|
73
|
-
|
|
160
|
+
// Check if we should accept autocomplete suggestion
|
|
161
|
+
if (cursorOffset === originalValue.length && getSuggestion) {
|
|
162
|
+
const suggestion = getSuggestion(originalValue);
|
|
163
|
+
if (suggestion &&
|
|
164
|
+
suggestion.startsWith(originalValue) &&
|
|
165
|
+
suggestion !== originalValue) {
|
|
166
|
+
// Accept the suggestion
|
|
167
|
+
nextValue = suggestion;
|
|
168
|
+
nextCursorOffset = suggestion.length;
|
|
169
|
+
onSuggestionAccept?.(suggestion);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
nextCursorOffset++;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
nextCursorOffset++;
|
|
177
|
+
}
|
|
74
178
|
}
|
|
75
179
|
}
|
|
76
180
|
else if (key.backspace || key.delete) {
|
|
@@ -110,8 +214,42 @@ function TextInput({ value: originalValue, placeholder = '', focus = true, mask,
|
|
|
110
214
|
? renderedValue
|
|
111
215
|
: renderedPlaceholder
|
|
112
216
|
: renderedValue;
|
|
217
|
+
// When syntax highlighting is enabled, use component-based rendering
|
|
218
|
+
// to avoid ANSI code conflicts between chalk and the syntax highlighter
|
|
113
219
|
if (language) {
|
|
114
|
-
|
|
220
|
+
const showGhost = ghostText && focus && cursorOffset === value.length;
|
|
221
|
+
const cursorVisible = showCursor && focus;
|
|
222
|
+
// Empty value with placeholder
|
|
223
|
+
if (value.length === 0 && placeholder) {
|
|
224
|
+
return (React.createElement(Text, null, cursorVisible ? (React.createElement(React.Fragment, null,
|
|
225
|
+
React.createElement(Text, { inverse: true }, placeholder[0] ?? ' '),
|
|
226
|
+
React.createElement(Text, { dimColor: true }, placeholder.slice(1)))) : (React.createElement(Text, { dimColor: true }, placeholder))));
|
|
227
|
+
}
|
|
228
|
+
// Empty value without placeholder
|
|
229
|
+
if (value.length === 0) {
|
|
230
|
+
return cursorVisible ? React.createElement(Text, { inverse: true }, " ") : React.createElement(Text, null);
|
|
231
|
+
}
|
|
232
|
+
const cursorAtEnd = cursorOffset === value.length;
|
|
233
|
+
// Use segment-based rendering for decorations support
|
|
234
|
+
const segments = createSegments(value, cursorOffset, decorations, cursorVisible);
|
|
235
|
+
return (React.createElement(Text, null,
|
|
236
|
+
segments.map(seg => {
|
|
237
|
+
// Cursor segment takes precedence over decorations
|
|
238
|
+
if (seg.isCursor) {
|
|
239
|
+
return (React.createElement(Text, { key: `cursor-${seg.start}`, inverse: true }, seg.text));
|
|
240
|
+
}
|
|
241
|
+
// Get merged decoration styles for this segment
|
|
242
|
+
const decorationStyle = mergeDecorationStyles(seg.decorations);
|
|
243
|
+
if (decorationStyle) {
|
|
244
|
+
// Render with decoration styles wrapping syntax highlight
|
|
245
|
+
return (React.createElement(Text, { key: `dec-${seg.start}`, ...decorationStyle },
|
|
246
|
+
React.createElement(SyntaxHighlight, { language: language, code: seg.text })));
|
|
247
|
+
}
|
|
248
|
+
// No decorations, just syntax highlight
|
|
249
|
+
return (React.createElement(SyntaxHighlight, { key: `seg-${seg.start}`, language: language, code: seg.text }));
|
|
250
|
+
}),
|
|
251
|
+
cursorVisible && cursorAtEnd && React.createElement(Text, { inverse: true }, " "),
|
|
252
|
+
showGhost && React.createElement(Text, { dimColor: true }, ghostText)));
|
|
115
253
|
}
|
|
116
254
|
return React.createElement(Text, null, displayValue);
|
|
117
255
|
}
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AACjD,OAAO,EAAC,IAAI,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ink-mini-code-editor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Code editor for Ink library",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "choneface/ink-mini-code-editor",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"build": "tsc",
|
|
22
22
|
"prepare": "tsc",
|
|
23
23
|
"pretest": "tsc",
|
|
24
|
-
"dev": "tsx source/
|
|
24
|
+
"dev": "tsx source/demo.tsx"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"build"
|
package/readme.md
CHANGED
|
@@ -108,6 +108,29 @@ Type: `Function`
|
|
|
108
108
|
|
|
109
109
|
Function to call when `Enter` is pressed, where first argument is the value of the input.
|
|
110
110
|
|
|
111
|
+
### getSuggestion
|
|
112
|
+
|
|
113
|
+
Type: `(value: string) => string | undefined`
|
|
114
|
+
|
|
115
|
+
Function that returns an autocomplete suggestion based on the current value. The suggestion should be the complete text (including what's already typed). When a valid suggestion is returned, a grey ghost text appears showing the remainder of the suggestion. Press the right arrow key to accept the suggestion.
|
|
116
|
+
|
|
117
|
+
```jsx
|
|
118
|
+
const getSuggestion = (value) => {
|
|
119
|
+
const commands = ['select * from users', 'insert into table', 'delete from table'];
|
|
120
|
+
return commands.find(cmd => cmd.startsWith(value) && cmd !== value);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
<CodeEditor value={code} onChange={setCode} getSuggestion={getSuggestion} />
|
|
124
|
+
// User types "sel" → displays: sel|ect * from users (grey ghost text)
|
|
125
|
+
// User presses → → value becomes "select * from users"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### onSuggestionAccept
|
|
129
|
+
|
|
130
|
+
Type: `(accepted: string) => void`
|
|
131
|
+
|
|
132
|
+
Callback function called when a suggestion is accepted via the right arrow key. The accepted suggestion string is passed as the argument.
|
|
133
|
+
|
|
111
134
|
## Uncontrolled usage
|
|
112
135
|
|
|
113
136
|
This component also exposes an [uncontrolled](https://reactjs.org/docs/uncontrolled-components.html) version, which handles `value` changes for you. To receive the final input value, use `onSubmit` prop. Initial value can be specified via `initialValue` prop.
|