scrollback editor shortcut
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -53,6 +53,9 @@ height = 760
|
|||||||
[kitty_graphics]
|
[kitty_graphics]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
|
[scrollback]
|
||||||
|
editor_command = "vi {file}"
|
||||||
|
|
||||||
[keybindings]
|
[keybindings]
|
||||||
navigate_left = "ALT+H"
|
navigate_left = "ALT+H"
|
||||||
navigate_down = "ALT+J"
|
navigate_down = "ALT+J"
|
||||||
@@ -63,6 +66,7 @@ new_floating = "ALT+SHIFT+F"
|
|||||||
next_floating = "ALT+F12"
|
next_floating = "ALT+F12"
|
||||||
close_pane = "ALT+X"
|
close_pane = "ALT+X"
|
||||||
open_font_selector = "ALT+T"
|
open_font_selector = "ALT+T"
|
||||||
|
open_scrollback = "ALT+S"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Defaults
|
## Defaults
|
||||||
@@ -73,5 +77,6 @@ open_font_selector = "ALT+T"
|
|||||||
- `Alt+F12`: cycle floating panes
|
- `Alt+F12`: cycle floating panes
|
||||||
- `Alt+x`: close the active floating pane
|
- `Alt+x`: close the active floating pane
|
||||||
- `Alt+t`: open the font selector
|
- `Alt+t`: open the font selector
|
||||||
|
- `Alt+s`: open the active pane scrollback in `$EDITOR`
|
||||||
- Font default: `JetBrainsMono Nerd Font`
|
- Font default: `JetBrainsMono Nerd Font`
|
||||||
- Kitty graphics protocol parsing is enabled by default
|
- Kitty graphics protocol parsing is enabled by default
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ height = 760
|
|||||||
[kitty_graphics]
|
[kitty_graphics]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
|
[scrollback]
|
||||||
|
editor_command = "vi {file}"
|
||||||
|
|
||||||
[keybindings]
|
[keybindings]
|
||||||
navigate_left = "ALT+H"
|
navigate_left = "ALT+H"
|
||||||
navigate_down = "ALT+J"
|
navigate_down = "ALT+J"
|
||||||
@@ -23,3 +26,4 @@ new_floating = "ALT+SHIFT+F"
|
|||||||
next_floating = "ALT+F12"
|
next_floating = "ALT+F12"
|
||||||
close_pane = "ALT+X"
|
close_pane = "ALT+X"
|
||||||
open_font_selector = "ALT+T"
|
open_font_selector = "ALT+T"
|
||||||
|
open_scrollback = "ALT+S"
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public record AppConfig(
|
|||||||
double windowWidth,
|
double windowWidth,
|
||||||
double windowHeight,
|
double windowHeight,
|
||||||
boolean kittyGraphics,
|
boolean kittyGraphics,
|
||||||
|
String scrollbackEditorCommand,
|
||||||
Map<String, KeyBinding> keybindings
|
Map<String, KeyBinding> keybindings
|
||||||
) {
|
) {
|
||||||
private static final List<String> KEYBINDING_KEYS = List.of(
|
private static final List<String> KEYBINDING_KEYS = List.of(
|
||||||
@@ -36,7 +37,8 @@ public record AppConfig(
|
|||||||
"new_floating",
|
"new_floating",
|
||||||
"next_floating",
|
"next_floating",
|
||||||
"close_pane",
|
"close_pane",
|
||||||
"open_font_selector"
|
"open_font_selector",
|
||||||
|
"open_scrollback"
|
||||||
);
|
);
|
||||||
|
|
||||||
public static AppConfig load() {
|
public static AppConfig load() {
|
||||||
@@ -59,6 +61,7 @@ public record AppConfig(
|
|||||||
doubleValue(document, "window.width", defaults.windowWidth),
|
doubleValue(document, "window.width", defaults.windowWidth),
|
||||||
doubleValue(document, "window.height", defaults.windowHeight),
|
doubleValue(document, "window.height", defaults.windowHeight),
|
||||||
booleanValue(document, "kitty_graphics.enabled", defaults.kittyGraphics),
|
booleanValue(document, "kitty_graphics.enabled", defaults.kittyGraphics),
|
||||||
|
stringValue(document, "scrollback.editor_command", defaults.scrollbackEditorCommand),
|
||||||
keybindings(document, defaults)
|
keybindings(document, defaults)
|
||||||
);
|
);
|
||||||
} catch (TomlException ex) {
|
} catch (TomlException ex) {
|
||||||
@@ -78,6 +81,7 @@ public record AppConfig(
|
|||||||
1200.0,
|
1200.0,
|
||||||
760.0,
|
760.0,
|
||||||
true,
|
true,
|
||||||
|
defaultScrollbackEditorCommand(),
|
||||||
Map.of(
|
Map.of(
|
||||||
"navigate_left", KeyBinding.parse("ALT+H"),
|
"navigate_left", KeyBinding.parse("ALT+H"),
|
||||||
"navigate_down", KeyBinding.parse("ALT+J"),
|
"navigate_down", KeyBinding.parse("ALT+J"),
|
||||||
@@ -87,7 +91,8 @@ public record AppConfig(
|
|||||||
"new_floating", KeyBinding.parse("ALT+SHIFT+F"),
|
"new_floating", KeyBinding.parse("ALT+SHIFT+F"),
|
||||||
"next_floating", KeyBinding.parse("ALT+F12"),
|
"next_floating", KeyBinding.parse("ALT+F12"),
|
||||||
"close_pane", KeyBinding.parse("ALT+X"),
|
"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,
|
windowWidth,
|
||||||
windowHeight,
|
windowHeight,
|
||||||
kittyGraphics,
|
kittyGraphics,
|
||||||
|
scrollbackEditorCommand,
|
||||||
keybindings
|
keybindings
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -123,6 +129,14 @@ public record AppConfig(
|
|||||||
return "/bin/bash";
|
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) {
|
private static Map<String, KeyBinding> keybindings(TomlTable table, AppConfig defaults) {
|
||||||
Map<String, KeyBinding> parsed = new LinkedHashMap<>();
|
Map<String, KeyBinding> parsed = new LinkedHashMap<>();
|
||||||
for (String key : KEYBINDING_KEYS) {
|
for (String key : KEYBINDING_KEYS) {
|
||||||
@@ -167,6 +181,8 @@ public record AppConfig(
|
|||||||
builder.append("height = ").append(trimDouble(windowHeight)).append("\n\n");
|
builder.append("height = ").append(trimDouble(windowHeight)).append("\n\n");
|
||||||
builder.append("[kitty_graphics]\n");
|
builder.append("[kitty_graphics]\n");
|
||||||
builder.append("enabled = ").append(kittyGraphics).append("\n\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");
|
builder.append("[keybindings]\n");
|
||||||
for (String key : KEYBINDING_KEYS) {
|
for (String key : KEYBINDING_KEYS) {
|
||||||
KeyBinding binding = keybindings.get(key);
|
KeyBinding binding = keybindings.get(key);
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public final class Main extends Application {
|
public final class Main extends Application {
|
||||||
private TerminalWorkspace workspace;
|
private TerminalWorkspace workspace;
|
||||||
private TerminalCanvasView terminalView;
|
private TerminalCanvasView terminalView;
|
||||||
@@ -79,6 +83,9 @@ public final class Main extends Application {
|
|||||||
} else if (config.keybindings().get("open_font_selector").matches(event)) {
|
} else if (config.keybindings().get("open_font_selector").matches(event)) {
|
||||||
openFontSelector();
|
openFontSelector();
|
||||||
event.consume();
|
event.consume();
|
||||||
|
} else if (config.keybindings().get("open_scrollback").matches(event)) {
|
||||||
|
openScrollbackInEditor();
|
||||||
|
event.consume();
|
||||||
} else {
|
} else {
|
||||||
String encoded = KeyEncoder.encode(event);
|
String encoded = KeyEncoder.encode(event);
|
||||||
if (encoded != null) {
|
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) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("prism.order", System.getProperty("prism.order", "es2,sw"));
|
System.setProperty("prism.order", System.getProperty("prism.order", "es2,sw"));
|
||||||
launch(Main.class, args);
|
launch(Main.class, args);
|
||||||
|
|||||||
@@ -115,6 +115,12 @@ public final class TerminalPane implements AutoCloseable {
|
|||||||
return renderSnapshot.get();
|
return renderSnapshot.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String scrollbackText() {
|
||||||
|
synchronized (terminal) {
|
||||||
|
return terminal.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long renderVersion() {
|
public long renderVersion() {
|
||||||
return renderVersion;
|
return renderVersion;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user