From 5f221939e3af74ad43306da80572338be93d9b7a Mon Sep 17 00:00:00 2001 From: Leon Mika Date: Sat, 9 May 2026 12:22:25 +0000 Subject: [PATCH] Add Cmd+L to rerun last command on current line(s) Co-authored-by: Shelley --- frontend/index.html | 2 +- frontend/src/cmplugins.js | 8 +++++++ .../src/controllers/commands_controller.js | 13 +++++++++++- frontend/src/services.js | 21 ++++++++++++++++--- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 43a2da8..708247a 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -20,7 +20,7 @@ + data-action="dq-showcommands@window->commands#showCommands dq-rerunlastcommand@window->commands#rerunLastCommand dq-rerunlastcommand-line@window->commands#rerunLastCommandOnLine">
{ + let event = new CustomEvent('dq-rerunlastcommand-line'); + window.dispatchEvent(event); + + return true; + } +}, { key: "Cmd-k", run: (view) => { const {state} = view; diff --git a/frontend/src/controllers/commands_controller.js b/frontend/src/controllers/commands_controller.js index 6bdc0b6..ec69f24 100644 --- a/frontend/src/controllers/commands_controller.js +++ b/frontend/src/controllers/commands_controller.js @@ -10,6 +10,10 @@ export class CommandsController extends Controller { "commandSelect", ]; + initialize() { + this._lineModeOnce = false; + } + async connect() { this._lastCommand = null; @@ -62,7 +66,14 @@ export class CommandsController extends Controller { } this._promptController()?.useLastValueForNextPrompt(); - textProcessor.runTextCommand(this._lastCommand); + const lineMode = this._lineModeOnce; + this._lineModeOnce = false; + textProcessor.runTextCommand(this._lastCommand, { lineMode }); + } + + rerunLastCommandOnLine(ev) { + this._lineModeOnce = true; + this.rerunLastCommand(ev); } _promptController() { diff --git a/frontend/src/services.js b/frontend/src/services.js index 88da2e0..2d65b6d 100644 --- a/frontend/src/services.js +++ b/frontend/src/services.js @@ -46,16 +46,31 @@ class TextProcessor { }); } - async runTextCommand(command) { + async runTextCommand(command, opts) { if (this._editor === undefined) { return; } + const lineMode = opts && opts.lineMode; let ranges = this._editor.state.selection.ranges; - let shouldBeAll = ranges.reduce((a, r) => a && r.from === r.to, true); + let hasSelection = ranges.some(r => r.from !== r.to); let inputs = []; - if (shouldBeAll) { + if (lineMode && !hasSelection) { + this._appendInsertPos = undefined; + const doc = this._editor.state.doc; + const seen = new Set(); + for (let r of ranges) { + const line = doc.lineAt(r.head); + if (seen.has(line.number)) continue; + seen.add(line.number); + inputs.push({ + text: line.text, + pos: line.from, + len: line.to - line.from, + }); + } + } else if (!hasSelection) { this._appendInsertPos = this._editor.state.selection.main.head; inputs.push({ text: this._editor.state.doc.toString(),