{
+ 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 5d74380..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;
@@ -47,6 +51,7 @@ export class CommandsController extends Controller {
runCommand(ev) {
ev.preventDefault();
+ this._promptController()?.clearUseLastValue();
textProcessor.runTextCommand(this.commandSelectTarget.value);
this._lastCommand = this.commandSelectTarget.value;
@@ -60,7 +65,21 @@ export class CommandsController extends Controller {
return;
}
- textProcessor.runTextCommand(this._lastCommand);
+ this._promptController()?.useLastValueForNextPrompt();
+ const lineMode = this._lineModeOnce;
+ this._lineModeOnce = false;
+ textProcessor.runTextCommand(this._lastCommand, { lineMode });
+ }
+
+ rerunLastCommandOnLine(ev) {
+ this._lineModeOnce = true;
+ this.rerunLastCommand(ev);
+ }
+
+ _promptController() {
+ const el = document.getElementById("prompt-dialog");
+ if (!el) return null;
+ return this.application.getControllerForElementAndIdentifier(el, "prompt");
}
_filterOptions(filterText) {
diff --git a/frontend/src/controllers/prompt_controller.js b/frontend/src/controllers/prompt_controller.js
index c8ff4e3..fe10ee0 100644
--- a/frontend/src/controllers/prompt_controller.js
+++ b/frontend/src/controllers/prompt_controller.js
@@ -8,8 +8,16 @@ export class PromptController extends Controller {
connect() {
this._callback = null;
+ this._lastValue = null;
+ this._useLastNext = false;
window.runtime.EventsOn("prompt-request", (data) => {
+ if (this._useLastNext && this._lastValue !== null) {
+ this._useLastNext = false;
+ window.runtime.EventsEmit("prompt-response", this._lastValue);
+ return;
+ }
+ this._useLastNext = false;
this.prompt(data.label, (res) => {
window.runtime.EventsEmit("prompt-response", res);
});
@@ -19,14 +27,16 @@ export class PromptController extends Controller {
prompt(label, callback) {
this._callback = callback;
this.labelTarget.textContent = label;
- this.inputTarget.value = "";
+ this.inputTarget.value = this._lastValue || "";
this.element.showModal();
+ this.inputTarget.select();
this.inputTarget.focus();
}
submit(ev) {
ev.preventDefault();
let value = this.inputTarget.value;
+ this._lastValue = value;
this.element.close();
if (this._callback) {
this._callback(value);
@@ -39,4 +49,12 @@ export class PromptController extends Controller {
this._callback = null;
this.element.close();
}
+
+ useLastValueForNextPrompt() {
+ this._useLastNext = true;
+ }
+
+ clearUseLastValue() {
+ this._useLastNext = false;
+ }
}
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(),