Add Cmd+L to rerun last command on current line(s)

Co-authored-by: Shelley <shelley@exe.dev>
This commit is contained in:
Leon Mika 2026-05-09 12:22:25 +00:00
parent 7c9023ae20
commit 5f221939e3
4 changed files with 39 additions and 5 deletions

View file

@ -20,7 +20,7 @@
</div> </div>
</dialog> </dialog>
<dialog id="command-dialog" data-controller="commands" <dialog id="command-dialog" data-controller="commands"
data-action="dq-showcommands@window->commands#showCommands dq-rerunlastcommand@window->commands#rerunLastCommand"> data-action="dq-showcommands@window->commands#showCommands dq-rerunlastcommand@window->commands#rerunLastCommand dq-rerunlastcommand-line@window->commands#rerunLastCommandOnLine">
<div class="dialog-body"> <div class="dialog-body">
<div class="command-input"> <div class="command-input">
<input data-commands-target="commandInput" type="text" placeholder="Enter command" <input data-commands-target="commandInput" type="text" placeholder="Enter command"

View file

@ -46,6 +46,14 @@ export const commandPalette = keymap.of([{
return true; return true;
} }
}, { }, {
key: "Cmd-l",
run: () => {
let event = new CustomEvent('dq-rerunlastcommand-line');
window.dispatchEvent(event);
return true;
}
}, {
key: "Cmd-k", key: "Cmd-k",
run: (view) => { run: (view) => {
const {state} = view; const {state} = view;

View file

@ -10,6 +10,10 @@ export class CommandsController extends Controller {
"commandSelect", "commandSelect",
]; ];
initialize() {
this._lineModeOnce = false;
}
async connect() { async connect() {
this._lastCommand = null; this._lastCommand = null;
@ -62,7 +66,14 @@ export class CommandsController extends Controller {
} }
this._promptController()?.useLastValueForNextPrompt(); 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() { _promptController() {

View file

@ -46,16 +46,31 @@ class TextProcessor {
}); });
} }
async runTextCommand(command) { async runTextCommand(command, opts) {
if (this._editor === undefined) { if (this._editor === undefined) {
return; return;
} }
const lineMode = opts && opts.lineMode;
let ranges = this._editor.state.selection.ranges; 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 = []; 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; this._appendInsertPos = this._editor.state.selection.main.head;
inputs.push({ inputs.push({
text: this._editor.state.doc.toString(), text: this._editor.state.doc.toString(),