Rework prompts

This commit is contained in:
crschnick
2025-04-02 09:37:15 +00:00
parent a5027fa6a7
commit 312368ed7d
15 changed files with 386 additions and 75 deletions
@@ -53,7 +53,7 @@ public class MarkdownComp extends Comp<CompStructure<StackPane>> {
private Path getHtmlFile(String markdown) {
if (TEMP == null) {
TEMP = ShellTemp.getLocalTempDataDirectory("wv");
TEMP = ShellTemp.getLocalTempDataDirectory("webview");
}
if (markdown == null) {
@@ -0,0 +1,57 @@
package io.xpipe.app.terminal;
import io.xpipe.app.util.GithubReleaseDownloader;
import io.xpipe.app.util.HttpHelper;
import io.xpipe.app.util.ShellTemp;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.store.FilePath;
import io.xpipe.core.util.JacksonMapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
public class ClinkHelper {
private static String downloadUrl = null;
private static Path downloadFile = null;
public static FilePath getTargetDir(ShellControl sc) throws Exception {
var targetDir = ShellTemp.createUserSpecificTempDataDirectory(sc, null).join("bin", "clink");
return targetDir;
}
public static boolean checkIfInstalled(ShellControl sc) throws Exception {
if (sc.view().findProgram("clink").isPresent()) {
return true;
}
var targetDir = getTargetDir(sc);
return sc.view().fileExists(targetDir.join("clink_x64.exe"));
}
public static void install(ShellControl sc) throws Exception {
var targetDir = getTargetDir(sc);
sc.view().mkdir(targetDir);
var temp = GithubReleaseDownloader.getDownloadTempFile("chrisant996/clink", "clink.zip", name -> name.endsWith(".zip") && !name.endsWith("symbols.zip"));
try (var fs = FileSystems.newFileSystem(temp)) {
var exeFile = fs.getPath("clink_x64.exe");
var exeBytes = Files.readAllBytes(exeFile);
sc.view().writeStreamFile(targetDir.join("clink_x64.exe"), new ByteArrayInputStream(exeBytes), exeBytes.length);
var batFile = fs.getPath("clink.bat");
var batBytes = Files.readAllBytes(batFile);
sc.view().writeStreamFile(targetDir.join("clink.bat"), new ByteArrayInputStream(batBytes), batBytes.length);
var dllFile = fs.getPath("clink_dll_x64.dll");
var dllBytes = Files.readAllBytes(dllFile);
sc.view().writeStreamFile(targetDir.join("clink_dll_x64.dll"), new ByteArrayInputStream(dllBytes), dllBytes.length);
}
}
}
@@ -1,13 +1,10 @@
package io.xpipe.app.terminal;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.password.KeePassXcAssociationKey;
import io.xpipe.app.password.KeePassXcManager;
import io.xpipe.app.util.OptionsBuilder;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.process.ShellDialect;
import io.xpipe.core.process.ShellScript;
import io.xpipe.core.process.ShellTerminalInitCommand;
import io.xpipe.core.store.FilePath;
import javafx.beans.property.Property;
@@ -15,6 +12,8 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.experimental.SuperBuilder;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
@SuperBuilder
@@ -23,8 +22,9 @@ public abstract class ConfigFileTerminalPrompt implements TerminalPrompt {
protected static <T extends ConfigFileTerminalPrompt> OptionsBuilder createOptions(Property<T> p, String extension, Function<String, T> creator) {
var prop = new SimpleObjectProperty<>(p.getValue() != null ? p.getValue().configuration : null);
return new OptionsBuilder()
.nameAndDescription("configuration")
.addComp(new IntegratedTextAreaComp(prop, false, "config", new SimpleStringProperty(extension)), prop)
.nameAndDescription("terminalPromptConfig")
.addComp(new IntegratedTextAreaComp(prop, false, p.getValue() != null ? p.getValue().getId() : "config",
new SimpleStringProperty(extension)).prefHeight(400), prop)
.bind(
() -> {
return creator.apply(prop.getValue());
@@ -39,15 +39,32 @@ public abstract class ConfigFileTerminalPrompt implements TerminalPrompt {
protected abstract FilePath getDefaultConfigFile(ShellControl sc) throws Exception;
@Override
public ShellTerminalInitCommand terminalCommand(ShellControl sc) throws Exception {
FilePath configFile;
if (configuration == null || configuration.isBlank()) {
configFile = getDefaultConfigFile(sc);
} else {
configFile = prepareCustomConfigFile(sc);
}
return terminalCommand(sc, configFile);
public ShellTerminalInitCommand terminalCommand() throws Exception {
return new ShellTerminalInitCommand() {
@Override
public Optional<String> terminalContent(ShellControl shellControl) throws Exception {
if (!installIfNeeded(shellControl)) {
return Optional.empty();
}
FilePath configFile;
if (configuration == null || configuration.isBlank()) {
configFile = getDefaultConfigFile(shellControl);
} else {
configFile = prepareCustomConfigFile(shellControl);
shellControl.view().writeTextFile(configFile, configuration);
}
var s = shellControl.getShellDialect().addToPathVariableCommand(List.of(getBinaryDirectory(shellControl).toString()), false);
return Optional.of(s + "\n" + setupTerminalCommand(shellControl, configFile).toString());
}
@Override
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
return getSupportedDialects().contains(dialect);
}
};
}
protected abstract ShellTerminalInitCommand terminalCommand(ShellControl shellControl, FilePath config) throws Exception;
protected abstract ShellScript setupTerminalCommand(ShellControl shellControl, FilePath config) throws Exception;
}
@@ -0,0 +1,117 @@
package io.xpipe.app.terminal;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.xpipe.app.util.CommandSupport;
import io.xpipe.app.util.GithubReleaseDownloader;
import io.xpipe.app.util.OptionsBuilder;
import io.xpipe.core.process.*;
import io.xpipe.core.store.FilePath;
import javafx.beans.property.Property;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
import java.util.ArrayList;
import java.util.List;
@Getter
@SuperBuilder
@ToString
@Jacksonized
@JsonTypeName("starship")
public class OhMyPoshTerminalPrompt extends ConfigFileTerminalPrompt {
public static OptionsBuilder createOptions(Property<OhMyPoshTerminalPrompt> p) {
return createOptions(p, "toml", s -> OhMyPoshTerminalPrompt.builder().configuration(s).build());
}
@Override
public String getDocsLink() {
return "https://starship.rs/guide/";
}
@Override
public String getId() {
return "starship";
}
@Override
public void checkCanInstall(ShellControl sc) throws Exception {
if (sc.getOsType() != OsType.WINDOWS) {
CommandSupport.isInPathOrThrow(sc, "curl");
}
}
@Override
public boolean checkIfInstalled(ShellControl sc) throws Exception {
if (sc.getShellDialect() == ShellDialects.CMD && !ClinkHelper.checkIfInstalled(sc)) {
return false;
}
if (sc.view().findProgram("starship").isPresent()) {
return true;
}
var extension = OsType.getLocal() == OsType.WINDOWS ? ".exe" : "";
return sc.view().fileExists(getBinaryDirectory(sc).join("starship" + extension));
}
@Override
public void install(ShellControl sc) throws Exception {
if (sc.getShellDialect() == ShellDialects.CMD) {
ClinkHelper.install(sc);
var configDir = getConfigurationDirectory(sc);
sc.view().mkdir(configDir);
sc.view().writeTextFile(configDir.join("starship.lua"), "load(io.popen('starship init cmd'):read(\"*a\"))()");
}
var dir = getBinaryDirectory(sc);
sc.view().mkdir(dir);
if (sc.getOsType() == OsType.WINDOWS) {
var file = GithubReleaseDownloader.getDownloadTempFile(
"JanDeDobbeleer/oh-my-posh",
"posh-windows-amd64.exe",
s -> s.equals("posh-windows-amd64.exe"));
sc.view().transferLocalFile(file, dir.join("starship.exe"));
} else {
sc.command("curl -sS https://starship.rs/install.sh | sh /dev/stdin -y --bin-dir \"" + dir + "\" > /dev/null").execute();
}
}
@Override
public FilePath prepareCustomConfigFile(ShellControl sc) throws Exception {
var file = getConfigurationDirectory(sc).join("starship.toml");
sc.view().writeTextFile(file, configuration);
return file;
}
@Override
public FilePath getDefaultConfigFile(ShellControl sc) throws Exception {
return sc.view().userHome().join(".config").join("starship.toml");
}
@Override
protected ShellScript setupTerminalCommand(ShellControl shellControl, FilePath config) throws Exception {
var lines = new ArrayList<String>();
if (shellControl.getShellDialect() == ShellDialects.CMD) {
lines.add(shellControl.getShellDialect().addToPathVariableCommand(List.of(ClinkHelper.getTargetDir(shellControl).toString()), false));
}
lines.add(shellControl.getShellDialect().getSetEnvironmentVariableCommand("STARSHIP_CONFIG", config.toString()));
if (shellControl.getShellDialect() == ShellDialects.CMD) {
lines.add("clink inject --quiet --profile \"" + getConfigurationDirectory(shellControl) + "\"");
} else if (ShellDialects.isPowershell(shellControl)) {
lines.add("Invoke-Expression (&starship init powershell)");
} else if (shellControl.getShellDialect() == ShellDialects.FISH) {
lines.add("starship init fish | source");
} else {
lines.add("eval \"$(starship init " + shellControl.getShellDialect().getId() + ")\"");
}
return ShellScript.lines(lines);
}
@Override
public List<ShellDialect> getSupportedDialects() {
return List.of(ShellDialects.BASH, ShellDialects.ZSH, ShellDialects.FISH, ShellDialects.CMD, ShellDialects.POWERSHELL, ShellDialects.POWERSHELL_CORE);
}
}
@@ -1,28 +1,21 @@
package io.xpipe.app.terminal;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.password.KeePassXcAssociationKey;
import io.xpipe.app.password.KeePassXcManager;
import io.xpipe.app.util.CommandSupport;
import io.xpipe.app.util.GithubReleaseDownloader;
import io.xpipe.app.util.OptionsBuilder;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.process.ShellDialect;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.process.ShellTerminalInitCommand;
import io.xpipe.core.process.*;
import io.xpipe.core.store.FilePath;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Getter
@SuperBuilder
@@ -37,32 +30,62 @@ public class StarshipTerminalPrompt extends ConfigFileTerminalPrompt {
@Override
public String getDocsLink() {
return "";
return "https://starship.rs/guide/";
}
@Override
public String getId() {
return "starship";
}
@Override
public void checkCanInstall(ShellControl sc) throws Exception {
CommandSupport.isInPathOrThrow(sc, "curl");
if (sc.getOsType() != OsType.WINDOWS) {
CommandSupport.isInPathOrThrow(sc, "curl");
}
}
@Override
public boolean checkIfInstalled(ShellControl sc) throws Exception {
if (sc.getShellDialect() == ShellDialects.CMD && !ClinkHelper.checkIfInstalled(sc)) {
return false;
}
if (sc.view().findProgram("starship").isPresent()) {
return true;
}
return false;
var extension = OsType.getLocal() == OsType.WINDOWS ? ".exe" : "";
return sc.view().fileExists(getBinaryDirectory(sc).join("starship" + extension));
}
@Override
public void install(ShellControl sc) throws Exception {
var dir = getBinaryDirectory(sc).join("starship");
sc.command("curl -sS https://starship.rs/install.sh | sh /dev/stdin -y --bin-dir \"" + dir + "\" > /dev/null").execute();
if (sc.getShellDialect() == ShellDialects.CMD) {
ClinkHelper.install(sc);
var configDir = getConfigurationDirectory(sc);
sc.view().mkdir(configDir);
sc.view().writeTextFile(configDir.join("starship.lua"), "load(io.popen('starship init cmd'):read(\"*a\"))()");
}
var dir = getBinaryDirectory(sc);
sc.view().mkdir(dir);
if (sc.getOsType() == OsType.WINDOWS) {
var file = GithubReleaseDownloader.getDownloadTempFile("starship/starship",
"starship-x86_64-pc-windows-msvc.zip",
s -> s.equals("starship-x86_64-pc-windows-msvc.zip"));
try (var fs = FileSystems.newFileSystem(file)) {
var exeFile = fs.getPath("starship.exe");
sc.view().transferLocalFile(exeFile, dir.join("starship.exe"));
}
} else {
sc.command("curl -sS https://starship.rs/install.sh | sh /dev/stdin -y --bin-dir \"" + dir + "\" > /dev/null").execute();
}
}
@Override
public FilePath prepareCustomConfigFile(ShellControl sc) throws Exception {
var file = getConfigurationDirectory(sc).join("starship").join("starship.toml");
var file = getConfigurationDirectory(sc).join("starship.toml");
sc.view().writeTextFile(file, configuration);
return file;
}
@@ -73,25 +96,26 @@ public class StarshipTerminalPrompt extends ConfigFileTerminalPrompt {
}
@Override
public ShellTerminalInitCommand terminalCommand(ShellControl shellControl, FilePath configFile) throws Exception {
return new ShellTerminalInitCommand() {
@Override
public Optional<String> terminalContent(ShellControl shellControl) throws Exception {
var s = shellControl.getShellDialect().getSetEnvironmentVariableCommand("STARSHIP_CONFIG", "") + "\n" + "eval \"$(starship init bash)\"";
return Optional.empty();
}
@Override
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
return false;
}
};
protected ShellScript setupTerminalCommand(ShellControl shellControl, FilePath config) throws Exception {
var lines = new ArrayList<String>();
if (shellControl.getShellDialect() == ShellDialects.CMD) {
lines.add(shellControl.getShellDialect().addToPathVariableCommand(List.of(ClinkHelper.getTargetDir(shellControl).toString()), false));
}
lines.add(shellControl.getShellDialect().getSetEnvironmentVariableCommand("STARSHIP_CONFIG", config.toString()));
if (shellControl.getShellDialect() == ShellDialects.CMD) {
lines.add("clink inject --quiet --profile \"" + getConfigurationDirectory(shellControl) + "\"");
} else if (ShellDialects.isPowershell(shellControl)) {
lines.add("Invoke-Expression (&starship init powershell)");
} else if (shellControl.getShellDialect() == ShellDialects.FISH) {
lines.add("starship init fish | source");
} else {
lines.add("eval \"$(starship init " + shellControl.getShellDialect().getId() + ")\"");
}
return ShellScript.lines(lines);
}
@Override
public List<ShellDialect> getSupportedDialects() {
return List.of(ShellDialects.BASH);
return List.of(ShellDialects.BASH, ShellDialects.ZSH, ShellDialects.FISH, ShellDialects.CMD, ShellDialects.POWERSHELL, ShellDialects.POWERSHELL_CORE);
}
}
@@ -1,6 +1,7 @@
package io.xpipe.app.terminal;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.ShellTemp;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.process.ShellDialect;
@@ -22,18 +23,31 @@ public interface TerminalPrompt {
String getDocsLink();
default FilePath getConfigurationDirectory(ShellControl sc) throws Exception {
return ShellTemp.createUserSpecificTempDataDirectory(sc, "prompt");
var d = ShellTemp.createUserSpecificTempDataDirectory(sc, "prompt").join(getId());
sc.view().mkdir(d);
return d;
}
default FilePath getBinaryDirectory(ShellControl sc) throws Exception {
return ShellTemp.createUserSpecificTempDataDirectory(sc, "bin");
var d = ShellTemp.createUserSpecificTempDataDirectory(sc, "bin").join(getId());
sc.view().mkdir(d);
return d;
}
default void installIfNeeded(ShellControl sc) throws Exception {
if (checkIfInstalled(sc)) {
checkCanInstall(sc);
install(sc);
String getId();
default boolean installIfNeeded(ShellControl sc) throws Exception {
if (!checkIfInstalled(sc)) {
try {
checkCanInstall(sc);
install(sc);
} catch (Exception e) {
ErrorEvent.fromThrowable(e).omit().handle();
return false;
}
return true;
}
return true;
}
void checkCanInstall(ShellControl sc) throws Exception;
@@ -42,7 +56,7 @@ public interface TerminalPrompt {
void install(ShellControl sc) throws Exception;
ShellTerminalInitCommand terminalCommand(ShellControl shellControl) throws Exception;
ShellTerminalInitCommand terminalCommand() throws Exception;
List<ShellDialect> getSupportedDialects();
}
@@ -12,14 +12,8 @@ public class TerminalPromptManager {
return;
}
var d = p.getSupportedDialects();
if (!d.contains(sc.getShellDialect())) {
return;
}
try {
p.installIfNeeded(sc);
sc.withInitSnippet(p.terminalCommand(sc));
sc.withInitSnippet(p.terminalCommand());
} catch (Exception e) {
ErrorEvent.fromThrowable(e).handle();
}
@@ -0,0 +1,63 @@
package io.xpipe.app.util;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.store.FilePath;
import io.xpipe.core.util.JacksonMapper;
import lombok.Value;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
public class GithubReleaseDownloader {
public static Path getDownloadTempFile(String repository, String id, Predicate<String> filter) throws Exception {
var tempDir = ShellTemp.getLocalTempDataDirectory("github");
var temp = tempDir.resolve(id);
if (Files.exists(temp)) {
return temp;
}
var request = HttpRequest.newBuilder().GET().uri(URI.create(getDownloadUrl(repository, filter))).build();
var r = HttpHelper.client().send(request,
HttpResponse.BodyHandlers.ofByteArray());
if (r.statusCode() >= 400) {
throw new IOException(new String(r.body(), StandardCharsets.UTF_8));
}
Files.createDirectories(tempDir);
Files.write(temp, r.body());
return temp;
}
private static String getDownloadUrl(String repository, Predicate<String> filter) throws Exception {
var request = HttpRequest.newBuilder().GET().uri(URI.create("https://api.github.com/repos/" + repository + "/releases")).build();
var r = HttpHelper.client().send(request,
HttpResponse.BodyHandlers.ofString());
if (r.statusCode() >= 400) {
throw new IOException(r.body());
}
var json = JacksonMapper.getDefault().readTree(r.body());
var latest = json.get(0);
var assets = latest.required("assets");
for (var asset : assets) {
var name = asset.required("name").asText();
if (filter.test(name)) {
var url = asset.required("browser_download_url").asText();
return url;
}
}
throw new IllegalStateException("Unable to find download url for " + repository);
}
}
@@ -49,7 +49,7 @@ public class ShellTemp {
proc.command("chmod 777 " + proc.getShellDialect().fileArgument(base))
.executeAndCheck();
var user = proc.getShellDialect().printUsernameCommand(proc).readStdoutOrThrow();
base = temp.join(user);
base = base.join(user);
} else {
var temp = proc.getSystemTemporaryDirectory();
base = temp.join("xpipe");
@@ -18,12 +18,12 @@ public abstract class SimpleFilterInputStream extends FilterInputStream {
@Override
public int read(byte @NonNull [] b, int off, int len) throws IOException {
for (int i = off; i < off + len; i++) {
var r = (byte) read();
var r = read();
if (r == -1) {
return i - off == 0 ? -1 : i - off;
}
b[i] = r;
b[i] = (byte) r;
}
return len;
}
@@ -3,6 +3,7 @@ package io.xpipe.core.process;
import lombok.Value;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Value
@@ -12,6 +13,10 @@ public class ShellScript {
return new ShellScript(Arrays.stream(lines).collect(Collectors.joining("\n")));
}
public static ShellScript lines(List<String> lines) {
return new ShellScript(lines.stream().collect(Collectors.joining("\n")));
}
String value;
@Override
@@ -3,6 +3,8 @@ package io.xpipe.core.process;
import io.xpipe.core.store.FilePath;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
public class ShellView {
@@ -66,6 +68,12 @@ public class ShellView {
.executeAndCheck();
}
public void mkdir(FilePath path) throws Exception {
shellControl.command(getDialect()
.getMkdirsCommand(path.toString()))
.execute();
}
public boolean directoryExists(FilePath path) throws Exception {
return getDialect().directoryExists(shellControl, path.toString()).executeAndCheck();
}
@@ -104,6 +112,12 @@ public class ShellView {
return out.flatMap(s -> s.lines().findFirst()).map(String::trim).map(s -> FilePath.of(s));
}
public void transferLocalFile(Path localPath, FilePath target) throws Exception {
try (var in = Files.newInputStream(localPath)) {
writeStreamFile(target, in, in.available());
}
}
public boolean isInPath(String executable) throws Exception {
return shellControl.executeSimpleBooleanCommand(
shellControl.getShellDialect().getWhichCommand(executable));
@@ -15,16 +15,16 @@ import java.util.*;
public class ScriptStoreSetup {
public static ShellControl controlWithDefaultScripts(ShellControl pc) {
return controlWithScripts(pc, getEnabledScripts());
public static void controlWithDefaultScripts(ShellControl pc) {
controlWithScripts(pc, getEnabledScripts());
}
public static ShellControl controlWithScripts(
public static void controlWithScripts(
ShellControl pc, List<DataStoreEntryRef<ScriptStore>> enabledScripts) {
try {
// Don't copy scripts if we don't want to modify the file system
if (!pc.getEffectiveSecurityPolicy().permitTempScriptCreation()) {
return pc;
return;
}
var initFlattened = flatten(enabledScripts).stream()
@@ -36,7 +36,7 @@ public class ScriptStoreSetup {
// Optimize if we have nothing to do
if (initFlattened.isEmpty() && bringFlattened.isEmpty()) {
return pc;
return;
}
initFlattened.forEach(s -> {
@@ -77,7 +77,6 @@ public class ScriptStoreSetup {
}
});
}
return pc;
} catch (StackOverflowError t) {
throw ErrorEvent.expected(
new RuntimeException("Unable to set up scripts. Is there a circular script dependency?", t));
@@ -10,6 +10,8 @@ import io.xpipe.app.ext.*;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.terminal.TerminalLauncher;
import io.xpipe.app.terminal.TerminalPromptManager;
import io.xpipe.app.terminal.TerminalProxyManager;
import io.xpipe.app.util.ShellStoreFormat;
import io.xpipe.ext.base.script.ScriptStoreSetup;
@@ -25,7 +27,9 @@ public interface ShellStoreProvider extends DataStoreProvider {
public void execute() throws Exception {
var replacement = ProcessControlProvider.get().replace(entry.ref());
ShellStore store = replacement.getStore().asNeeded();
var control = ScriptStoreSetup.controlWithDefaultScripts(store.standaloneControl());
var control = store.standaloneControl();
ScriptStoreSetup.controlWithDefaultScripts(control);
TerminalPromptManager.configurePromptScript(control);
TerminalLauncher.open(
replacement.get(),
DataStorage.get().getStoreEntryDisplayName(replacement.get()),
+3
View File
@@ -1381,4 +1381,7 @@ refreshOpenpubkey=Refresh openpubkey identity
refreshOpenpubkeyDescription=Run opkssh refresh to make the openpubkey identity valid again
all=All
terminalPrompt=Terminal prompt
terminalPromptDescription=The terminal prompt tool to use in your remote terminals.\n\nEnabling a terminal prompt will automatically set up and configure the prompt tool on the target system when opening a terminal session. This will increase the terminal loading time for the first time while the prompt is being set up on the remote system.
terminalPromptConfiguration=Terminal prompt configuration
terminalPromptConfig=Config file
terminalPromptConfigDescription=The custom config file to apply to the prompt. This config will be automatically set up on the target system when the terminal is initialized and used as the default prompt config.\n\nIf you want to use the existing default config file on each system, you can leave this field empty.