@travisennis/acai 0.0.11 → 0.0.13
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/README.md +5 -5
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +2 -5
- package/dist/commands/history/types.d.ts +3 -2
- package/dist/commands/history/types.d.ts.map +1 -1
- package/dist/commands/init-project/utils.d.ts +0 -1
- package/dist/commands/init-project/utils.d.ts.map +1 -1
- package/dist/commands/init-project/utils.js +1 -12
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +6 -19
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +4 -1
- package/dist/commands/session/index.d.ts.map +1 -1
- package/dist/commands/session/index.js +6 -0
- package/dist/commands/session/types.d.ts +1 -0
- package/dist/commands/session/types.d.ts.map +1 -1
- package/dist/commands/share/html-renderer.d.ts.map +1 -1
- package/dist/commands/share/html-renderer.js +54 -48
- package/dist/commands/tools/index.d.ts +3 -0
- package/dist/commands/tools/index.d.ts.map +1 -0
- package/dist/commands/tools/index.js +191 -0
- package/dist/commands/tools/templates.d.ts +6 -0
- package/dist/commands/tools/templates.d.ts.map +1 -0
- package/dist/commands/tools/templates.js +97 -0
- package/dist/config/index.d.ts +5 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +42 -6
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -68
- package/dist/models/anthropic-provider.d.ts +1 -1
- package/dist/models/deepseek-provider.d.ts +3 -3
- package/dist/models/deepseek-provider.js +17 -17
- package/dist/models/google-provider.d.ts +2 -4
- package/dist/models/google-provider.d.ts.map +1 -1
- package/dist/models/google-provider.js +2 -17
- package/dist/models/groq-provider.d.ts +2 -4
- package/dist/models/groq-provider.d.ts.map +1 -1
- package/dist/models/groq-provider.js +3 -21
- package/dist/models/manager.d.ts +1 -10
- package/dist/models/manager.d.ts.map +1 -1
- package/dist/models/manager.js +2 -2
- package/dist/models/opencode-go-provider.d.ts +11 -1
- package/dist/models/opencode-go-provider.d.ts.map +1 -1
- package/dist/models/opencode-go-provider.js +130 -0
- package/dist/models/opencode-zen-provider.d.ts +3 -3
- package/dist/models/opencode-zen-provider.d.ts.map +1 -1
- package/dist/models/opencode-zen-provider.js +26 -32
- package/dist/models/openrouter-provider.d.ts +4 -15
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +26 -169
- package/dist/models/providers.d.ts +1 -1
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/xai-provider.d.ts +1 -2
- package/dist/models/xai-provider.d.ts.map +1 -1
- package/dist/models/xai-provider.js +0 -13
- package/dist/prompts/manager.d.ts.map +1 -1
- package/dist/prompts/manager.js +5 -1
- package/dist/prompts/system-prompt.d.ts +1 -2
- package/dist/prompts/system-prompt.d.ts.map +1 -1
- package/dist/prompts/system-prompt.js +26 -15
- package/dist/repl/index.d.ts +28 -13
- package/dist/repl/index.d.ts.map +1 -1
- package/dist/repl/index.js +242 -305
- package/dist/skills/activated-tracker.d.ts +11 -0
- package/dist/skills/activated-tracker.d.ts.map +1 -0
- package/dist/skills/activated-tracker.js +16 -0
- package/dist/skills/index.d.ts +12 -2
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +127 -71
- package/dist/terminal/control.d.ts +1 -21
- package/dist/terminal/control.d.ts.map +1 -1
- package/dist/terminal/control.js +1 -32
- package/dist/terminal/formatting.d.ts +0 -33
- package/dist/terminal/formatting.d.ts.map +1 -1
- package/dist/terminal/formatting.js +0 -91
- package/dist/terminal/highlight/theme.d.ts +0 -37
- package/dist/terminal/highlight/theme.d.ts.map +1 -1
- package/dist/terminal/highlight/theme.js +1 -79
- package/dist/terminal/keys.d.ts +0 -97
- package/dist/terminal/keys.d.ts.map +1 -1
- package/dist/terminal/keys.js +0 -194
- package/dist/terminal/select-prompt.d.ts.map +1 -1
- package/dist/terminal/select-prompt.js +65 -51
- package/dist/terminal/style.d.ts +1 -1
- package/dist/terminal/style.d.ts.map +1 -1
- package/dist/terminal/supports-color.d.ts.map +1 -1
- package/dist/terminal/supports-color.js +38 -20
- package/dist/terminal/supports-hyperlinks.d.ts +3 -0
- package/dist/terminal/supports-hyperlinks.d.ts.map +1 -1
- package/dist/terminal/supports-hyperlinks.js +72 -31
- package/dist/terminal/table/layout-manager.d.ts +0 -20
- package/dist/terminal/table/layout-manager.d.ts.map +1 -1
- package/dist/terminal/table/layout-manager.js +68 -44
- package/dist/terminal/table/utils.d.ts +0 -1
- package/dist/terminal/table/utils.d.ts.map +1 -1
- package/dist/terminal/table/utils.js +2 -4
- package/dist/tools/apply-patch.d.ts +5 -3
- package/dist/tools/apply-patch.d.ts.map +1 -1
- package/dist/tools/apply-patch.js +154 -123
- package/dist/tools/bash.d.ts +4 -4
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +27 -13
- package/dist/tools/dynamic-tool-loader.d.ts +17 -3
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +360 -81
- package/dist/tools/edit-file.d.ts +2 -2
- package/dist/tools/index.d.ts +27 -151
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +16 -21
- package/dist/tools/read-file.d.ts +8 -8
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +32 -13
- package/dist/tools/save-file.d.ts +4 -4
- package/dist/tools/skill.d.ts +2 -1
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +64 -14
- package/dist/tools/types.d.ts +8 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/web-fetch.d.ts +8 -12
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +86 -44
- package/dist/tools/web-search.d.ts +4 -8
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +41 -33
- package/dist/tui/autocomplete/utils.d.ts +0 -15
- package/dist/tui/autocomplete/utils.d.ts.map +1 -1
- package/dist/tui/autocomplete/utils.js +0 -85
- package/dist/tui/autocomplete.d.ts +1 -1
- package/dist/tui/autocomplete.d.ts.map +1 -1
- package/dist/tui/autocomplete.js +1 -1
- package/dist/tui/components/editor.d.ts +12 -0
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +181 -195
- package/dist/tui/components/footer.d.ts +0 -2
- package/dist/tui/components/footer.d.ts.map +1 -1
- package/dist/tui/components/footer.js +1 -17
- package/dist/tui/components/input.d.ts +4 -0
- package/dist/tui/components/input.d.ts.map +1 -1
- package/dist/tui/components/input.js +33 -31
- package/dist/tui/components/markdown.d.ts +30 -0
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/markdown.js +274 -242
- package/dist/tui/components/modal.d.ts.map +1 -1
- package/dist/tui/components/modal.js +11 -11
- package/dist/tui/components/select-list.d.ts +5 -0
- package/dist/tui/components/select-list.d.ts.map +1 -1
- package/dist/tui/components/select-list.js +69 -98
- package/dist/tui/components/table.d.ts +6 -0
- package/dist/tui/components/table.d.ts.map +1 -1
- package/dist/tui/components/table.js +61 -52
- package/dist/tui/index.d.ts +1 -8
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +0 -8
- package/dist/tui/tui.d.ts +9 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +78 -48
- package/dist/tui/utils.d.ts +7 -0
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +117 -53
- package/dist/utils/bash.d.ts.map +1 -1
- package/dist/utils/bash.js +121 -104
- package/dist/utils/binary-output.d.ts +32 -0
- package/dist/utils/binary-output.d.ts.map +1 -0
- package/dist/utils/binary-output.js +127 -0
- package/dist/utils/command-protection.d.ts +3 -2
- package/dist/utils/command-protection.d.ts.map +1 -1
- package/dist/utils/command-protection.js +121 -29
- package/dist/utils/filesystem/operations.d.ts +0 -15
- package/dist/utils/filesystem/operations.d.ts.map +1 -1
- package/dist/utils/filesystem/operations.js +1 -38
- package/dist/utils/filesystem/security.d.ts.map +1 -1
- package/dist/utils/filesystem/security.js +22 -15
- package/dist/utils/filetype-detection.d.ts +0 -1
- package/dist/utils/filetype-detection.d.ts.map +1 -1
- package/dist/utils/filetype-detection.js +0 -12
- package/dist/utils/formatting.d.ts +0 -30
- package/dist/utils/formatting.d.ts.map +1 -1
- package/dist/utils/formatting.js +0 -44
- package/dist/utils/git.d.ts +4 -6
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +36 -46
- package/dist/utils/ignore.d.ts +1 -1
- package/dist/utils/ignore.d.ts.map +1 -1
- package/dist/utils/ignore.js +1 -1
- package/dist/utils/parsing.d.ts +1 -1
- package/dist/utils/parsing.d.ts.map +1 -1
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +77 -79
- package/dist/utils/yaml.d.ts +0 -1
- package/dist/utils/yaml.d.ts.map +1 -1
- package/dist/utils/yaml.js +80 -89
- package/dist/utils/zod.d.ts +0 -3
- package/dist/utils/zod.d.ts.map +1 -1
- package/dist/utils/zod.js +0 -7
- package/package.json +32 -29
- package/dist/agent/sub-agent.d.ts +0 -23
- package/dist/agent/sub-agent.d.ts.map +0 -1
- package/dist/agent/sub-agent.js +0 -109
- package/dist/commands/add-directory/index.d.ts +0 -3
- package/dist/commands/add-directory/index.d.ts.map +0 -1
- package/dist/commands/add-directory/index.js +0 -50
- package/dist/commands/add-directory/utils.d.ts +0 -3
- package/dist/commands/add-directory/utils.d.ts.map +0 -1
- package/dist/commands/add-directory/utils.js +0 -15
- package/dist/commands/clear/index.d.ts +0 -3
- package/dist/commands/clear/index.d.ts.map +0 -1
- package/dist/commands/clear/index.js +0 -13
- package/dist/commands/generate-rules/index.d.ts +0 -3
- package/dist/commands/generate-rules/index.d.ts.map +0 -1
- package/dist/commands/generate-rules/index.js +0 -206
- package/dist/commands/generate-rules/service.d.ts +0 -22
- package/dist/commands/generate-rules/service.d.ts.map +0 -1
- package/dist/commands/generate-rules/service.js +0 -103
- package/dist/commands/generate-rules/utils.d.ts +0 -5
- package/dist/commands/generate-rules/utils.d.ts.map +0 -1
- package/dist/commands/generate-rules/utils.js +0 -25
- package/dist/commands/handoff/index.d.ts +0 -3
- package/dist/commands/handoff/index.d.ts.map +0 -1
- package/dist/commands/handoff/index.js +0 -97
- package/dist/commands/handoff/utils.d.ts +0 -4
- package/dist/commands/handoff/utils.d.ts.map +0 -1
- package/dist/commands/handoff/utils.js +0 -123
- package/dist/commands/list-directories/index.d.ts +0 -3
- package/dist/commands/list-directories/index.d.ts.map +0 -1
- package/dist/commands/list-directories/index.js +0 -35
- package/dist/commands/pickup/index.d.ts +0 -3
- package/dist/commands/pickup/index.d.ts.map +0 -1
- package/dist/commands/pickup/index.js +0 -141
- package/dist/commands/pickup/types.d.ts +0 -6
- package/dist/commands/pickup/types.d.ts.map +0 -1
- package/dist/commands/pickup/types.js +0 -1
- package/dist/commands/pickup/utils.d.ts +0 -7
- package/dist/commands/pickup/utils.d.ts.map +0 -1
- package/dist/commands/pickup/utils.js +0 -56
- package/dist/commands/remove-directory/index.d.ts +0 -3
- package/dist/commands/remove-directory/index.d.ts.map +0 -1
- package/dist/commands/remove-directory/index.js +0 -55
- package/dist/commands/review/index.d.ts +0 -3
- package/dist/commands/review/index.d.ts.map +0 -1
- package/dist/commands/review/index.js +0 -12
- package/dist/commands/review/review-panel.d.ts +0 -3
- package/dist/commands/review/review-panel.d.ts.map +0 -1
- package/dist/commands/review/review-panel.js +0 -186
- package/dist/commands/review/utils.d.ts +0 -18
- package/dist/commands/review/utils.d.ts.map +0 -1
- package/dist/commands/review/utils.js +0 -146
- package/dist/commands/shell/index.d.ts +0 -3
- package/dist/commands/shell/index.d.ts.map +0 -1
- package/dist/commands/shell/index.js +0 -96
- package/dist/modes/manager.d.ts +0 -24
- package/dist/modes/manager.d.ts.map +0 -1
- package/dist/modes/manager.js +0 -77
- package/dist/modes/prompts.d.ts +0 -2
- package/dist/modes/prompts.d.ts.map +0 -1
- package/dist/modes/prompts.js +0 -142
- package/dist/subagents/index.d.ts +0 -16
- package/dist/subagents/index.d.ts.map +0 -1
- package/dist/subagents/index.js +0 -231
- package/dist/terminal/index.d.ts +0 -9
- package/dist/terminal/index.d.ts.map +0 -1
- package/dist/terminal/index.js +0 -8
- package/dist/tools/agent.d.ts +0 -27
- package/dist/tools/agent.d.ts.map +0 -1
- package/dist/tools/agent.js +0 -81
- package/dist/tools/directory-tree.d.ts +0 -28
- package/dist/tools/directory-tree.d.ts.map +0 -1
- package/dist/tools/directory-tree.js +0 -152
- package/dist/tools/glob.d.ts +0 -35
- package/dist/tools/glob.d.ts.map +0 -1
- package/dist/tools/glob.js +0 -159
- package/dist/tools/grep.d.ts +0 -100
- package/dist/tools/grep.d.ts.map +0 -1
- package/dist/tools/grep.js +0 -601
- package/dist/tools/ls.d.ts +0 -26
- package/dist/tools/ls.d.ts.map +0 -1
- package/dist/tools/ls.js +0 -82
- package/dist/tui/components/header.d.ts +0 -21
- package/dist/tui/components/header.d.ts.map +0 -1
- package/dist/tui/components/header.js +0 -63
- package/dist/utils/bash/parse.d.ts +0 -19
- package/dist/utils/bash/parse.d.ts.map +0 -1
- package/dist/utils/bash/parse.js +0 -223
- package/dist/utils/bash/quote.d.ts +0 -6
- package/dist/utils/bash/quote.d.ts.map +0 -1
- package/dist/utils/bash/quote.js +0 -23
- package/dist/utils/generators.d.ts +0 -3
- package/dist/utils/generators.d.ts.map +0 -1
- package/dist/utils/generators.js +0 -25
- package/dist/utils/glob.d.ts +0 -52
- package/dist/utils/glob.d.ts.map +0 -1
- package/dist/utils/glob.js +0 -376
package/dist/tui/autocomplete.js
CHANGED
|
@@ -8,7 +8,7 @@ export { CombinedProvider } from "./autocomplete/combined-provider.js";
|
|
|
8
8
|
export { CommandProvider } from "./autocomplete/command-provider.js";
|
|
9
9
|
export { FileSearchProvider } from "./autocomplete/file-search-provider.js";
|
|
10
10
|
export { SkillProvider } from "./autocomplete/skill-provider.js";
|
|
11
|
-
export {
|
|
11
|
+
export { extractPathPrefix } from "./autocomplete/utils.js";
|
|
12
12
|
// Convenience function for backward compatibility
|
|
13
13
|
export function createDefaultProvider(commands = [], _allowedDirs = [process.cwd()]) {
|
|
14
14
|
return new CombinedProvider([
|
|
@@ -68,6 +68,7 @@ export declare class Editor implements Component {
|
|
|
68
68
|
/** Internal setText that doesn't reset history state - used by navigateHistory */
|
|
69
69
|
private setTextInternal;
|
|
70
70
|
invalidate(): void;
|
|
71
|
+
private renderCursorOnLine;
|
|
71
72
|
render(width: number): string[];
|
|
72
73
|
handleInput(data: string): void;
|
|
73
74
|
private processInputData;
|
|
@@ -83,10 +84,15 @@ export declare class Editor implements Component {
|
|
|
83
84
|
private handleWordNavigation;
|
|
84
85
|
private handleArrowKeys;
|
|
85
86
|
private layoutText;
|
|
87
|
+
private pushSingleLayoutLine;
|
|
88
|
+
private pushWrappedLayoutLines;
|
|
86
89
|
getText(): string;
|
|
87
90
|
setText(text: string): void;
|
|
88
91
|
private insertCharacter;
|
|
89
92
|
private handlePaste;
|
|
93
|
+
private handleLargePaste;
|
|
94
|
+
private handleSingleLinePaste;
|
|
95
|
+
private handleMultiLinePaste;
|
|
90
96
|
private addNewLine;
|
|
91
97
|
private handleBackspace;
|
|
92
98
|
private moveToLineStart;
|
|
@@ -95,6 +101,10 @@ export declare class Editor implements Component {
|
|
|
95
101
|
private deleteToStartOfLine;
|
|
96
102
|
private deleteToEndOfLine;
|
|
97
103
|
private deleteWordBackwards;
|
|
104
|
+
private mergeLineWithPrevious;
|
|
105
|
+
private deleteWordOnCurrentLine;
|
|
106
|
+
private findWordBoundaryBackwards;
|
|
107
|
+
private isWordBoundaryChar;
|
|
98
108
|
/**
|
|
99
109
|
* Build a mapping from visual lines to logical positions.
|
|
100
110
|
* Returns an array where each element represents a visual line with:
|
|
@@ -108,6 +118,8 @@ export declare class Editor implements Component {
|
|
|
108
118
|
*/
|
|
109
119
|
private findCurrentVisualLine;
|
|
110
120
|
private moveCursor;
|
|
121
|
+
private moveCursorVertical;
|
|
122
|
+
private moveCursorHorizontal;
|
|
111
123
|
private isWordBoundary;
|
|
112
124
|
private moveWordBackwards;
|
|
113
125
|
private moveWordForwards;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../source/tui/components/editor.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAuK3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,UAAU,WAAW;IACnB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,MAAO,YAAW,SAAS;IACtC,OAAO,CAAC,KAAK,CAIX;IAEF,OAAO,CAAC,KAAK,CAAc;IAG3B,OAAO,CAAC,SAAS,CAAM;IAGhB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAG5C,OAAO,CAAC,oBAAoB,CAAC,CAAuB;IACpD,OAAO,CAAC,gBAAgB,CAAC,CAAa;IACtC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,yBAAyB,CAAC,CAAiB;IAGnD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,YAAY,CAAK;IAGzB,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAM;IAEnB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,aAAa,UAAS;IAGtB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CACxB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;gBAExC,KAAK,CAAC,EAAE,WAAW;IAQ/B;;OAEG;IACH,UAAU,IAAI,SAAS,MAAM,EAAE;IAI/B;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAYhC,uBAAuB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;YAI/C,oBAAoB;IAclC,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,eAAe;IAgBvB,kFAAkF;IAClF,OAAO,CAAC,eAAe;IAWvB,UAAU,IAAI,IAAI;IAIlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../source/tui/components/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -261,6 +261,35 @@ export class Editor {
|
|
|
261
261
|
invalidate() {
|
|
262
262
|
// No cached state to invalidate currently
|
|
263
263
|
}
|
|
264
|
+
renderCursorOnLine(displayText, lineVisibleWidth, layoutLine, width) {
|
|
265
|
+
const before = displayText.slice(0, layoutLine.cursorPos);
|
|
266
|
+
const after = displayText.slice(layoutLine.cursorPos);
|
|
267
|
+
if (after.length > 0) {
|
|
268
|
+
const afterGraphemes = [...getSegmenter().segment(after)];
|
|
269
|
+
const firstGrapheme = afterGraphemes[0]?.segment || "";
|
|
270
|
+
const restAfter = after.slice(firstGrapheme.length);
|
|
271
|
+
const cursor = `\x1b[7m${firstGrapheme}\x1b[0m`;
|
|
272
|
+
return { displayText: before + cursor + restAfter, lineVisibleWidth };
|
|
273
|
+
}
|
|
274
|
+
if (lineVisibleWidth < width) {
|
|
275
|
+
const cursor = "\x1b[7m \x1b[0m";
|
|
276
|
+
return {
|
|
277
|
+
displayText: before + cursor,
|
|
278
|
+
lineVisibleWidth: lineVisibleWidth + 1,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const beforeGraphemes = [...getSegmenter().segment(before)];
|
|
282
|
+
if (beforeGraphemes.length > 0) {
|
|
283
|
+
const lastGrapheme = beforeGraphemes[beforeGraphemes.length - 1]?.segment || "";
|
|
284
|
+
const cursor = `\x1b[7m${lastGrapheme}\x1b[0m`;
|
|
285
|
+
const beforeWithoutLast = beforeGraphemes
|
|
286
|
+
.slice(0, -1)
|
|
287
|
+
.map((g) => g.segment)
|
|
288
|
+
.join("");
|
|
289
|
+
return { displayText: beforeWithoutLast + cursor, lineVisibleWidth };
|
|
290
|
+
}
|
|
291
|
+
return { displayText, lineVisibleWidth };
|
|
292
|
+
}
|
|
264
293
|
render(width) {
|
|
265
294
|
// Store width for cursor navigation
|
|
266
295
|
this.lastWidth = width;
|
|
@@ -274,50 +303,12 @@ export class Editor {
|
|
|
274
303
|
for (const layoutLine of layoutLines) {
|
|
275
304
|
let displayText = layoutLine.text;
|
|
276
305
|
let lineVisibleWidth = layoutLine.width;
|
|
277
|
-
// Add cursor if this line has it
|
|
278
306
|
if (layoutLine.hasCursor && layoutLine.cursorPos !== undefined) {
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
// Cursor is on a character (grapheme) - replace it with highlighted version
|
|
283
|
-
// Get the first grapheme from 'after'
|
|
284
|
-
const afterGraphemes = [...getSegmenter().segment(after)];
|
|
285
|
-
const firstGrapheme = afterGraphemes[0]?.segment || "";
|
|
286
|
-
const restAfter = after.slice(firstGrapheme.length);
|
|
287
|
-
const cursor = `\x1b[7m${firstGrapheme}\x1b[0m`;
|
|
288
|
-
displayText = before + cursor + restAfter;
|
|
289
|
-
// lineVisibleWidth stays the same - we're replacing, not adding
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
// Cursor is at the end - check if we have room for the space
|
|
293
|
-
if (lineVisibleWidth < width) {
|
|
294
|
-
// We have room - add highlighted space
|
|
295
|
-
const cursor = "\x1b[7m \x1b[0m";
|
|
296
|
-
displayText = before + cursor;
|
|
297
|
-
// lineVisibleWidth increases by 1 - we're adding a space
|
|
298
|
-
lineVisibleWidth = lineVisibleWidth + 1;
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
// Line is at full width - use reverse video on last grapheme if possible
|
|
302
|
-
// or just show cursor at the end without adding space
|
|
303
|
-
const beforeGraphemes = [...getSegmenter().segment(before)];
|
|
304
|
-
if (beforeGraphemes.length > 0) {
|
|
305
|
-
const lastGrapheme = beforeGraphemes[beforeGraphemes.length - 1]?.segment || "";
|
|
306
|
-
const cursor = `\x1b[7m${lastGrapheme}\x1b[0m`;
|
|
307
|
-
// Rebuild 'before' without the last grapheme
|
|
308
|
-
const beforeWithoutLast = beforeGraphemes
|
|
309
|
-
.slice(0, -1)
|
|
310
|
-
.map((g) => g.segment)
|
|
311
|
-
.join("");
|
|
312
|
-
displayText = beforeWithoutLast + cursor;
|
|
313
|
-
}
|
|
314
|
-
// lineVisibleWidth stays the same
|
|
315
|
-
}
|
|
316
|
-
}
|
|
307
|
+
const cursorResult = this.renderCursorOnLine(displayText, lineVisibleWidth, layoutLine, width);
|
|
308
|
+
displayText = cursorResult.displayText;
|
|
309
|
+
lineVisibleWidth = cursorResult.lineVisibleWidth;
|
|
317
310
|
}
|
|
318
|
-
// Calculate padding based on actual visible width
|
|
319
311
|
const padding = " ".repeat(Math.max(0, width - lineVisibleWidth));
|
|
320
|
-
// Render the line (no side borders, just horizontal lines above and below)
|
|
321
312
|
result.push(displayText + padding);
|
|
322
313
|
}
|
|
323
314
|
// Render bottom border
|
|
@@ -624,58 +615,62 @@ export class Editor {
|
|
|
624
615
|
const metrics = lineMetricsCache.get(line);
|
|
625
616
|
const lineVisibleWidth = metrics.totalWidth;
|
|
626
617
|
if (lineVisibleWidth <= contentWidth) {
|
|
627
|
-
|
|
628
|
-
if (isCurrentLine) {
|
|
629
|
-
layoutLines.push({
|
|
630
|
-
text: line,
|
|
631
|
-
hasCursor: true,
|
|
632
|
-
cursorPos: this.state.cursorCol,
|
|
633
|
-
width: lineVisibleWidth,
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
else {
|
|
637
|
-
layoutLines.push({
|
|
638
|
-
text: line,
|
|
639
|
-
hasCursor: false,
|
|
640
|
-
width: lineVisibleWidth,
|
|
641
|
-
});
|
|
642
|
-
}
|
|
618
|
+
this.pushSingleLayoutLine(layoutLines, line, isCurrentLine, lineVisibleWidth);
|
|
643
619
|
}
|
|
644
620
|
else {
|
|
645
|
-
// Line needs wrapping - use shared helper
|
|
646
621
|
const chunks = computeLineChunks(line, contentWidth);
|
|
647
|
-
|
|
648
|
-
const chunk = chunks[chunkIndex];
|
|
649
|
-
if (!chunk)
|
|
650
|
-
continue;
|
|
651
|
-
const cursorPos = this.state.cursorCol;
|
|
652
|
-
const isLastChunk = chunkIndex === chunks.length - 1;
|
|
653
|
-
// For non-last chunks, cursor at endIndex belongs to the next chunk
|
|
654
|
-
const hasCursorInChunk = isCurrentLine &&
|
|
655
|
-
cursorPos >= chunk.startIndex &&
|
|
656
|
-
(isLastChunk
|
|
657
|
-
? cursorPos <= chunk.endIndex
|
|
658
|
-
: cursorPos < chunk.endIndex);
|
|
659
|
-
if (hasCursorInChunk) {
|
|
660
|
-
layoutLines.push({
|
|
661
|
-
text: chunk.text,
|
|
662
|
-
hasCursor: true,
|
|
663
|
-
cursorPos: cursorPos - chunk.startIndex,
|
|
664
|
-
width: chunk.width,
|
|
665
|
-
});
|
|
666
|
-
}
|
|
667
|
-
else {
|
|
668
|
-
layoutLines.push({
|
|
669
|
-
text: chunk.text,
|
|
670
|
-
hasCursor: false,
|
|
671
|
-
width: chunk.width,
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
}
|
|
622
|
+
this.pushWrappedLayoutLines(layoutLines, chunks, isCurrentLine);
|
|
675
623
|
}
|
|
676
624
|
}
|
|
677
625
|
return layoutLines;
|
|
678
626
|
}
|
|
627
|
+
pushSingleLayoutLine(layoutLines, line, isCurrentLine, width) {
|
|
628
|
+
if (isCurrentLine) {
|
|
629
|
+
layoutLines.push({
|
|
630
|
+
text: line,
|
|
631
|
+
hasCursor: true,
|
|
632
|
+
cursorPos: this.state.cursorCol,
|
|
633
|
+
width,
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
layoutLines.push({
|
|
638
|
+
text: line,
|
|
639
|
+
hasCursor: false,
|
|
640
|
+
width,
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
pushWrappedLayoutLines(layoutLines, chunks, isCurrentLine) {
|
|
645
|
+
const cursorPos = this.state.cursorCol;
|
|
646
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
647
|
+
const chunk = chunks[chunkIndex];
|
|
648
|
+
if (!chunk)
|
|
649
|
+
continue;
|
|
650
|
+
const isLastChunk = chunkIndex === chunks.length - 1;
|
|
651
|
+
// For non-last chunks, cursor at endIndex belongs to the next chunk
|
|
652
|
+
const hasCursorInChunk = isCurrentLine &&
|
|
653
|
+
cursorPos >= chunk.startIndex &&
|
|
654
|
+
(isLastChunk
|
|
655
|
+
? cursorPos <= chunk.endIndex
|
|
656
|
+
: cursorPos < chunk.endIndex);
|
|
657
|
+
if (hasCursorInChunk) {
|
|
658
|
+
layoutLines.push({
|
|
659
|
+
text: chunk.text,
|
|
660
|
+
hasCursor: true,
|
|
661
|
+
cursorPos: cursorPos - chunk.startIndex,
|
|
662
|
+
width: chunk.width,
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
layoutLines.push({
|
|
667
|
+
text: chunk.text,
|
|
668
|
+
hasCursor: false,
|
|
669
|
+
width: chunk.width,
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
679
674
|
getText() {
|
|
680
675
|
return this.state.lines.join("\n");
|
|
681
676
|
}
|
|
@@ -713,69 +708,59 @@ export class Editor {
|
|
|
713
708
|
}
|
|
714
709
|
}
|
|
715
710
|
handlePaste(pastedText) {
|
|
716
|
-
// Clean the pasted text
|
|
717
711
|
const cleanText = pastedText.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
718
|
-
// Convert tabs to spaces (4 spaces per tab)
|
|
719
712
|
const tabExpandedText = cleanText.replace(/\t/g, " ");
|
|
720
|
-
// Filter out non-printable characters except newlines
|
|
721
713
|
const filteredText = tabExpandedText
|
|
722
714
|
.split("")
|
|
723
715
|
.filter((char) => char === "\n" || (char >= " " && char <= "~"))
|
|
724
716
|
.join("");
|
|
725
|
-
// Split into lines
|
|
726
717
|
const pastedLines = filteredText.split("\n");
|
|
727
|
-
// Check if this is a large paste (> 10 lines or > 1000 characters)
|
|
728
718
|
const totalChars = filteredText.length;
|
|
729
719
|
if (pastedLines.length > 10 || totalChars > 1000) {
|
|
730
|
-
|
|
731
|
-
this.pasteCounter++;
|
|
732
|
-
const pasteId = this.pasteCounter;
|
|
733
|
-
this.pastes.set(pasteId, filteredText);
|
|
734
|
-
// Insert marker like "[paste #1 +123 lines]" or "[paste #1 1234 chars]"
|
|
735
|
-
const marker = pastedLines.length > 10
|
|
736
|
-
? `[paste #${pasteId} +${pastedLines.length} lines]`
|
|
737
|
-
: `[paste #${pasteId} ${totalChars} chars]`;
|
|
738
|
-
for (const char of marker) {
|
|
739
|
-
this.insertCharacter(char, true);
|
|
740
|
-
}
|
|
720
|
+
this.handleLargePaste(filteredText, pastedLines, totalChars);
|
|
741
721
|
return;
|
|
742
722
|
}
|
|
743
723
|
if (pastedLines.length === 1) {
|
|
744
|
-
|
|
745
|
-
const text = pastedLines[0] || "";
|
|
746
|
-
for (const char of text) {
|
|
747
|
-
this.insertCharacter(char, true);
|
|
748
|
-
}
|
|
724
|
+
this.handleSingleLinePaste(pastedLines[0] || "");
|
|
749
725
|
return;
|
|
750
726
|
}
|
|
751
|
-
|
|
727
|
+
this.handleMultiLinePaste(pastedLines);
|
|
728
|
+
}
|
|
729
|
+
handleLargePaste(filteredText, pastedLines, totalChars) {
|
|
730
|
+
this.pasteCounter++;
|
|
731
|
+
const pasteId = this.pasteCounter;
|
|
732
|
+
this.pastes.set(pasteId, filteredText);
|
|
733
|
+
const marker = pastedLines.length > 10
|
|
734
|
+
? `[paste #${pasteId} +${pastedLines.length} lines]`
|
|
735
|
+
: `[paste #${pasteId} ${totalChars} chars]`;
|
|
736
|
+
for (const char of marker) {
|
|
737
|
+
this.insertCharacter(char, true);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
handleSingleLinePaste(text) {
|
|
741
|
+
for (const char of text) {
|
|
742
|
+
this.insertCharacter(char, true);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
handleMultiLinePaste(pastedLines) {
|
|
752
746
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
753
747
|
const beforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
754
748
|
const afterCursor = currentLine.slice(this.state.cursorCol);
|
|
755
|
-
// Build the new lines array step by step
|
|
756
749
|
const newLines = [];
|
|
757
|
-
// Add all lines before current line
|
|
758
750
|
for (let i = 0; i < this.state.cursorLine; i++) {
|
|
759
751
|
newLines.push(this.state.lines[i] || "");
|
|
760
752
|
}
|
|
761
|
-
// Add the first pasted line merged with before cursor text
|
|
762
753
|
newLines.push(beforeCursor + (pastedLines[0] || ""));
|
|
763
|
-
// Add all middle pasted lines
|
|
764
754
|
for (let i = 1; i < pastedLines.length - 1; i++) {
|
|
765
755
|
newLines.push(pastedLines[i] || "");
|
|
766
756
|
}
|
|
767
|
-
// Add the last pasted line with after cursor text
|
|
768
757
|
newLines.push((pastedLines[pastedLines.length - 1] || "") + afterCursor);
|
|
769
|
-
// Add all lines after current line
|
|
770
758
|
for (let i = this.state.cursorLine + 1; i < this.state.lines.length; i++) {
|
|
771
759
|
newLines.push(this.state.lines[i] || "");
|
|
772
760
|
}
|
|
773
|
-
// Replace the entire lines array
|
|
774
761
|
this.state.lines = newLines;
|
|
775
|
-
// Update cursor position to end of pasted content
|
|
776
762
|
this.state.cursorLine += pastedLines.length - 1;
|
|
777
763
|
this.state.cursorCol = (pastedLines[pastedLines.length - 1] || "").length;
|
|
778
|
-
// Notify of change
|
|
779
764
|
if (this.onChange) {
|
|
780
765
|
this.onChange(this.getText());
|
|
781
766
|
}
|
|
@@ -892,49 +877,54 @@ export class Editor {
|
|
|
892
877
|
deleteWordBackwards() {
|
|
893
878
|
this.historyIndex = -1; // Exit history browsing mode
|
|
894
879
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
895
|
-
// If at start of line, behave like backspace at column 0 (merge with previous line)
|
|
896
880
|
if (this.state.cursorCol === 0) {
|
|
897
|
-
|
|
898
|
-
const previousLine = this.state.lines[this.state.cursorLine - 1] || "";
|
|
899
|
-
this.state.lines[this.state.cursorLine - 1] =
|
|
900
|
-
previousLine + currentLine;
|
|
901
|
-
this.state.lines.splice(this.state.cursorLine, 1);
|
|
902
|
-
this.state.cursorLine--;
|
|
903
|
-
this.state.cursorCol = previousLine.length;
|
|
904
|
-
}
|
|
881
|
+
this.mergeLineWithPrevious(currentLine);
|
|
905
882
|
}
|
|
906
883
|
else {
|
|
907
|
-
|
|
908
|
-
const isWhitespace = (char) => /\s/.test(char);
|
|
909
|
-
const isPunctuation = (char) => {
|
|
910
|
-
// Treat obvious code punctuation as boundaries
|
|
911
|
-
return /[(){}[\]<>.,;:'"!?+\-=*/\\|&%^$#@~`]/.test(char);
|
|
912
|
-
};
|
|
913
|
-
let deleteFrom = this.state.cursorCol;
|
|
914
|
-
const lastChar = textBeforeCursor[deleteFrom - 1] ?? "";
|
|
915
|
-
// If immediately on whitespace or punctuation, delete that single boundary char
|
|
916
|
-
if (isWhitespace(lastChar) || isPunctuation(lastChar)) {
|
|
917
|
-
deleteFrom -= 1;
|
|
918
|
-
}
|
|
919
|
-
else {
|
|
920
|
-
// Otherwise, delete a run of non-boundary characters (the "word")
|
|
921
|
-
while (deleteFrom > 0) {
|
|
922
|
-
const ch = textBeforeCursor[deleteFrom - 1] ?? "";
|
|
923
|
-
if (isWhitespace(ch) || isPunctuation(ch)) {
|
|
924
|
-
break;
|
|
925
|
-
}
|
|
926
|
-
deleteFrom -= 1;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
this.state.lines[this.state.cursorLine] =
|
|
930
|
-
currentLine.slice(0, deleteFrom) +
|
|
931
|
-
currentLine.slice(this.state.cursorCol);
|
|
932
|
-
this.state.cursorCol = deleteFrom;
|
|
884
|
+
this.deleteWordOnCurrentLine(currentLine);
|
|
933
885
|
}
|
|
934
886
|
if (this.onChange) {
|
|
935
887
|
this.onChange(this.getText());
|
|
936
888
|
}
|
|
937
889
|
}
|
|
890
|
+
mergeLineWithPrevious(currentLine) {
|
|
891
|
+
if (this.state.cursorLine <= 0)
|
|
892
|
+
return;
|
|
893
|
+
const previousLine = this.state.lines[this.state.cursorLine - 1] || "";
|
|
894
|
+
this.state.lines[this.state.cursorLine - 1] = previousLine + currentLine;
|
|
895
|
+
this.state.lines.splice(this.state.cursorLine, 1);
|
|
896
|
+
this.state.cursorLine--;
|
|
897
|
+
this.state.cursorCol = previousLine.length;
|
|
898
|
+
}
|
|
899
|
+
deleteWordOnCurrentLine(currentLine) {
|
|
900
|
+
const deleteFrom = this.findWordBoundaryBackwards(currentLine, this.state.cursorCol);
|
|
901
|
+
this.state.lines[this.state.cursorLine] =
|
|
902
|
+
currentLine.slice(0, deleteFrom) +
|
|
903
|
+
currentLine.slice(this.state.cursorCol);
|
|
904
|
+
this.state.cursorCol = deleteFrom;
|
|
905
|
+
}
|
|
906
|
+
findWordBoundaryBackwards(text, fromIndex) {
|
|
907
|
+
const textBeforeCursor = text.slice(0, fromIndex);
|
|
908
|
+
let deleteFrom = fromIndex;
|
|
909
|
+
const lastChar = textBeforeCursor[deleteFrom - 1] ?? "";
|
|
910
|
+
if (this.isWordBoundaryChar(lastChar)) {
|
|
911
|
+
return deleteFrom - 1;
|
|
912
|
+
}
|
|
913
|
+
while (deleteFrom > 0) {
|
|
914
|
+
const ch = textBeforeCursor[deleteFrom - 1] ?? "";
|
|
915
|
+
if (this.isWordBoundaryChar(ch)) {
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
deleteFrom -= 1;
|
|
919
|
+
}
|
|
920
|
+
return deleteFrom;
|
|
921
|
+
}
|
|
922
|
+
isWordBoundaryChar(char) {
|
|
923
|
+
if (/\s/.test(char))
|
|
924
|
+
return true;
|
|
925
|
+
// Treat obvious code punctuation as boundaries
|
|
926
|
+
return /[(){}[\]<>.,;:'"!?+\-=*/\\|&%^$#@~`]/.test(char);
|
|
927
|
+
}
|
|
938
928
|
/**
|
|
939
929
|
* Build a mapping from visual lines to logical positions.
|
|
940
930
|
* Returns an array where each element represents a visual line with:
|
|
@@ -994,53 +984,49 @@ export class Editor {
|
|
|
994
984
|
return visualLines.length - 1;
|
|
995
985
|
}
|
|
996
986
|
moveCursor(deltaLine, deltaCol) {
|
|
997
|
-
const width = this.lastWidth;
|
|
998
987
|
if (deltaLine !== 0) {
|
|
999
|
-
|
|
1000
|
-
const visualLines = this.buildVisualLineMap(width);
|
|
1001
|
-
const currentVisualLine = this.findCurrentVisualLine(visualLines);
|
|
1002
|
-
// Calculate column position within current visual line
|
|
1003
|
-
const currentVl = visualLines[currentVisualLine];
|
|
1004
|
-
const visualCol = currentVl
|
|
1005
|
-
? this.state.cursorCol - currentVl.startCol
|
|
1006
|
-
: 0;
|
|
1007
|
-
// Move to target visual line
|
|
1008
|
-
const targetVisualLine = currentVisualLine + deltaLine;
|
|
1009
|
-
if (targetVisualLine >= 0 && targetVisualLine < visualLines.length) {
|
|
1010
|
-
const targetVl = visualLines[targetVisualLine];
|
|
1011
|
-
if (targetVl) {
|
|
1012
|
-
this.state.cursorLine = targetVl.logicalLine;
|
|
1013
|
-
// Try to maintain visual column position, clamped to line length
|
|
1014
|
-
const targetCol = targetVl.startCol + Math.min(visualCol, targetVl.length);
|
|
1015
|
-
const logicalLine = this.state.lines[targetVl.logicalLine] || "";
|
|
1016
|
-
this.state.cursorCol = Math.min(targetCol, logicalLine.length);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
988
|
+
this.moveCursorVertical(deltaLine);
|
|
1019
989
|
}
|
|
1020
990
|
if (deltaCol !== 0) {
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
991
|
+
this.moveCursorHorizontal(deltaCol);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
moveCursorVertical(deltaLine) {
|
|
995
|
+
const width = this.lastWidth;
|
|
996
|
+
const visualLines = this.buildVisualLineMap(width);
|
|
997
|
+
const currentVisualLine = this.findCurrentVisualLine(visualLines);
|
|
998
|
+
const currentVl = visualLines[currentVisualLine];
|
|
999
|
+
const visualCol = currentVl ? this.state.cursorCol - currentVl.startCol : 0;
|
|
1000
|
+
const targetVisualLine = currentVisualLine + deltaLine;
|
|
1001
|
+
if (targetVisualLine >= 0 && targetVisualLine < visualLines.length) {
|
|
1002
|
+
const targetVl = visualLines[targetVisualLine];
|
|
1003
|
+
if (targetVl) {
|
|
1004
|
+
this.state.cursorLine = targetVl.logicalLine;
|
|
1005
|
+
const targetCol = targetVl.startCol + Math.min(visualCol, targetVl.length);
|
|
1006
|
+
const logicalLine = this.state.lines[targetVl.logicalLine] || "";
|
|
1007
|
+
this.state.cursorCol = Math.min(targetCol, logicalLine.length);
|
|
1032
1008
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
moveCursorHorizontal(deltaCol) {
|
|
1012
|
+
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
1013
|
+
if (deltaCol > 0) {
|
|
1014
|
+
if (this.state.cursorCol < currentLine.length) {
|
|
1015
|
+
this.state.cursorCol++;
|
|
1016
|
+
}
|
|
1017
|
+
else if (this.state.cursorLine < this.state.lines.length - 1) {
|
|
1018
|
+
this.state.cursorLine++;
|
|
1019
|
+
this.state.cursorCol = 0;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
else {
|
|
1023
|
+
if (this.state.cursorCol > 0) {
|
|
1024
|
+
this.state.cursorCol--;
|
|
1025
|
+
}
|
|
1026
|
+
else if (this.state.cursorLine > 0) {
|
|
1027
|
+
this.state.cursorLine--;
|
|
1028
|
+
const prevLine = this.state.lines[this.state.cursorLine] || "";
|
|
1029
|
+
this.state.cursorCol = prevLine.length;
|
|
1044
1030
|
}
|
|
1045
1031
|
}
|
|
1046
1032
|
}
|
|
@@ -8,7 +8,6 @@ type State = {
|
|
|
8
8
|
currentContextWindow: number;
|
|
9
9
|
contextWindow: number;
|
|
10
10
|
agentState?: AgentState;
|
|
11
|
-
currentMode?: string;
|
|
12
11
|
};
|
|
13
12
|
export declare class FooterComponent implements Component {
|
|
14
13
|
private modelManager;
|
|
@@ -16,7 +15,6 @@ export declare class FooterComponent implements Component {
|
|
|
16
15
|
private state;
|
|
17
16
|
private progressBar;
|
|
18
17
|
private agentState?;
|
|
19
|
-
private currentMode;
|
|
20
18
|
constructor(modelManager: ModelManager, tokenTracker: TokenTracker | undefined, state: State);
|
|
21
19
|
setState(state: State): void;
|
|
22
20
|
resetState(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,WAAW,CAAC;AAGzD,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,WAAW,CAAC;AAGzD,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AA2CF,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,UAAU,CAAC,CAAa;gBAE9B,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,KAAK,EAAE,KAAK;IAad,QAAQ,CAAC,KAAK,EAAE,KAAK;IASrB,UAAU;IAIV,gBAAgB,IAAI,iBAAiB;IAIrC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAkEhC"}
|
|
@@ -41,7 +41,6 @@ export class FooterComponent {
|
|
|
41
41
|
state;
|
|
42
42
|
progressBar;
|
|
43
43
|
agentState;
|
|
44
|
-
currentMode = "Normal";
|
|
45
44
|
constructor(modelManager, tokenTracker, state) {
|
|
46
45
|
this.modelManager = modelManager;
|
|
47
46
|
this.tokenTracker = tokenTracker;
|
|
@@ -53,9 +52,6 @@ export class FooterComponent {
|
|
|
53
52
|
if (state.agentState) {
|
|
54
53
|
this.agentState = state.agentState;
|
|
55
54
|
}
|
|
56
|
-
if (state.currentMode !== undefined) {
|
|
57
|
-
this.currentMode = state.currentMode;
|
|
58
|
-
}
|
|
59
55
|
this.state = state;
|
|
60
56
|
this.progressBar.setCurrent(state.currentContextWindow);
|
|
61
57
|
this.progressBar.setTotal(state.contextWindow);
|
|
@@ -72,20 +68,8 @@ export class FooterComponent {
|
|
|
72
68
|
const [pathLine, gitLine] = formatProjectStatus(this.state.projectStatus);
|
|
73
69
|
const padding = Math.max(0, width - visibleWidth(pathLine) - modelInfo.length);
|
|
74
70
|
results.push(pathLine + " ".repeat(padding) + style.dim(modelInfo));
|
|
75
|
-
const modeDisplay = this.currentMode !== "Normal"
|
|
76
|
-
? style.magenta(`[${this.currentMode}]`)
|
|
77
|
-
: "";
|
|
78
71
|
if (gitLine) {
|
|
79
|
-
|
|
80
|
-
const gitPadding = Math.max(0, width - visibleWidth(gitLine) - visibleWidth(modeDisplay));
|
|
81
|
-
results.push(`${gitLine}${" ".repeat(gitPadding)}${modeDisplay}`);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
results.push(gitLine);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
else if (modeDisplay) {
|
|
88
|
-
results.push(modeDisplay);
|
|
72
|
+
results.push(gitLine);
|
|
89
73
|
}
|
|
90
74
|
// Line 3: Total session usage from token tracker (accumulated across all turns)
|
|
91
75
|
if (this.tokenTracker) {
|
|
@@ -9,6 +9,10 @@ export declare class Input implements Component {
|
|
|
9
9
|
getValue(): string;
|
|
10
10
|
setValue(value: string): void;
|
|
11
11
|
handleInput(data: string): void;
|
|
12
|
+
private handleSpecialKey;
|
|
13
|
+
private backspace;
|
|
14
|
+
private deleteForward;
|
|
15
|
+
private insertCharacter;
|
|
12
16
|
render(width: number): string[];
|
|
13
17
|
}
|
|
14
18
|
//# sourceMappingURL=input.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../source/tui/components/input.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;;GAEG;AACH,qBAAa,KAAM,YAAW,SAAS;IACrC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,MAAM,CAAK;IACZ,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../source/tui/components/input.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;;GAEG;AACH,qBAAa,KAAM,YAAW,SAAS;IACrC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,MAAM,CAAK;IACZ,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK/B,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,eAAe;IAQvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAuDhC"}
|