scrollback editor shortcut

This commit is contained in:
Gregor Lohaus
2026-05-28 13:53:44 +02:00
parent 7dfff664fc
commit 80cd318c1c
12 changed files with 68 additions and 2 deletions

View File

@@ -25,6 +25,7 @@ public record AppConfig(
double windowWidth,
double windowHeight,
boolean kittyGraphics,
String scrollbackEditorCommand,
Map<String, KeyBinding> keybindings
) {
private static final List<String> KEYBINDING_KEYS = List.of(
@@ -36,7 +37,8 @@ public record AppConfig(
"new_floating",
"next_floating",
"close_pane",
"open_font_selector"
"open_font_selector",
"open_scrollback"
);
public static AppConfig load() {
@@ -59,6 +61,7 @@ public record AppConfig(
doubleValue(document, "window.width", defaults.windowWidth),
doubleValue(document, "window.height", defaults.windowHeight),
booleanValue(document, "kitty_graphics.enabled", defaults.kittyGraphics),
stringValue(document, "scrollback.editor_command", defaults.scrollbackEditorCommand),
keybindings(document, defaults)
);
} catch (TomlException ex) {
@@ -78,6 +81,7 @@ public record AppConfig(
1200.0,
760.0,
true,
defaultScrollbackEditorCommand(),
Map.of(
"navigate_left", KeyBinding.parse("ALT+H"),
"navigate_down", KeyBinding.parse("ALT+J"),
@@ -87,7 +91,8 @@ public record AppConfig(
"new_floating", KeyBinding.parse("ALT+SHIFT+F"),
"next_floating", KeyBinding.parse("ALT+F12"),
"close_pane", KeyBinding.parse("ALT+X"),
"open_font_selector", KeyBinding.parse("ALT+T")
"open_font_selector", KeyBinding.parse("ALT+T"),
"open_scrollback", KeyBinding.parse("ALT+S")
)
);
}
@@ -103,6 +108,7 @@ public record AppConfig(
windowWidth,
windowHeight,
kittyGraphics,
scrollbackEditorCommand,
keybindings
);
}
@@ -123,6 +129,14 @@ public record AppConfig(
return "/bin/bash";
}
private static String defaultScrollbackEditorCommand() {
String editor = System.getenv("EDITOR");
if (editor == null || editor.isBlank()) {
editor = "vi";
}
return editor.trim() + " {file}";
}
private static Map<String, KeyBinding> keybindings(TomlTable table, AppConfig defaults) {
Map<String, KeyBinding> parsed = new LinkedHashMap<>();
for (String key : KEYBINDING_KEYS) {
@@ -167,6 +181,8 @@ public record AppConfig(
builder.append("height = ").append(trimDouble(windowHeight)).append("\n\n");
builder.append("[kitty_graphics]\n");
builder.append("enabled = ").append(kittyGraphics).append("\n\n");
builder.append("[scrollback]\n");
builder.append("editor_command = ").append(quoted(scrollbackEditorCommand)).append("\n\n");
builder.append("[keybindings]\n");
for (String key : KEYBINDING_KEYS) {
KeyBinding binding = keybindings.get(key);

View File

@@ -15,6 +15,10 @@ import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public final class Main extends Application {
private TerminalWorkspace workspace;
private TerminalCanvasView terminalView;
@@ -79,6 +83,9 @@ public final class Main extends Application {
} else if (config.keybindings().get("open_font_selector").matches(event)) {
openFontSelector();
event.consume();
} else if (config.keybindings().get("open_scrollback").matches(event)) {
openScrollbackInEditor();
event.consume();
} else {
String encoded = KeyEncoder.encode(event);
if (encoded != null) {
@@ -143,6 +150,34 @@ public final class Main extends Application {
});
}
private void openScrollbackInEditor() {
try {
Path file = Files.createTempFile("jprototerm-scrollback-", ".txt");
Files.writeString(file, workspace.activePane().scrollbackText());
file.toFile().deleteOnExit();
workspace.activePane().send(scrollbackEditorCommand(file) + "\r");
} catch (IOException ex) {
System.err.println("Could not open scrollback in editor: " + ex.getMessage());
}
}
private String scrollbackEditorCommand(Path file) {
String quotedFile = shellQuote(file.toString());
String command = config.scrollbackEditorCommand();
if (command == null || command.isBlank()) {
command = "vi {file}";
}
if (command.contains("{file}")) {
return command.replace("{file}", quotedFile);
}
return command + " " + quotedFile;
}
private static String shellQuote(String value) {
return "'" + value.replace("'", "'\"'\"'") + "'";
}
public static void main(String[] args) {
System.setProperty("prism.order", System.getProperty("prism.order", "es2,sw"));
launch(Main.class, args);

View File

@@ -115,6 +115,12 @@ public final class TerminalPane implements AutoCloseable {
return renderSnapshot.get();
}
public String scrollbackText() {
synchronized (terminal) {
return terminal.text();
}
}
public long renderVersion() {
return renderVersion;
}