Terminal rework

This commit is contained in:
crschnick
2025-03-26 19:51:05 +00:00
parent f7df1b9d56
commit 71e6050a71
5 changed files with 67 additions and 7 deletions
@@ -217,7 +217,7 @@ public class TerminalCategory extends AppPrefsCategory {
});
websiteLinkButton.minWidth(Region.USE_PREF_SIZE);
websiteLinkButton.disable(Bindings.createBooleanBinding(() -> {
return prefs.terminalMultiplexer.getValue().getDocsLink() == null;
return prefs.terminalMultiplexer.getValue() == null || prefs.terminalMultiplexer.getValue().getDocsLink() == null;
}, prefs.terminalMultiplexer));
var hbox = new HBox(entryComboBox, websiteLinkButton.createRegion());
@@ -14,6 +14,7 @@ public interface TerminalMultiplexer {
static List<Class<?>> getClasses() {
var l = new ArrayList<Class<?>>();
l.add(TmuxTerminalMultiplexer.class);
l.add(ZellijTerminalMultiplexer.class);
return l;
}
@@ -0,0 +1,47 @@
package io.xpipe.app.terminal;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.process.ShellScript;
import io.xpipe.core.process.TerminalInitScriptConfig;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import lombok.extern.jackson.Jacksonized;
@Builder
@Jacksonized
@JsonTypeName("tmux")
public class TmuxTerminalMultiplexer implements TerminalMultiplexer {
@Override
public String getDocsLink() {
return "https://github.com/tmux/tmux/wiki/Getting-Started";
}
@Override
public ShellScript launchScriptExternal(ShellControl control, String command, TerminalInitScriptConfig config) throws Exception {
return ShellScript.lines(
"tmux new-window -t xpipe -n \"" + escape(config.getDisplayName(), true) + "\" " + escape(command , false)
);
}
@Override
public ShellScript launchScriptSession(ShellControl control, String command, TerminalInitScriptConfig config) throws Exception {
return ShellScript.lines(
"tmux kill-session -t xpipe",
"tmux new-session -d -s xpipe",
"tmux rename-window \"" + escape(config.getDisplayName(), true) + "\"",
"tmux send-keys -t xpipe '" + escape(command, false) + "' Enter",
"tmux attach -d -t xpipe"
);
}
private String escape(String s, boolean quotes) {
var r = s.replaceAll("\\\\", "\\\\\\\\");
if (quotes) {
r = r.replaceAll("\"", "\\\\\"");
}
return r;
}
}
@@ -22,9 +22,7 @@ import lombok.Getter;
import lombok.ToString;
import lombok.extern.jackson.Jacksonized;
@Getter
@Builder(toBuilder = true)
@ToString
@Builder
@Jacksonized
@JsonTypeName("zellij")
public class ZellijTerminalMultiplexer implements TerminalMultiplexer {
@@ -3,6 +3,7 @@ package io.xpipe.app.util;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.xpipe.app.comp.base.ChoicePaneComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.terminal.ZellijTerminalMultiplexer;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
@@ -29,12 +30,25 @@ public class OptionsChoiceBuilder {
return null;
}
private static OptionsBuilder createOptionsForClass(Class<?> c, Property<?> property) {
private static OptionsBuilder createOptionsForClass(Class<?> c, Property<Object> property) {
try {
var method = c.getDeclaredMethod("createOptions", Property.class);
method.setAccessible(true);
var r = method.invoke(null, property);
return r != null ? (OptionsBuilder) r : new OptionsBuilder();
if (r != null) {
return (OptionsBuilder) r;
}
} catch (Exception ignored) {}
try {
var bm = c.getDeclaredMethod("builder");
bm.setAccessible(true);
var b = bm.invoke(null);
var m = b.getClass().getDeclaredMethod("build");
m.setAccessible(true);
var defValue = c.cast(m.invoke(b));
var def = new OptionsBuilder().bind(() -> defValue, property);
return def;
} catch (Exception e) {
return new OptionsBuilder();
}
@@ -80,7 +94,7 @@ public class OptionsChoiceBuilder {
map.put(AppI18n.observable("none"), new OptionsBuilder());
}
for (int i = 0; i < sub.size(); i++) {
map.put(AppI18n.observable(createIdForClass(sub.get(i))), createOptionsForClass(sub.get(i), properties.get(i)));
map.put(AppI18n.observable(createIdForClass(sub.get(i))), createOptionsForClass(sub.get(i), properties.get(i + (allowNull ? 1 : 0))));
}
return new OptionsBuilder()