From 953d91ca42fcbfc8da649e116f5e346dfd7a5b71 Mon Sep 17 00:00:00 2001 From: crschnick Date: Tue, 1 Apr 2025 13:51:00 +0000 Subject: [PATCH] Scripting rework --- .../java/io/xpipe/app/ext/ShellStore.java | 20 +++++++++++ .../terminal/ConfigFileTerminalPrompt.java | 35 +++++++++++++++++++ .../app/terminal/StarshipTerminalPrompt.java | 33 +++++++++++++++++ .../io/xpipe/app/terminal/TerminalPrompt.java | 31 ++++++++++++++++ .../io/xpipe/core/process/ShellControl.java | 2 ++ .../core/process/WrapperShellControl.java | 5 +++ .../ext/base/store/ShellStoreProvider.java | 2 +- .../ext/base/resources/scripts/clink.bat | 6 ++-- .../ext/base/resources/scripts/ohmyposh.bat | 17 +++++++-- .../ext/base/resources/scripts/ohmyposh.ps1 | 14 +++++--- 10 files changed, 154 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/io/xpipe/app/terminal/ConfigFileTerminalPrompt.java create mode 100644 app/src/main/java/io/xpipe/app/terminal/StarshipTerminalPrompt.java create mode 100644 app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java diff --git a/app/src/main/java/io/xpipe/app/ext/ShellStore.java b/app/src/main/java/io/xpipe/app/ext/ShellStore.java index 3dc2961cb..980b31537 100644 --- a/app/src/main/java/io/xpipe/app/ext/ShellStore.java +++ b/app/src/main/java/io/xpipe/app/ext/ShellStore.java @@ -28,6 +28,26 @@ public interface ShellStore extends DataStore, FileSystemStore, ValidatableStore return new StubShellControl(getSession().getShellControl()); } + default boolean checkSessionAlive() { + var session = getSession(); + if (session == null || !session.isRunning()) { + return false; + } + + try { + session.getShellControl().command(" echo xpipetest").execute(); + return true; + } catch (Exception e) { + ErrorEvent.fromThrowable(e).expected().omit().handle(); + try { + stopSessionIfNeeded(); + } catch (Exception se) { + ErrorEvent.fromThrowable(se).expected().omit().handle(); + } + return false; + } + } + @Override default ShellSession newSession() throws Exception { var func = shellFunction(); diff --git a/app/src/main/java/io/xpipe/app/terminal/ConfigFileTerminalPrompt.java b/app/src/main/java/io/xpipe/app/terminal/ConfigFileTerminalPrompt.java new file mode 100644 index 000000000..fd4325253 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/terminal/ConfigFileTerminalPrompt.java @@ -0,0 +1,35 @@ +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.ShellTerminalInitCommand; +import javafx.beans.property.Property; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import lombok.experimental.SuperBuilder; + +import java.util.function.Function; + +@SuperBuilder +public abstract class ConfigFileTerminalPrompt implements TerminalPrompt { + + protected static OptionsBuilder createOptions(Property p, String extension, Function creator) { + var prop = new SimpleObjectProperty(); + return new OptionsBuilder() + .nameAndDescription("configuration") + .addComp(new IntegratedTextAreaComp(prop, false, "config", new SimpleStringProperty(extension)), prop) + .bind( + () -> { + return creator.apply(prop.getValue()); + }, + p); + } + + protected String configuration; +} diff --git a/app/src/main/java/io/xpipe/app/terminal/StarshipTerminalPrompt.java b/app/src/main/java/io/xpipe/app/terminal/StarshipTerminalPrompt.java new file mode 100644 index 000000000..c95af3d70 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/terminal/StarshipTerminalPrompt.java @@ -0,0 +1,33 @@ +package io.xpipe.app.terminal; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import io.xpipe.core.process.ShellControl; +import io.xpipe.core.process.ShellTerminalInitCommand; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +@Getter +@SuperBuilder +@ToString +@Jacksonized +@JsonTypeName("starship") +public class StarshipTerminalPrompt extends ConfigFileTerminalPrompt { + + @Override + public String getDocsLink() { + return ""; + } + + @Override + public void checkSupported(ShellControl sc) throws Exception { + + } + + @Override + public ShellTerminalInitCommand setup(ShellControl shellControl) throws Exception { + return null; + } +} diff --git a/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java b/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java new file mode 100644 index 000000000..9f22fb264 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java @@ -0,0 +1,31 @@ +package io.xpipe.app.terminal; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.xpipe.core.process.ShellControl; +import io.xpipe.core.process.ShellScript; +import io.xpipe.core.process.ShellTerminalInitCommand; +import io.xpipe.core.process.TerminalInitScriptConfig; +import io.xpipe.core.util.ValidationException; + +import java.util.ArrayList; +import java.util.List; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") +public interface TerminalPrompt { + + static List> getClasses() { + var l = new ArrayList>(); + l.add(TmuxTerminalMultiplexer.class); + l.add(ZellijTerminalMultiplexer.class); + l.add(ScreenTerminalMultiplexer.class); + return l; + } + + default void checkComplete() throws ValidationException {} + + String getDocsLink(); + + void checkSupported(ShellControl sc) throws Exception; + + ShellTerminalInitCommand setup(ShellControl shellControl) throws Exception; +} diff --git a/core/src/main/java/io/xpipe/core/process/ShellControl.java b/core/src/main/java/io/xpipe/core/process/ShellControl.java index 59ba3fbf3..9ce90d53c 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellControl.java +++ b/core/src/main/java/io/xpipe/core/process/ShellControl.java @@ -190,6 +190,8 @@ public interface ShellControl extends ProcessControl { ShellControl withInitSnippet(ShellTerminalInitCommand snippet); + Optional getActiveReplacementBackgroundSession() throws Exception; + default ShellControl subShell(@NonNull ShellDialect type) { var o = new ShellOpenFunction() { diff --git a/core/src/main/java/io/xpipe/core/process/WrapperShellControl.java b/core/src/main/java/io/xpipe/core/process/WrapperShellControl.java index bf1204c87..7451bd43a 100644 --- a/core/src/main/java/io/xpipe/core/process/WrapperShellControl.java +++ b/core/src/main/java/io/xpipe/core/process/WrapperShellControl.java @@ -343,6 +343,11 @@ public class WrapperShellControl implements ShellControl { return parent.withInitSnippet(snippet); } + @Override + public Optional getActiveReplacementBackgroundSession() throws Exception { + return parent.getActiveReplacementBackgroundSession(); + } + @Override public ShellControl subShell() { return parent.subShell(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/store/ShellStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/store/ShellStoreProvider.java index e4b8b854d..f907e2991 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/store/ShellStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/store/ShellStoreProvider.java @@ -25,7 +25,7 @@ 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.tempControl()); + var control = ScriptStoreSetup.controlWithDefaultScripts(store.standaloneControl()); TerminalLauncher.open( replacement.get(), DataStorage.get().getStoreEntryDisplayName(replacement.get()), diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat index e780ec2a2..bb27d14f5 100644 --- a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/clink.bat @@ -1,4 +1,4 @@ -WHERE clink >NUL 2>NUL +WHERE /q clink IF %ERRORLEVEL%==0 ( exit /b 0 ) @@ -15,5 +15,7 @@ $defaultCreds = [System.Net.CredentialCache]::DefaultCredentials;^ if ($defaultCreds) {^ $downloader.Credentials = $defaultCreds^ }^ -$downloader.DownloadFile("https://github.com/chrisant996/clink/releases/download/v1.7.7/clink.1.7.7.521fa7.zip", "$env:TEMP\clink.zip");^ +$downloader.DownloadFile("https://github.com/chrisant996/clink/releases/download/v1.7.13/clink.1.7.13.ac5d42.zip", "$env:TEMP\clink.zip");^ Expand-Archive -Force -LiteralPath "$env:TEMP\clink.zip" -DestinationPath "$env:TEMP\xpipe\scriptdata\clink"; | powershell -NoLogo >NUL + +clink set clink.autoupdate off diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.bat b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.bat index 79e45bbce..cf920f60c 100644 --- a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.bat +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.bat @@ -1,5 +1,16 @@ -WHERE /q winget && winget install JanDeDobbeleer.OhMyPosh -s winget || powershell -ExecutionPolicy Bypass -Command "Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://ohmyposh.dev/install.ps1'))" -SET "PATH=%PATH%;%USERPROFILE%\AppData\Local\Programs\oh-my-posh\bin" -MKDIR "%TEMP%\\xpipe\\scriptdata\\starship" >NUL 2>NUL +WHERE /q oh-my-posh +IF NOT %ERRORLEVEL%==0 ( + IF NOT EXIST "%USERPROFILE%\AppData\Local\Programs\oh-my-posh\bin\oh-my-posh.exe" ( + WHERE /q winget + IF NOT %ERRORLEVEL%==0 ( + winget install JanDeDobbeleer.OhMyPosh -s winget + ) ELSE ( + powershell -ExecutionPolicy Bypass -Command "Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://ohmyposh.dev/install.ps1'))" + ) + ) + SET "PATH=%PATH%;%USERPROFILE%\AppData\Local\Programs\oh-my-posh\bin" +) + +MKDIR "%TEMP%\\xpipe\\scriptdata\\ohmyposh" >NUL 2>NUL ECHO load(io.popen('oh-my-posh init cmd'):read("*a"))() > "%TEMP%\\xpipe\\scriptdata\\ohmyposh\\ohmyposh.lua" clink inject --quiet --profile "%TEMP%\\xpipe\\scriptdata\\ohmyposh" diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.ps1 b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.ps1 index 3ec0eb9e4..6319e0a84 100644 --- a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.ps1 +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/ohmyposh.ps1 @@ -1,7 +1,11 @@ -if (Get-Command "winget" -ErrorAction SilentlyContinue) { - winget install JanDeDobbeleer.OhMyPosh -s winget -} else { - Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://ohmyposh.dev/install.ps1')) +if ( -not Get-Command "oh-my-posh" -ErrorAction SilentlyContinue) { + if ( -not Test-Path "$env:USERPROFILE\AppData\Local\Programs\oh-my-posh\bin\oh-my-posh.exe" -PathType Leaf) { + if (Get-Command "winget" -ErrorAction SilentlyContinue) { + winget install JanDeDobbeleer.OhMyPosh -s winget + } else { + Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://ohmyposh.dev/install.ps1')) + } + } + $env:Path += ";$env:USERPROFILE\AppData\Local\Programs\oh-my-posh\bin" } -$env:Path += ";$env:USERPROFILE\AppData\Local\Programs\oh-my-posh\bin" & ([ScriptBlock]::Create((oh-my-posh init $(oh-my-posh get shell) --config "$env:POSH_THEMES_PATH\jandedobbeleer.omp.json" --print) -join "`n"))