phase 14: list/heading edit commands + CommandOutcome split
Six new executeCommand entries — the cheap surgical edits that account for the bulk of vimwiki users' daily keymap traffic. Heavier commands (table.align/moveColumn/insert, list.changeSymbol/changeLevel/renumber/ removeDone, link.normalize, colorize) are deferred for a follow-up since each needs its own structural rewriter. CommandOutcome split: - `Edit(WorkspaceEdit)` — server applies via apply_edit. - `Value(Value)` — returned verbatim to the client (used by read-only queries like nextTask). - execute_command handler in lib.rs dispatches both cases. New commands: - nuwiki.list.toggleCheckbox — [ ] ↔ [X]; mid-states snap to [X]; rejected reverts to [ ]. - nuwiki.list.cycleCheckbox — [ ] → [.] → [o] → [O] → [X] → [ ]; rejected resets to [ ]. - nuwiki.list.rejectCheckbox — toggle the [-] rejected marker. - nuwiki.list.nextTask — returns Location of the first unfinished task after the cursor; wraps to the start of the doc when none found below. Only items with checkboxes count. - nuwiki.heading.addLevel — = → ==; clamps at 6. - nuwiki.heading.removeLevel — == → =; clamps at 1 (no-op on h1). Pure ops: - ops::toggle_state / cycle_state / reject_state — checkbox state transitions. - ops::checkbox_edit / next_task / heading_change_level — end-to-end edit producers. Tests drive these directly without spinning up a Backend. - ops::rewrite_heading_with_level — text-level rewrite preserving the leading whitespace that marks a centered heading (lives outside the heading span, so the edit doesn't touch it). - ops::find_list_item_at / find_checkbox_span / item_in_list — AST + source-text helpers, pub for downstream tooling. Tests (21 new): - State transitions: round-trip, progression, dash toggle. - checkbox_edit: empty → done, partial → cycle, reject path, no-op on plain item, no-op off list, nested-sublist resolution. - heading_change_level: h2→h3, level-6 cap, h3→h2, h1 no-op, off-heading no-op, span boundary semantics. - next_task: first-unfinished, wrap-around, all-done returns None, plain items ignored. - COMMANDS list ↔ handler match. All 211 prior tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -639,7 +639,7 @@ impl LanguageServer for Backend {
|
||||
params: ExecuteCommandParams,
|
||||
) -> LspResult<Option<serde_json::Value>> {
|
||||
match commands::execute(self, ¶ms.command, params.arguments).await {
|
||||
Ok(Some(edit)) => {
|
||||
Ok(Some(commands::CommandOutcome::Edit(edit))) => {
|
||||
if let Err(e) = self.client.apply_edit(edit).await {
|
||||
self.client
|
||||
.log_message(
|
||||
@@ -650,6 +650,7 @@ impl LanguageServer for Backend {
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
Ok(Some(commands::CommandOutcome::Value(v))) => Ok(Some(v)),
|
||||
Ok(None) => Ok(None),
|
||||
Err(msg) => {
|
||||
self.client
|
||||
|
||||
Reference in New Issue
Block a user