@armadra/agent 0.0.0-stage → 0.2.1
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/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +426 -2
- package/dist/agent/agent.d.ts +56 -0
- package/dist/agent/agent.js +129 -0
- package/dist/agent/loop.d.ts +51 -0
- package/dist/agent/loop.js +158 -0
- package/dist/agent/queue.d.ts +25 -0
- package/dist/agent/queue.js +55 -0
- package/dist/agent/retry.d.ts +22 -0
- package/dist/agent/retry.js +92 -0
- package/dist/agent/schema.d.ts +27 -0
- package/dist/agent/schema.js +186 -0
- package/dist/agent/session-cache.d.ts +100 -0
- package/dist/agent/session-cache.js +511 -0
- package/dist/agent/session-compaction.d.ts +49 -0
- package/dist/agent/session-compaction.js +251 -0
- package/dist/agent/session-core.d.ts +103 -0
- package/dist/agent/session-core.js +7 -0
- package/dist/agent/session-run.d.ts +55 -0
- package/dist/agent/session-run.js +246 -0
- package/dist/agent/session-state.d.ts +39 -0
- package/dist/agent/session-state.js +118 -0
- package/dist/agent/session-subagent.d.ts +54 -0
- package/dist/agent/session-subagent.js +157 -0
- package/dist/agent/session-sync.d.ts +20 -0
- package/dist/agent/session-sync.js +104 -0
- package/dist/agent/session-tools.d.ts +24 -0
- package/dist/agent/session-tools.js +277 -0
- package/dist/agent/session.d.ts +117 -0
- package/dist/agent/session.js +484 -0
- package/dist/agent/system-prompt.d.ts +49 -0
- package/dist/agent/system-prompt.js +121 -0
- package/dist/agent/tool-runner.d.ts +64 -0
- package/dist/agent/tool-runner.js +309 -0
- package/dist/agent/transform.d.ts +26 -0
- package/dist/agent/transform.js +171 -0
- package/dist/agent/types.d.ts +378 -0
- package/dist/agent/types.js +21 -0
- package/dist/ai/apis/anthropic-messages.d.ts +26 -0
- package/dist/ai/apis/anthropic-messages.js +214 -0
- package/dist/ai/apis/anthropic-request.d.ts +42 -0
- package/dist/ai/apis/anthropic-request.js +282 -0
- package/dist/ai/apis/api.d.ts +28 -0
- package/dist/ai/apis/api.js +102 -0
- package/dist/ai/apis/cache-params.d.ts +48 -0
- package/dist/ai/apis/cache-params.js +163 -0
- package/dist/ai/apis/google-generative-ai.d.ts +32 -0
- package/dist/ai/apis/google-generative-ai.js +249 -0
- package/dist/ai/apis/google-request.d.ts +40 -0
- package/dist/ai/apis/google-request.js +255 -0
- package/dist/ai/apis/openai-compat.d.ts +35 -0
- package/dist/ai/apis/openai-compat.js +142 -0
- package/dist/ai/apis/openai-completions.d.ts +28 -0
- package/dist/ai/apis/openai-completions.js +246 -0
- package/dist/ai/apis/openai-request.d.ts +35 -0
- package/dist/ai/apis/openai-request.js +303 -0
- package/dist/ai/apis/openai-responses-request.d.ts +52 -0
- package/dist/ai/apis/openai-responses-request.js +266 -0
- package/dist/ai/apis/openai-responses.d.ts +28 -0
- package/dist/ai/apis/openai-responses.js +303 -0
- package/dist/ai/apis/shared.d.ts +56 -0
- package/dist/ai/apis/shared.js +179 -0
- package/dist/ai/cache/economics.d.ts +24 -0
- package/dist/ai/cache/economics.js +69 -0
- package/dist/ai/cache/fingerprint.d.ts +17 -0
- package/dist/ai/cache/fingerprint.js +39 -0
- package/dist/ai/cache/miss.d.ts +49 -0
- package/dist/ai/cache/miss.js +96 -0
- package/dist/ai/cache/reporting.d.ts +39 -0
- package/dist/ai/cache/reporting.js +102 -0
- package/dist/ai/cache/types.d.ts +94 -0
- package/dist/ai/cache/types.js +19 -0
- package/dist/ai/cache/warmer.d.ts +94 -0
- package/dist/ai/cache/warmer.js +224 -0
- package/dist/ai/context.d.ts +35 -0
- package/dist/ai/context.js +114 -0
- package/dist/ai/cost.d.ts +21 -0
- package/dist/ai/cost.js +60 -0
- package/dist/ai/event-stream.d.ts +33 -0
- package/dist/ai/event-stream.js +101 -0
- package/dist/ai/fake/fake-provider.d.ts +68 -0
- package/dist/ai/fake/fake-provider.js +278 -0
- package/dist/ai/fake/fake-script.d.ts +69 -0
- package/dist/ai/fake/fake-script.js +142 -0
- package/dist/ai/http.d.ts +54 -0
- package/dist/ai/http.js +212 -0
- package/dist/ai/json-partial.d.ts +17 -0
- package/dist/ai/json-partial.js +243 -0
- package/dist/ai/overflow.d.ts +22 -0
- package/dist/ai/overflow.js +61 -0
- package/dist/ai/providers/auth.d.ts +71 -0
- package/dist/ai/providers/auth.js +202 -0
- package/dist/ai/providers/builtin.d.ts +23 -0
- package/dist/ai/providers/builtin.js +148 -0
- package/dist/ai/providers/catalog-data.d.ts +5 -0
- package/dist/ai/providers/catalog-data.js +19 -0
- package/dist/ai/providers/catalog.d.ts +28 -0
- package/dist/ai/providers/catalog.js +166 -0
- package/dist/ai/providers/registry.d.ts +83 -0
- package/dist/ai/providers/registry.js +305 -0
- package/dist/ai/sse.d.ts +32 -0
- package/dist/ai/sse.js +140 -0
- package/dist/ai/thinking.d.ts +42 -0
- package/dist/ai/thinking.js +101 -0
- package/dist/ai/types.d.ts +428 -0
- package/dist/ai/types.js +19 -0
- package/dist/bundle/ama-sandbox.cjs +324 -0
- package/dist/bundle/ama.cjs +25770 -0
- package/dist/bundle.d.ts +9 -0
- package/dist/bundle.js +15 -0
- package/dist/cli/args.d.ts +82 -0
- package/dist/cli/args.js +381 -0
- package/dist/cli/bootstrap.d.ts +18 -0
- package/dist/cli/bootstrap.js +398 -0
- package/dist/cli/compose-providers.d.ts +37 -0
- package/dist/cli/compose-providers.js +104 -0
- package/dist/cli/compose-session.d.ts +69 -0
- package/dist/cli/compose-session.js +370 -0
- package/dist/cli/compose-store.d.ts +24 -0
- package/dist/cli/compose-store.js +125 -0
- package/dist/cli/compose.d.ts +106 -0
- package/dist/cli/compose.js +206 -0
- package/dist/cli/default-model.d.ts +16 -0
- package/dist/cli/default-model.js +24 -0
- package/dist/cli/deps.d.ts +205 -0
- package/dist/cli/deps.js +12 -0
- package/dist/cli/exit-codes.d.ts +29 -0
- package/dist/cli/exit-codes.js +40 -0
- package/dist/cli/main.d.ts +26 -0
- package/dist/cli/main.js +165 -0
- package/dist/cli/runtime.d.ts +90 -0
- package/dist/cli/runtime.js +8 -0
- package/dist/cli/startup-screen.d.ts +15 -0
- package/dist/cli/startup-screen.js +56 -0
- package/dist/cli/startup-steps.d.ts +35 -0
- package/dist/cli/startup-steps.js +197 -0
- package/dist/cli/subcommands/auth.d.ts +12 -0
- package/dist/cli/subcommands/auth.js +91 -0
- package/dist/cli/subcommands/config.d.ts +44 -0
- package/dist/cli/subcommands/config.js +201 -0
- package/dist/cli/subcommands/context.d.ts +21 -0
- package/dist/cli/subcommands/context.js +41 -0
- package/dist/cli/subcommands/doctor.d.ts +11 -0
- package/dist/cli/subcommands/doctor.js +246 -0
- package/dist/cli/subcommands/models-cache-probe.d.ts +34 -0
- package/dist/cli/subcommands/models-cache-probe.js +190 -0
- package/dist/cli/subcommands/models-discover.d.ts +40 -0
- package/dist/cli/subcommands/models-discover.js +204 -0
- package/dist/cli/subcommands/models.d.ts +40 -0
- package/dist/cli/subcommands/models.js +144 -0
- package/dist/cli/subcommands/sessions.d.ts +11 -0
- package/dist/cli/subcommands/sessions.js +100 -0
- package/dist/codemode/capability.d.ts +37 -0
- package/dist/codemode/capability.js +55 -0
- package/dist/codemode/declarations.d.ts +44 -0
- package/dist/codemode/declarations.js +111 -0
- package/dist/codemode/host-side.d.ts +59 -0
- package/dist/codemode/host-side.js +253 -0
- package/dist/codemode/modes.d.ts +23 -0
- package/dist/codemode/modes.js +40 -0
- package/dist/codemode/protocol.d.ts +91 -0
- package/dist/codemode/protocol.js +114 -0
- package/dist/codemode/sandbox-entry.d.ts +25 -0
- package/dist/codemode/sandbox-entry.js +323 -0
- package/dist/codemode/store.d.ts +26 -0
- package/dist/codemode/store.js +53 -0
- package/dist/codemode/tool.d.ts +105 -0
- package/dist/codemode/tool.js +283 -0
- package/dist/compaction/branch-summary.d.ts +30 -0
- package/dist/compaction/branch-summary.js +79 -0
- package/dist/compaction/breaker.d.ts +32 -0
- package/dist/compaction/breaker.js +65 -0
- package/dist/compaction/cut-point.d.ts +23 -0
- package/dist/compaction/cut-point.js +70 -0
- package/dist/compaction/estimate.d.ts +30 -0
- package/dist/compaction/estimate.js +114 -0
- package/dist/compaction/prune-tier.d.ts +31 -0
- package/dist/compaction/prune-tier.js +83 -0
- package/dist/compaction/serialize.d.ts +20 -0
- package/dist/compaction/serialize.js +115 -0
- package/dist/compaction/summarize-tier.d.ts +111 -0
- package/dist/compaction/summarize-tier.js +305 -0
- package/dist/config/auth-file.d.ts +39 -0
- package/dist/config/auth-file.js +92 -0
- package/dist/config/context-files.d.ts +30 -0
- package/dist/config/context-files.js +77 -0
- package/dist/config/load.d.ts +45 -0
- package/dist/config/load.js +97 -0
- package/dist/config/merge.d.ts +73 -0
- package/dist/config/merge.js +248 -0
- package/dist/config/paths.d.ts +38 -0
- package/dist/config/paths.js +108 -0
- package/dist/config/profile.d.ts +27 -0
- package/dist/config/profile.js +65 -0
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.js +413 -0
- package/dist/config/trust.d.ts +42 -0
- package/dist/config/trust.js +122 -0
- package/dist/config/types.d.ts +172 -0
- package/dist/config/types.js +27 -0
- package/dist/config/write.d.ts +10 -0
- package/dist/config/write.js +25 -0
- package/dist/errors.d.ts +28 -0
- package/dist/errors.js +30 -0
- package/dist/hooks/config.d.ts +49 -0
- package/dist/hooks/config.js +102 -0
- package/dist/hooks/dispatcher.d.ts +41 -0
- package/dist/hooks/dispatcher.js +104 -0
- package/dist/hooks/matcher.d.ts +22 -0
- package/dist/hooks/matcher.js +108 -0
- package/dist/hooks/protocol.d.ts +33 -0
- package/dist/hooks/protocol.js +240 -0
- package/dist/hooks/runner.d.ts +30 -0
- package/dist/hooks/runner.js +143 -0
- package/dist/hooks/types.d.ts +147 -0
- package/dist/hooks/types.js +20 -0
- package/dist/host/api-impl.d.ts +75 -0
- package/dist/host/api-impl.js +173 -0
- package/dist/host/loader.d.ts +31 -0
- package/dist/host/loader.js +147 -0
- package/dist/host/types.d.ts +169 -0
- package/dist/host/types.js +14 -0
- package/dist/host.d.ts +5 -0
- package/dist/host.js +4 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +28 -0
- package/dist/modes/commands-core.d.ts +44 -0
- package/dist/modes/commands-core.js +171 -0
- package/dist/modes/interactive/approval-dialog.d.ts +48 -0
- package/dist/modes/interactive/approval-dialog.js +202 -0
- package/dist/modes/interactive/commands.d.ts +41 -0
- package/dist/modes/interactive/commands.js +202 -0
- package/dist/modes/interactive/completion.d.ts +53 -0
- package/dist/modes/interactive/completion.js +157 -0
- package/dist/modes/interactive/interactive-mode.d.ts +46 -0
- package/dist/modes/interactive/interactive-mode.js +487 -0
- package/dist/modes/interactive/key-dispatch.d.ts +29 -0
- package/dist/modes/interactive/key-dispatch.js +107 -0
- package/dist/modes/interactive/line/line-editor.d.ts +50 -0
- package/dist/modes/interactive/line/line-editor.js +232 -0
- package/dist/modes/interactive/line/line-mode.d.ts +20 -0
- package/dist/modes/interactive/line/line-mode.js +216 -0
- package/dist/modes/interactive/line/line-render.d.ts +35 -0
- package/dist/modes/interactive/line/line-render.js +171 -0
- package/dist/modes/interactive/line/paste-state.d.ts +26 -0
- package/dist/modes/interactive/line/paste-state.js +72 -0
- package/dist/modes/interactive/message-view.d.ts +77 -0
- package/dist/modes/interactive/message-view.js +269 -0
- package/dist/modes/interactive/pickers.d.ts +42 -0
- package/dist/modes/interactive/pickers.js +115 -0
- package/dist/modes/interactive/startup-ui.d.ts +28 -0
- package/dist/modes/interactive/startup-ui.js +238 -0
- package/dist/modes/interactive/status-bar.d.ts +48 -0
- package/dist/modes/interactive/status-bar.js +139 -0
- package/dist/modes/interactive/tool-view.d.ts +95 -0
- package/dist/modes/interactive/tool-view.js +344 -0
- package/dist/modes/print/json-event.d.ts +15 -0
- package/dist/modes/print/json-event.js +39 -0
- package/dist/modes/print/print-mode.d.ts +15 -0
- package/dist/modes/print/print-mode.js +96 -0
- package/dist/modes/rpc/commands.d.ts +40 -0
- package/dist/modes/rpc/commands.js +258 -0
- package/dist/modes/rpc/jsonl.d.ts +16 -0
- package/dist/modes/rpc/jsonl.js +55 -0
- package/dist/modes/rpc/rpc-mode.d.ts +22 -0
- package/dist/modes/rpc/rpc-mode.js +153 -0
- package/dist/modes/session-report.d.ts +55 -0
- package/dist/modes/session-report.js +278 -0
- package/dist/modes/shared.d.ts +13 -0
- package/dist/modes/shared.js +52 -0
- package/dist/modes/startup-ui-text.d.ts +16 -0
- package/dist/modes/startup-ui-text.js +103 -0
- package/dist/permissions/broker.d.ts +47 -0
- package/dist/permissions/broker.js +107 -0
- package/dist/permissions/dangerous.d.ts +47 -0
- package/dist/permissions/dangerous.js +370 -0
- package/dist/permissions/pipeline.d.ts +51 -0
- package/dist/permissions/pipeline.js +181 -0
- package/dist/permissions/preview.d.ts +43 -0
- package/dist/permissions/preview.js +463 -0
- package/dist/permissions/rules.d.ts +58 -0
- package/dist/permissions/rules.js +249 -0
- package/dist/permissions/types.d.ts +100 -0
- package/dist/permissions/types.js +18 -0
- package/dist/rpc.d.ts +171 -0
- package/dist/rpc.js +13 -0
- package/dist/sdk.d.ts +98 -0
- package/dist/sdk.js +195 -0
- package/dist/session/manager.d.ts +70 -0
- package/dist/session/manager.js +278 -0
- package/dist/session/migrate.d.ts +19 -0
- package/dist/session/migrate.js +53 -0
- package/dist/session/projection.d.ts +50 -0
- package/dist/session/projection.js +180 -0
- package/dist/session/store.d.ts +47 -0
- package/dist/session/store.js +210 -0
- package/dist/session/tree.d.ts +21 -0
- package/dist/session/tree.js +88 -0
- package/dist/session/types.d.ts +199 -0
- package/dist/session/types.js +18 -0
- package/dist/skills/discover.d.ts +60 -0
- package/dist/skills/discover.js +160 -0
- package/dist/skills/expand.d.ts +35 -0
- package/dist/skills/expand.js +46 -0
- package/dist/skills/frontmatter.d.ts +27 -0
- package/dist/skills/frontmatter.js +157 -0
- package/dist/skills/index-prompt.d.ts +13 -0
- package/dist/skills/index-prompt.js +42 -0
- package/dist/skills/templates.d.ts +52 -0
- package/dist/skills/templates.js +177 -0
- package/dist/tools/bash.d.ts +49 -0
- package/dist/tools/bash.js +222 -0
- package/dist/tools/edit-fuzzy.d.ts +36 -0
- package/dist/tools/edit-fuzzy.js +129 -0
- package/dist/tools/edit.d.ts +38 -0
- package/dist/tools/edit.js +241 -0
- package/dist/tools/file-mutex.d.ts +8 -0
- package/dist/tools/file-mutex.js +29 -0
- package/dist/tools/glob.d.ts +44 -0
- package/dist/tools/glob.js +217 -0
- package/dist/tools/grep.d.ts +39 -0
- package/dist/tools/grep.js +179 -0
- package/dist/tools/ignore.d.ts +40 -0
- package/dist/tools/ignore.js +174 -0
- package/dist/tools/ls.d.ts +21 -0
- package/dist/tools/ls.js +96 -0
- package/dist/tools/output-accumulator.d.ts +48 -0
- package/dist/tools/output-accumulator.js +106 -0
- package/dist/tools/paths.d.ts +20 -0
- package/dist/tools/paths.js +58 -0
- package/dist/tools/presets.d.ts +71 -0
- package/dist/tools/presets.js +128 -0
- package/dist/tools/process-tree.d.ts +35 -0
- package/dist/tools/process-tree.js +125 -0
- package/dist/tools/read.d.ts +28 -0
- package/dist/tools/read.js +181 -0
- package/dist/tools/registry.d.ts +43 -0
- package/dist/tools/registry.js +106 -0
- package/dist/tools/shell.d.ts +38 -0
- package/dist/tools/shell.js +91 -0
- package/dist/tools/task.d.ts +29 -0
- package/dist/tools/task.js +107 -0
- package/dist/tools/todo.d.ts +28 -0
- package/dist/tools/todo.js +107 -0
- package/dist/tools/truncate.d.ts +44 -0
- package/dist/tools/truncate.js +175 -0
- package/dist/tools/types.d.ts +135 -0
- package/dist/tools/types.js +19 -0
- package/dist/tools/write.d.ts +20 -0
- package/dist/tools/write.js +84 -0
- package/dist/tui/ansi.d.ts +29 -0
- package/dist/tui/ansi.js +420 -0
- package/dist/tui/component.d.ts +38 -0
- package/dist/tui/component.js +13 -0
- package/dist/tui/components/box.d.ts +26 -0
- package/dist/tui/components/box.js +65 -0
- package/dist/tui/components/container.d.ts +14 -0
- package/dist/tui/components/container.js +39 -0
- package/dist/tui/components/editor-buffer.d.ts +67 -0
- package/dist/tui/components/editor-buffer.js +300 -0
- package/dist/tui/components/editor-paste.d.ts +29 -0
- package/dist/tui/components/editor-paste.js +64 -0
- package/dist/tui/components/editor.d.ts +114 -0
- package/dist/tui/components/editor.js +530 -0
- package/dist/tui/components/key-value.d.ts +29 -0
- package/dist/tui/components/key-value.js +48 -0
- package/dist/tui/components/loader.d.ts +35 -0
- package/dist/tui/components/loader.js +71 -0
- package/dist/tui/components/markdown.d.ts +90 -0
- package/dist/tui/components/markdown.js +462 -0
- package/dist/tui/components/meter.d.ts +29 -0
- package/dist/tui/components/meter.js +47 -0
- package/dist/tui/components/overlay.d.ts +24 -0
- package/dist/tui/components/overlay.js +52 -0
- package/dist/tui/components/select-list.d.ts +57 -0
- package/dist/tui/components/select-list.js +179 -0
- package/dist/tui/components/spacer.d.ts +11 -0
- package/dist/tui/components/spacer.js +16 -0
- package/dist/tui/components/text.d.ts +30 -0
- package/dist/tui/components/text.js +65 -0
- package/dist/tui/keybindings.d.ts +66 -0
- package/dist/tui/keybindings.js +120 -0
- package/dist/tui/keys.d.ts +38 -0
- package/dist/tui/keys.js +275 -0
- package/dist/tui/stdin-buffer.d.ts +41 -0
- package/dist/tui/stdin-buffer.js +206 -0
- package/dist/tui/terminal.d.ts +79 -0
- package/dist/tui/terminal.js +153 -0
- package/dist/tui/theme.d.ts +31 -0
- package/dist/tui/theme.js +199 -0
- package/dist/tui/tui.d.ts +103 -0
- package/dist/tui/tui.js +363 -0
- package/dist/tui/vt-screen.d.ts +46 -0
- package/dist/tui/vt-screen.js +251 -0
- package/dist/tui.d.ts +30 -0
- package/dist/tui.js +31 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.js +24 -0
- package/docs/codemode.md +102 -0
- package/docs/hooks.md +196 -0
- package/docs/host-api.md +161 -0
- package/docs/providers.md +316 -0
- package/docs/rpc.md +253 -0
- package/docs/session-format.md +119 -0
- package/docs/tui.md +168 -0
- package/package.json +101 -4
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 编辑器文本缓冲(设计 §12.4):行 / 光标 / 撤销栈(50 步)/ 单词导航 / 不可分割段。[B4]
|
|
3
|
+
*
|
|
4
|
+
* - 光标列是该行内的 UTF-16 下标,移动与删除按字素簇进行(emoji、组合字符不会被切开)。
|
|
5
|
+
* - 不可分割段(大粘贴折叠标记)由 `atomic` 回调按行给出区间:光标不会停在段内,
|
|
6
|
+
* 退格 / 删除 / 删词把整段一起删掉,单词导航把整段当作一个词。
|
|
7
|
+
* - 撤销:每次编辑前存快照;连续输入同类字符合并为一步;上限 50 步。
|
|
8
|
+
* - 不做选区(无鼠标、无 kill ring,§12.9)。
|
|
9
|
+
*/
|
|
10
|
+
const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
11
|
+
function graphemeStarts(line) {
|
|
12
|
+
const starts = [];
|
|
13
|
+
for (const { index } of segmenter.segment(line))
|
|
14
|
+
starts.push(index);
|
|
15
|
+
starts.push(line.length);
|
|
16
|
+
return starts;
|
|
17
|
+
}
|
|
18
|
+
function classify(ch) {
|
|
19
|
+
if (/\s/.test(ch))
|
|
20
|
+
return "space";
|
|
21
|
+
if (/[\p{L}\p{N}_]/u.test(ch))
|
|
22
|
+
return "word";
|
|
23
|
+
return "punct";
|
|
24
|
+
}
|
|
25
|
+
export class EditorBuffer {
|
|
26
|
+
lines = [""];
|
|
27
|
+
cur = { line: 0, col: 0 };
|
|
28
|
+
undoStack = [];
|
|
29
|
+
lastKind = null;
|
|
30
|
+
undoLimit;
|
|
31
|
+
atomic;
|
|
32
|
+
constructor(options = {}) {
|
|
33
|
+
this.undoLimit = options.undoLimit ?? 50;
|
|
34
|
+
this.atomic = options.atomic ?? (() => []);
|
|
35
|
+
}
|
|
36
|
+
get cursor() {
|
|
37
|
+
return { ...this.cur };
|
|
38
|
+
}
|
|
39
|
+
getLines() {
|
|
40
|
+
return this.lines;
|
|
41
|
+
}
|
|
42
|
+
getText() {
|
|
43
|
+
return this.lines.join("\n");
|
|
44
|
+
}
|
|
45
|
+
isEmpty() {
|
|
46
|
+
return this.lines.length === 1 && this.lines[0] === "";
|
|
47
|
+
}
|
|
48
|
+
get undoDepth() {
|
|
49
|
+
return this.undoStack.length;
|
|
50
|
+
}
|
|
51
|
+
/** 替换全部文本,光标到末尾。recordUndo=false 时不进撤销栈(历史浏览、提交清空)。 */
|
|
52
|
+
setText(text, recordUndo = true) {
|
|
53
|
+
if (recordUndo)
|
|
54
|
+
this.snapshot("other");
|
|
55
|
+
this.lines = text.split("\n");
|
|
56
|
+
const last = this.lines.length - 1;
|
|
57
|
+
this.cur = { line: last, col: this.lines[last].length };
|
|
58
|
+
if (!recordUndo)
|
|
59
|
+
this.lastKind = null;
|
|
60
|
+
}
|
|
61
|
+
/** 清空并丢弃撤销历史。 */
|
|
62
|
+
reset() {
|
|
63
|
+
this.lines = [""];
|
|
64
|
+
this.cur = { line: 0, col: 0 };
|
|
65
|
+
this.undoStack = [];
|
|
66
|
+
this.lastKind = null;
|
|
67
|
+
}
|
|
68
|
+
setCursor(pos) {
|
|
69
|
+
const line = Math.max(0, Math.min(this.lines.length - 1, pos.line));
|
|
70
|
+
const col = Math.max(0, Math.min(this.lines[line].length, pos.col));
|
|
71
|
+
this.cur = { line, col: this.snapOutOfAtomic(line, col) };
|
|
72
|
+
this.lastKind = null;
|
|
73
|
+
}
|
|
74
|
+
/** 插入文本(可含换行)。 */
|
|
75
|
+
insert(text) {
|
|
76
|
+
if (text === "")
|
|
77
|
+
return;
|
|
78
|
+
const kind = text.length <= 2 && !text.includes("\n")
|
|
79
|
+
? /\s/.test(text)
|
|
80
|
+
? "type-space"
|
|
81
|
+
: "type-word"
|
|
82
|
+
: "other";
|
|
83
|
+
this.snapshot(kind);
|
|
84
|
+
const line = this.lines[this.cur.line];
|
|
85
|
+
const before = line.slice(0, this.cur.col);
|
|
86
|
+
const after = line.slice(this.cur.col);
|
|
87
|
+
const parts = text.split("\n");
|
|
88
|
+
if (parts.length === 1) {
|
|
89
|
+
this.lines[this.cur.line] = before + text + after;
|
|
90
|
+
this.cur = { line: this.cur.line, col: this.cur.col + text.length };
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const newLines = [before + parts[0], ...parts.slice(1, -1), parts[parts.length - 1] + after];
|
|
94
|
+
this.lines.splice(this.cur.line, 1, ...newLines);
|
|
95
|
+
this.cur = { line: this.cur.line + parts.length - 1, col: parts[parts.length - 1].length };
|
|
96
|
+
}
|
|
97
|
+
newLine() {
|
|
98
|
+
this.insert("\n");
|
|
99
|
+
}
|
|
100
|
+
backspace() {
|
|
101
|
+
const { line, col } = this.cur;
|
|
102
|
+
if (col === 0) {
|
|
103
|
+
if (line === 0)
|
|
104
|
+
return;
|
|
105
|
+
this.snapshot("other");
|
|
106
|
+
const prevLen = this.lines[line - 1].length;
|
|
107
|
+
this.lines[line - 1] += this.lines[line];
|
|
108
|
+
this.lines.splice(line, 1);
|
|
109
|
+
this.cur = { line: line - 1, col: prevLen };
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const start = this.prevStop(line, col);
|
|
113
|
+
this.snapshot("other");
|
|
114
|
+
this.deleteRange(line, start, col);
|
|
115
|
+
}
|
|
116
|
+
deleteForward() {
|
|
117
|
+
const { line, col } = this.cur;
|
|
118
|
+
const text = this.lines[line];
|
|
119
|
+
if (col >= text.length) {
|
|
120
|
+
if (line >= this.lines.length - 1)
|
|
121
|
+
return;
|
|
122
|
+
this.snapshot("other");
|
|
123
|
+
this.lines[line] = text + this.lines[line + 1];
|
|
124
|
+
this.lines.splice(line + 1, 1);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
this.snapshot("other");
|
|
128
|
+
this.deleteRange(line, col, this.nextStop(line, col));
|
|
129
|
+
}
|
|
130
|
+
moveLeft() {
|
|
131
|
+
const { line, col } = this.cur;
|
|
132
|
+
if (col > 0)
|
|
133
|
+
this.cur = { line, col: this.prevStop(line, col) };
|
|
134
|
+
else if (line > 0)
|
|
135
|
+
this.cur = { line: line - 1, col: this.lines[line - 1].length };
|
|
136
|
+
this.lastKind = null;
|
|
137
|
+
}
|
|
138
|
+
moveRight() {
|
|
139
|
+
const { line, col } = this.cur;
|
|
140
|
+
if (col < this.lines[line].length)
|
|
141
|
+
this.cur = { line, col: this.nextStop(line, col) };
|
|
142
|
+
else if (line < this.lines.length - 1)
|
|
143
|
+
this.cur = { line: line + 1, col: 0 };
|
|
144
|
+
this.lastKind = null;
|
|
145
|
+
}
|
|
146
|
+
moveLineStart() {
|
|
147
|
+
this.cur = { line: this.cur.line, col: 0 };
|
|
148
|
+
this.lastKind = null;
|
|
149
|
+
}
|
|
150
|
+
moveLineEnd() {
|
|
151
|
+
this.cur = { line: this.cur.line, col: this.lines[this.cur.line].length };
|
|
152
|
+
this.lastKind = null;
|
|
153
|
+
}
|
|
154
|
+
moveWordLeft() {
|
|
155
|
+
const { line, col } = this.cur;
|
|
156
|
+
if (col === 0)
|
|
157
|
+
return this.moveLeft();
|
|
158
|
+
this.cur = { line, col: this.wordStartBefore(line, col) };
|
|
159
|
+
this.lastKind = null;
|
|
160
|
+
}
|
|
161
|
+
moveWordRight() {
|
|
162
|
+
const { line, col } = this.cur;
|
|
163
|
+
if (col >= this.lines[line].length)
|
|
164
|
+
return this.moveRight();
|
|
165
|
+
this.cur = { line, col: this.wordEndAfter(line, col) };
|
|
166
|
+
this.lastKind = null;
|
|
167
|
+
}
|
|
168
|
+
deleteWordBackward() {
|
|
169
|
+
const { line, col } = this.cur;
|
|
170
|
+
if (col === 0)
|
|
171
|
+
return this.backspace();
|
|
172
|
+
this.snapshot("other");
|
|
173
|
+
this.deleteRange(line, this.wordStartBefore(line, col), col);
|
|
174
|
+
}
|
|
175
|
+
deleteWordForward() {
|
|
176
|
+
const { line, col } = this.cur;
|
|
177
|
+
if (col >= this.lines[line].length)
|
|
178
|
+
return this.deleteForward();
|
|
179
|
+
this.snapshot("other");
|
|
180
|
+
this.deleteRange(line, col, this.wordEndAfter(line, col));
|
|
181
|
+
}
|
|
182
|
+
deleteToLineStart() {
|
|
183
|
+
const { line, col } = this.cur;
|
|
184
|
+
if (col === 0)
|
|
185
|
+
return this.backspace();
|
|
186
|
+
this.snapshot("other");
|
|
187
|
+
this.deleteRange(line, 0, col);
|
|
188
|
+
}
|
|
189
|
+
deleteToLineEnd() {
|
|
190
|
+
const { line, col } = this.cur;
|
|
191
|
+
if (col >= this.lines[line].length)
|
|
192
|
+
return this.deleteForward();
|
|
193
|
+
this.snapshot("other");
|
|
194
|
+
this.deleteRange(line, col, this.lines[line].length);
|
|
195
|
+
}
|
|
196
|
+
undo() {
|
|
197
|
+
const snap = this.undoStack.pop();
|
|
198
|
+
if (!snap)
|
|
199
|
+
return false;
|
|
200
|
+
this.lines = snap.lines;
|
|
201
|
+
this.cur = snap.cursor;
|
|
202
|
+
this.lastKind = null;
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
/** 光标所在行内、光标前的文本(补全提供者用)。 */
|
|
206
|
+
textBeforeCursor() {
|
|
207
|
+
return this.lines[this.cur.line].slice(0, this.cur.col);
|
|
208
|
+
}
|
|
209
|
+
/** 把当前行 [from, cursor) 替换为 text(补全接受)。 */
|
|
210
|
+
replaceBeforeCursor(from, text) {
|
|
211
|
+
this.snapshot("other");
|
|
212
|
+
const { line, col } = this.cur;
|
|
213
|
+
const current = this.lines[line];
|
|
214
|
+
const start = Math.max(0, Math.min(from, col));
|
|
215
|
+
this.lines[line] = current.slice(0, start) + text + current.slice(col);
|
|
216
|
+
this.cur = { line, col: start + text.length };
|
|
217
|
+
}
|
|
218
|
+
deleteRange(line, from, to) {
|
|
219
|
+
const text = this.lines[line];
|
|
220
|
+
this.lines[line] = text.slice(0, from) + text.slice(to);
|
|
221
|
+
this.cur = { line, col: from };
|
|
222
|
+
}
|
|
223
|
+
snapshot(kind) {
|
|
224
|
+
const coalesce = kind !== "other" && kind === this.lastKind;
|
|
225
|
+
this.lastKind = kind === "other" ? null : kind;
|
|
226
|
+
if (coalesce)
|
|
227
|
+
return;
|
|
228
|
+
this.undoStack.push({ lines: [...this.lines], cursor: { ...this.cur } });
|
|
229
|
+
if (this.undoStack.length > this.undoLimit)
|
|
230
|
+
this.undoStack.shift();
|
|
231
|
+
}
|
|
232
|
+
atomicAt(line, col, inclusiveEnd) {
|
|
233
|
+
return this.atomic(this.lines[line]).find(([s, e]) => inclusiveEnd ? col > s && col <= e : col >= s && col < e);
|
|
234
|
+
}
|
|
235
|
+
snapOutOfAtomic(line, col) {
|
|
236
|
+
const range = this.atomic(this.lines[line]).find(([s, e]) => col > s && col < e);
|
|
237
|
+
return range ? range[1] : col;
|
|
238
|
+
}
|
|
239
|
+
/** 光标左侧的停靠点(字素簇或整段不可分割段)。 */
|
|
240
|
+
prevStop(line, col) {
|
|
241
|
+
const range = this.atomicAt(line, col, true);
|
|
242
|
+
if (range)
|
|
243
|
+
return range[0];
|
|
244
|
+
const starts = graphemeStarts(this.lines[line]);
|
|
245
|
+
let prev = 0;
|
|
246
|
+
for (const s of starts) {
|
|
247
|
+
if (s >= col)
|
|
248
|
+
break;
|
|
249
|
+
prev = s;
|
|
250
|
+
}
|
|
251
|
+
return prev;
|
|
252
|
+
}
|
|
253
|
+
nextStop(line, col) {
|
|
254
|
+
const range = this.atomicAt(line, col, false);
|
|
255
|
+
if (range)
|
|
256
|
+
return range[1];
|
|
257
|
+
const starts = graphemeStarts(this.lines[line]);
|
|
258
|
+
return starts.find((s) => s > col) ?? this.lines[line].length;
|
|
259
|
+
}
|
|
260
|
+
classAt(line, col) {
|
|
261
|
+
if (this.atomicAt(line, col, false))
|
|
262
|
+
return "word";
|
|
263
|
+
return classify(this.lines[line][col] ?? " ");
|
|
264
|
+
}
|
|
265
|
+
wordStartBefore(line, col) {
|
|
266
|
+
let pos = col;
|
|
267
|
+
while (pos > 0 && this.classAt(line, this.prevStop(line, pos)) === "space") {
|
|
268
|
+
pos = this.prevStop(line, pos);
|
|
269
|
+
}
|
|
270
|
+
if (pos === 0)
|
|
271
|
+
return 0;
|
|
272
|
+
const first = this.prevStop(line, pos);
|
|
273
|
+
if (this.atomicAt(line, pos, true))
|
|
274
|
+
return first;
|
|
275
|
+
const cls = this.classAt(line, first);
|
|
276
|
+
pos = first;
|
|
277
|
+
while (pos > 0) {
|
|
278
|
+
const p = this.prevStop(line, pos);
|
|
279
|
+
if (this.atomicAt(line, pos, true) || this.classAt(line, p) !== cls)
|
|
280
|
+
break;
|
|
281
|
+
pos = p;
|
|
282
|
+
}
|
|
283
|
+
return pos;
|
|
284
|
+
}
|
|
285
|
+
wordEndAfter(line, col) {
|
|
286
|
+
const len = this.lines[line].length;
|
|
287
|
+
let pos = col;
|
|
288
|
+
while (pos < len && this.classAt(line, pos) === "space")
|
|
289
|
+
pos = this.nextStop(line, pos);
|
|
290
|
+
if (pos >= len)
|
|
291
|
+
return len;
|
|
292
|
+
if (this.atomicAt(line, pos, false))
|
|
293
|
+
return this.nextStop(line, pos);
|
|
294
|
+
const cls = this.classAt(line, pos);
|
|
295
|
+
while (pos < len && !this.atomicAt(line, pos, false) && this.classAt(line, pos) === cls) {
|
|
296
|
+
pos = this.nextStop(line, pos);
|
|
297
|
+
}
|
|
298
|
+
return pos;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 大粘贴折叠(设计 §12.4):超过 10 行或超过 1 000 字符的粘贴折叠为 `[paste #N +M lines]`,
|
|
3
|
+
* 在编辑器里是不可分割段;提交时展开为原文。[B4]
|
|
4
|
+
*
|
|
5
|
+
* - 换行规范化:`\r\n` / 单独的 `\r` → `\n`(括号粘贴里终端常把换行发成 `\r`)。
|
|
6
|
+
* - 未折叠的粘贴把制表符换成 4 个空格(编辑器按列宽渲染,`\t` 没有确定宽度);折叠内容保留原文。
|
|
7
|
+
* - 标记只在本编辑器记录过的编号上展开;用户手打的同形文本不会被替换成别的内容。
|
|
8
|
+
*/
|
|
9
|
+
export declare const PASTE_LINE_THRESHOLD = 10;
|
|
10
|
+
export declare const PASTE_CHAR_THRESHOLD = 1000;
|
|
11
|
+
export declare function normalizePastedText(text: string): string;
|
|
12
|
+
export declare function countLines(text: string): number;
|
|
13
|
+
/** 是否需要折叠(> 10 行或 > 1 000 字符)。 */
|
|
14
|
+
export declare function shouldCollapse(text: string): boolean;
|
|
15
|
+
export declare function formatMarker(id: number, lines: number): string;
|
|
16
|
+
export declare class PasteStore {
|
|
17
|
+
private next;
|
|
18
|
+
private readonly entries;
|
|
19
|
+
/** 处理一次粘贴:返回要插入编辑器的文本(折叠标记或规范化后的原文)。 */
|
|
20
|
+
accept(raw: string): string;
|
|
21
|
+
get size(): number;
|
|
22
|
+
get(id: number): string | undefined;
|
|
23
|
+
/** 把文本里已登记的标记展开为原文。 */
|
|
24
|
+
expand(text: string): string;
|
|
25
|
+
/** 一行内已登记标记的区间(编辑器的不可分割段)。 */
|
|
26
|
+
ranges(line: string): Array<readonly [number, number]>;
|
|
27
|
+
/** 提交后清空(编号继续递增,避免历史里的旧标记与新粘贴混淆)。 */
|
|
28
|
+
clear(): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 大粘贴折叠(设计 §12.4):超过 10 行或超过 1 000 字符的粘贴折叠为 `[paste #N +M lines]`,
|
|
3
|
+
* 在编辑器里是不可分割段;提交时展开为原文。[B4]
|
|
4
|
+
*
|
|
5
|
+
* - 换行规范化:`\r\n` / 单独的 `\r` → `\n`(括号粘贴里终端常把换行发成 `\r`)。
|
|
6
|
+
* - 未折叠的粘贴把制表符换成 4 个空格(编辑器按列宽渲染,`\t` 没有确定宽度);折叠内容保留原文。
|
|
7
|
+
* - 标记只在本编辑器记录过的编号上展开;用户手打的同形文本不会被替换成别的内容。
|
|
8
|
+
*/
|
|
9
|
+
export const PASTE_LINE_THRESHOLD = 10;
|
|
10
|
+
export const PASTE_CHAR_THRESHOLD = 1000;
|
|
11
|
+
const MARKER_RE = /\[paste #(\d+) \+(\d+) lines\]/g;
|
|
12
|
+
export function normalizePastedText(text) {
|
|
13
|
+
return text.replace(/\r\n?/g, "\n");
|
|
14
|
+
}
|
|
15
|
+
export function countLines(text) {
|
|
16
|
+
return text === "" ? 0 : text.split("\n").length;
|
|
17
|
+
}
|
|
18
|
+
/** 是否需要折叠(> 10 行或 > 1 000 字符)。 */
|
|
19
|
+
export function shouldCollapse(text) {
|
|
20
|
+
return countLines(text) > PASTE_LINE_THRESHOLD || text.length > PASTE_CHAR_THRESHOLD;
|
|
21
|
+
}
|
|
22
|
+
export function formatMarker(id, lines) {
|
|
23
|
+
return `[paste #${id} +${lines} lines]`;
|
|
24
|
+
}
|
|
25
|
+
export class PasteStore {
|
|
26
|
+
next = 1;
|
|
27
|
+
entries = new Map();
|
|
28
|
+
/** 处理一次粘贴:返回要插入编辑器的文本(折叠标记或规范化后的原文)。 */
|
|
29
|
+
accept(raw) {
|
|
30
|
+
const text = normalizePastedText(raw);
|
|
31
|
+
if (!shouldCollapse(text))
|
|
32
|
+
return text.replace(/\t/g, " ");
|
|
33
|
+
const id = this.next++;
|
|
34
|
+
this.entries.set(id, text);
|
|
35
|
+
return formatMarker(id, countLines(text));
|
|
36
|
+
}
|
|
37
|
+
get size() {
|
|
38
|
+
return this.entries.size;
|
|
39
|
+
}
|
|
40
|
+
get(id) {
|
|
41
|
+
return this.entries.get(id);
|
|
42
|
+
}
|
|
43
|
+
/** 把文本里已登记的标记展开为原文。 */
|
|
44
|
+
expand(text) {
|
|
45
|
+
if (this.entries.size === 0)
|
|
46
|
+
return text;
|
|
47
|
+
return text.replace(MARKER_RE, (marker, id) => this.entries.get(Number(id)) ?? marker);
|
|
48
|
+
}
|
|
49
|
+
/** 一行内已登记标记的区间(编辑器的不可分割段)。 */
|
|
50
|
+
ranges(line) {
|
|
51
|
+
if (this.entries.size === 0 || !line.includes("[paste #"))
|
|
52
|
+
return [];
|
|
53
|
+
const out = [];
|
|
54
|
+
for (const m of line.matchAll(MARKER_RE)) {
|
|
55
|
+
if (this.entries.has(Number(m[1])))
|
|
56
|
+
out.push([m.index, m.index + m[0].length]);
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/** 提交后清空(编号继续递增,避免历史里的旧标记与新粘贴混淆)。 */
|
|
61
|
+
clear() {
|
|
62
|
+
this.entries.clear();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 多行编辑器组件(设计 §12.3、§12.4)。[B4]
|
|
3
|
+
*
|
|
4
|
+
* - 渲染:上下边框之间按列宽折行(不切开字素与折叠标记);超过 `maxVisibleLines` 时视窗跟随光标,
|
|
5
|
+
* 边框上提示上 / 下方隐藏的行数;获焦时在光标处输出 CURSOR_MARKER 并反显光标格。
|
|
6
|
+
* - 键位:`tui.editor.*`(见 keybindings.ts)。Enter 提交(`disableSubmit` 时忽略);Shift+Enter / Ctrl+J 换行;
|
|
7
|
+
* Up/Down 在首 / 末视觉行时浏览历史(单行文本或空文本或已在浏览中),否则按视觉行移动。
|
|
8
|
+
* - 括号粘贴(`ESC[200~…ESC[201~`,由 StdinBuffer 合成一次输入):> 10 行或 > 1 000 字符折叠为
|
|
9
|
+
* `[paste #N +M lines]`,提交时展开;粘贴期间不触发补全;粘贴后紧随的 `\r` 是普通 Enter(提交)。
|
|
10
|
+
* - 补全:提供者由外部注入(`/` 命令、`@` 文件等由 B7 实现);同步或异步返回候选与替换起点。
|
|
11
|
+
* - 历史:会话内 + 可选历史文件(JSONL,每行一个 JSON 字符串,保留最近 500 条)。
|
|
12
|
+
*/
|
|
13
|
+
import { type Component, type Focusable, type Theme } from "../component.js";
|
|
14
|
+
import { type Keybindings } from "../keybindings.js";
|
|
15
|
+
export interface AutocompleteItem {
|
|
16
|
+
/** 接受后替换进编辑器的文本。 */
|
|
17
|
+
value: string;
|
|
18
|
+
label: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface AutocompleteResult {
|
|
22
|
+
items: AutocompleteItem[];
|
|
23
|
+
/** 当前行内被替换区间的起点(UTF-16 列);终点是光标。 */
|
|
24
|
+
from: number;
|
|
25
|
+
}
|
|
26
|
+
export interface AutocompleteContext {
|
|
27
|
+
/** 当前行全文。 */
|
|
28
|
+
line: string;
|
|
29
|
+
/** 当前行光标前的文本。 */
|
|
30
|
+
textBeforeCursor: string;
|
|
31
|
+
/** 编辑器全文(折叠标记未展开)。 */
|
|
32
|
+
text: string;
|
|
33
|
+
/** Tab 主动请求时为 true;输入触发时为 false。 */
|
|
34
|
+
force: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface AutocompleteProvider {
|
|
37
|
+
getSuggestions(context: AutocompleteContext): AutocompleteResult | null | Promise<AutocompleteResult | null>;
|
|
38
|
+
}
|
|
39
|
+
export interface EditorOptions {
|
|
40
|
+
theme?: Theme;
|
|
41
|
+
keybindings?: Keybindings;
|
|
42
|
+
/** 可见文本行上限,缺省 10。 */
|
|
43
|
+
maxVisibleLines?: number;
|
|
44
|
+
/** 历史条数上限,缺省 500。 */
|
|
45
|
+
historyLimit?: number;
|
|
46
|
+
/** 历史文件路径(JSONL);缺省只保留会话内历史。 */
|
|
47
|
+
historyFile?: string;
|
|
48
|
+
autocomplete?: AutocompleteProvider;
|
|
49
|
+
/** 异步补全返回后请求重绘。 */
|
|
50
|
+
requestRender?: () => void;
|
|
51
|
+
placeholder?: string;
|
|
52
|
+
onSubmit?(text: string): void;
|
|
53
|
+
onChange?(text: string): void;
|
|
54
|
+
}
|
|
55
|
+
export declare function loadHistoryFile(path: string, limit?: number): string[];
|
|
56
|
+
export declare class Editor implements Component, Focusable {
|
|
57
|
+
private readonly options;
|
|
58
|
+
focused: boolean;
|
|
59
|
+
/** 审批对话框期间置 true:Enter 不提交。 */
|
|
60
|
+
disableSubmit: boolean;
|
|
61
|
+
private readonly buffer;
|
|
62
|
+
private readonly pastes;
|
|
63
|
+
private readonly keys;
|
|
64
|
+
private readonly theme;
|
|
65
|
+
private history;
|
|
66
|
+
private historyIndex;
|
|
67
|
+
private draft;
|
|
68
|
+
private lastWidth;
|
|
69
|
+
private scrollTop;
|
|
70
|
+
private preferredCol;
|
|
71
|
+
private completion;
|
|
72
|
+
private completionToken;
|
|
73
|
+
constructor(options?: EditorOptions);
|
|
74
|
+
private get historyLimit();
|
|
75
|
+
/** 编辑器原文(折叠标记未展开)。 */
|
|
76
|
+
getText(): string;
|
|
77
|
+
/** 展开折叠标记后的文本(即提交内容)。 */
|
|
78
|
+
getExpandedText(): string;
|
|
79
|
+
setText(text: string): void;
|
|
80
|
+
insertText(text: string): void;
|
|
81
|
+
clear(): void;
|
|
82
|
+
isEmpty(): boolean;
|
|
83
|
+
get cursor(): {
|
|
84
|
+
line: number;
|
|
85
|
+
col: number;
|
|
86
|
+
};
|
|
87
|
+
get isCompletionOpen(): boolean;
|
|
88
|
+
getHistory(): readonly string[];
|
|
89
|
+
setHistory(entries: readonly string[]): void;
|
|
90
|
+
addToHistory(text: string): void;
|
|
91
|
+
/** 取出提交内容(展开、记历史、清空),不调用 onSubmit;空文本返回 null。供 followUp 等使用。 */
|
|
92
|
+
takeSubmission(): string | null;
|
|
93
|
+
submit(): void;
|
|
94
|
+
handleInput(data: string): void;
|
|
95
|
+
private handleCompletionKey;
|
|
96
|
+
private handleAction;
|
|
97
|
+
private afterEdit;
|
|
98
|
+
private verticalMove;
|
|
99
|
+
private historyStep;
|
|
100
|
+
private colAtWidth;
|
|
101
|
+
private prevGrapheme;
|
|
102
|
+
private requestCompletion;
|
|
103
|
+
private applyCompletion;
|
|
104
|
+
private acceptCompletion;
|
|
105
|
+
private closeCompletion;
|
|
106
|
+
private contentWidth;
|
|
107
|
+
/** 逻辑行 → 视觉行(按列宽折行,不切开字素与折叠标记)。 */
|
|
108
|
+
private layout;
|
|
109
|
+
private cursorRowIndex;
|
|
110
|
+
private renderRow;
|
|
111
|
+
render(width: number): string[];
|
|
112
|
+
private border;
|
|
113
|
+
invalidate(): void;
|
|
114
|
+
}
|