From e9587c24d65f1657911cc48ded49f96bfb1ba6d3 Mon Sep 17 00:00:00 2001 From: crschnick Date: Mon, 22 Jan 2024 06:54:54 +0000 Subject: [PATCH] Rebase fixes --- .../xpipe/app/browser/BrowserClipboard.java | 4 +- .../xpipe/app/core/check/AppShellCheck.java | 4 +- .../app/prefs/ExternalApplicationType.java | 3 +- .../xpipe/app/prefs/ExternalTerminalType.java | 6 +- .../io/xpipe/app/prefs/PasswordCategory.java | 6 +- .../io/xpipe/app/update/AppInstaller.java | 20 ++-- .../xpipe/app/update/XPipeInstanceHelper.java | 2 +- .../java/io/xpipe/app/util/SmoothScroll.java | 107 ------------------ .../core/process/ProcessControlProvider.java | 4 + .../io/xpipe/core/process/ShellControl.java | 4 - .../io/xpipe/core/process/ShellDialect.java | 15 +-- .../io/xpipe/core/process/ShellDialects.java | 21 ++-- .../xpipe/core/process/ShellProperties.java | 9 ++ .../io/xpipe/core/util/XPipeInstallation.java | 3 +- 14 files changed, 50 insertions(+), 158 deletions(-) delete mode 100644 app/src/main/java/io/xpipe/app/util/SmoothScroll.java diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java b/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java index e7cd49da6..01d97b66c 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserClipboard.java @@ -2,7 +2,7 @@ package io.xpipe.app.browser; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.util.ThreadHelper; -import io.xpipe.core.process.ShellDialects; +import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.store.FileSystem; import io.xpipe.core.util.FailableRunnable; import javafx.beans.property.Property; @@ -32,7 +32,7 @@ public class BrowserClipboard { public String toClipboardString() { return entries.stream().map(fileEntry -> "\"" + fileEntry.getPath() + "\"").collect( - Collectors.joining(ShellDialects.getPlatformDefault().getNewLine().getNewLineString())); + Collectors.joining(ProcessControlProvider.get().getEffectiveLocalDialect().getNewLine().getNewLineString())); } } diff --git a/app/src/main/java/io/xpipe/app/core/check/AppShellCheck.java b/app/src/main/java/io/xpipe/app/core/check/AppShellCheck.java index 9980022ad..ed8773eda 100644 --- a/app/src/main/java/io/xpipe/app/core/check/AppShellCheck.java +++ b/app/src/main/java/io/xpipe/app/core/check/AppShellCheck.java @@ -2,8 +2,8 @@ package io.xpipe.app.core.check; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.util.LocalShell; +import io.xpipe.core.process.ProcessControlProvider; import io.xpipe.core.process.ProcessOutputException; -import io.xpipe.core.process.ShellDialects; import java.util.Optional; @@ -24,7 +24,7 @@ public class AppShellCheck { - The operating system is not supported You can reach out to us if you want to properly diagnose the cause individually and hopefully fix it. - """.formatted(ShellDialects.getPlatformDefault().getDisplayName(), err.get()); + """.formatted(ProcessControlProvider.get().getEffectiveLocalDialect().getDisplayName(), err.get()); ErrorEvent.fromMessage(msg).handle(); } } diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java index a5155b6df..55f4165a8 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java @@ -5,7 +5,6 @@ import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.util.LocalShell; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellControl; -import io.xpipe.core.process.ShellDialects; import java.nio.file.Files; import java.nio.file.Path; @@ -119,7 +118,7 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue { protected Optional determineFromPath() { // Try to locate if it is in the Path try (var cc = LocalShell.getShell() - .command(ShellDialects.getPlatformDefault().getWhichCommand(executable)) + .command(var1 -> var1.getShellDialect().getWhichCommand(executable)) .start()) { var out = cc.readStdoutDiscardErr(); var exit = cc.getExitCode(); diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java index 444309631..9734c76a9 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalTerminalType.java @@ -7,6 +7,7 @@ import io.xpipe.app.util.*; import io.xpipe.core.process.CommandBuilder; import io.xpipe.core.process.OsType; import io.xpipe.core.process.ShellControl; +import io.xpipe.core.process.ShellDialects; import io.xpipe.core.store.FileNames; import io.xpipe.core.store.LocalStore; import lombok.Getter; @@ -134,11 +135,14 @@ public interface ExternalTerminalType extends PrefsChoiceValue { // backslash of a filepath to escape the closing quote in the title argument // So just remove that slash var fixedName = FileNames.removeTrailingSlash(configuration.getTitle()); + var toExec = !ShellDialects.isPowershell(LocalShell.getShell()) ? + CommandBuilder.of().addFile(configuration.getScriptFile()) : + CommandBuilder.of().add("powershell", "-ExecutionPolicy", "Bypass", "-File").addQuoted(configuration.getScriptFile()); LocalShell.getShell() .executeSimpleCommand(CommandBuilder.of() .add("wt", "-w", "1", "nt", "--title") .addQuoted(fixedName) - .addFile(configuration.getScriptFile())); + .addSub(toExec)); } @Override diff --git a/app/src/main/java/io/xpipe/app/prefs/PasswordCategory.java b/app/src/main/java/io/xpipe/app/prefs/PasswordCategory.java index 8a0bb2b51..7b1d08179 100644 --- a/app/src/main/java/io/xpipe/app/prefs/PasswordCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/PasswordCategory.java @@ -10,7 +10,6 @@ import io.xpipe.app.fxcomps.impl.TextFieldComp; import io.xpipe.app.util.TerminalHelper; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.process.CommandControl; -import io.xpipe.core.process.ShellDialects; import io.xpipe.core.store.LocalStore; import javafx.beans.property.SimpleStringProperty; import javafx.geometry.Insets; @@ -41,10 +40,9 @@ public class PasswordCategory extends AppPrefsCategory { "Password test", new LocalStore() .control() - .command(cmd + .command(sc -> cmd + "\n" - + ShellDialects.getPlatformDefault() - .getEchoCommand("Is this your password?", false)) + + sc.getShellDialect().getEchoCommand("Is this your password?", false)) .terminalExitMode(CommandControl.TerminalExitMode.KEEP_OPEN)); }); }; diff --git a/app/src/main/java/io/xpipe/app/update/AppInstaller.java b/app/src/main/java/io/xpipe/app/update/AppInstaller.java index b4c157e78..dc29c72d7 100644 --- a/app/src/main/java/io/xpipe/app/update/AppInstaller.java +++ b/app/src/main/java/io/xpipe/app/update/AppInstaller.java @@ -6,10 +6,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName; import io.xpipe.app.core.AppProperties; import io.xpipe.app.util.ScriptHelper; import io.xpipe.app.util.TerminalHelper; -import io.xpipe.core.process.CommandControl; -import io.xpipe.core.process.OsType; -import io.xpipe.core.process.ShellControl; -import io.xpipe.core.process.ShellDialects; +import io.xpipe.core.process.*; import io.xpipe.core.store.FileNames; import io.xpipe.core.store.LocalStore; import io.xpipe.core.util.XPipeInstallation; @@ -18,7 +15,6 @@ import lombok.Getter; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; public class AppInstaller { @@ -125,19 +121,19 @@ public class AppInstaller { var exec = XPipeInstallation.getInstallationExecutable( shellControl, XPipeInstallation.getDefaultInstallationBasePath(shellControl)); var logsDir = FileNames.join(XPipeInstallation.getDataDir(shellControl), "logs"); - var cmd = new ArrayList<>(java.util.List.of( + var cmd = CommandBuilder.of().add( "start", "/wait", "msiexec", - "/i", - file, - "/l*", - FileNames.join(logsDir, "installer_" + FileNames.getFileName(file) + ".log"), + "/i").addFile( + file).add( + "/l*").addFile( + FileNames.join(logsDir, "installer_" + FileNames.getFileName(file) + ".log")).add( "/qb", - "&", + "&").addFile( exec // "/qf" - )); + ); try (CommandControl c = shellControl.command(cmd).start()) { c.discardOrThrow(); } diff --git a/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java b/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java index b0aa71de2..bbe311d7e 100644 --- a/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java +++ b/app/src/main/java/io/xpipe/app/update/XPipeInstanceHelper.java @@ -35,7 +35,7 @@ public class XPipeInstanceHelper { public static boolean isSupported(ShellStore host) { try (var pc = host.control().start(); - var cmd = pc.command(List.of("xpipe"))) { + var cmd = pc.command("xpipe")) { cmd.discardOrThrow(); return true; } catch (Exception e) { diff --git a/app/src/main/java/io/xpipe/app/util/SmoothScroll.java b/app/src/main/java/io/xpipe/app/util/SmoothScroll.java deleted file mode 100644 index 5c19f6d28..000000000 --- a/app/src/main/java/io/xpipe/app/util/SmoothScroll.java +++ /dev/null @@ -1,107 +0,0 @@ -package io.xpipe.app.util; - -import javafx.animation.Animation; -import javafx.animation.KeyFrame; -import javafx.animation.Timeline; -import javafx.event.EventHandler; -import javafx.geometry.Bounds; -import javafx.geometry.Orientation; -import javafx.scene.Node; -import javafx.scene.control.ListView; -import javafx.scene.control.ScrollBar; -import javafx.scene.control.TableView; -import javafx.scene.input.MouseEvent; -import javafx.scene.input.ScrollEvent; -import javafx.util.Duration; - -import java.util.function.Function; - -public class SmoothScroll { - - private static ScrollBar getScrollbarComponent(Node no, Orientation orientation) { - Node n = no.lookup(".scroll-bar"); - if (n instanceof final ScrollBar bar) { - if (bar.getOrientation().equals(orientation)) { - return bar; - } - } - - return null; - } - - public static void smoothScrollingListView(Node n, double speed) { - smoothScrollingListView(n, speed, Orientation.VERTICAL, bounds -> bounds.getHeight()); - } - - public static void smoothHScrollingListView(ListView listView, double speed) { - smoothScrollingListView(listView, speed, Orientation.HORIZONTAL, bounds -> bounds.getHeight()); - } - - private static void smoothScrollingListView( - Node n, double speed, Orientation orientation, Function sizeFunc) { - ((TableView) n).skinProperty().addListener((observable, oldValue, newValue) -> { - if (newValue != null) { - ScrollBar scrollBar = getScrollbarComponent(n, orientation); - if (scrollBar == null) { - return; - } - scrollBar.setUnitIncrement(1); - final double[] frictions = { - 0.99, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.04, 0.01, 0.008, 0.008, 0.008, 0.008, 0.0006, 0.0005, - 0.00003, 0.00001 - }; - final double[] pushes = {speed}; - final double[] derivatives = new double[frictions.length]; - final double[] lastVPos = {0}; - Timeline timeline = new Timeline(); - final EventHandler dragHandler = event -> timeline.stop(); - final EventHandler scrollHandler = event -> { - scrollBar.valueProperty().set(lastVPos[0]); - if (event.getEventType() == ScrollEvent.SCROLL) { - double direction = event.getDeltaY() > 0 ? -1 : 1; - for (int i = 0; i < pushes.length; i++) { - derivatives[i] += direction * pushes[i]; - } - if (timeline.getStatus() == Animation.Status.STOPPED) { - timeline.play(); - } - } - event.consume(); - }; - if (scrollBar.getParent() != null) { - scrollBar.getParent().addEventHandler(MouseEvent.DRAG_DETECTED, dragHandler); - scrollBar.getParent().addEventHandler(ScrollEvent.ANY, scrollHandler); - } - scrollBar.parentProperty().addListener((o, oldVal, newVal) -> { - if (oldVal != null) { - oldVal.removeEventHandler(MouseEvent.DRAG_DETECTED, dragHandler); - oldVal.removeEventHandler(ScrollEvent.ANY, scrollHandler); - } - if (newVal != null) { - newVal.addEventHandler(MouseEvent.DRAG_DETECTED, dragHandler); - newVal.addEventHandler(ScrollEvent.ANY, scrollHandler); - } - }); - - timeline.getKeyFrames().add(new KeyFrame(Duration.millis(3), (event) -> { - for (int i = 0; i < derivatives.length; i++) { - derivatives[i] *= frictions[i]; - } - for (int i = 1; i < derivatives.length; i++) { - derivatives[i] += derivatives[i - 1]; - } - double dy = derivatives[derivatives.length - 1]; - double size = sizeFunc.apply(scrollBar.getLayoutBounds()); - scrollBar.valueProperty().set(Math.min(Math.max(scrollBar.getValue() + dy / size, 0), 1)); - lastVPos[0] = scrollBar.getValue(); - if (Math.abs(dy) < 1) { - if (Math.abs(dy) < 0.001) { - timeline.stop(); - } - } - })); - timeline.setCycleCount(Animation.INDEFINITE); - } - }); - } -} \ No newline at end of file diff --git a/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java b/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java index 718f72be6..fd7b5f112 100644 --- a/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java +++ b/core/src/main/java/io/xpipe/core/process/ProcessControlProvider.java @@ -33,4 +33,8 @@ public abstract class ProcessControlProvider { public abstract ShellControl createLocalProcessControl(boolean stoppable); public abstract Object createStorageHandler(); + + public abstract ShellDialect getEffectiveLocalDialect(); + + public abstract ShellDialect getFallbackDialect(); } 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 480ebdb68..65b45c245 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellControl.java +++ b/core/src/main/java/io/xpipe/core/process/ShellControl.java @@ -236,10 +236,6 @@ public interface ShellControl extends ProcessControl { }); } - default CommandControl command(List command) { - return command(shellProcessControl -> ShellDialect.flatten(command)); - } - default CommandControl command(CommandBuilder builder) { return command(shellProcessControl -> builder.buildString(shellProcessControl)); } diff --git a/core/src/main/java/io/xpipe/core/process/ShellDialect.java b/core/src/main/java/io/xpipe/core/process/ShellDialect.java index cd9d9b8f8..304dcaf8f 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellDialect.java +++ b/core/src/main/java/io/xpipe/core/process/ShellDialect.java @@ -10,24 +10,11 @@ import java.io.IOException; import java.nio.charset.Charset; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import java.util.stream.Stream; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") public interface ShellDialect { - static String flatten(List command) { - return command.stream() - .map(s -> s.contains(" ") - && !(s.startsWith("\"") && s.endsWith("\"")) - && !(s.startsWith("'") && s.endsWith("'")) - ? "\"" + s + "\"" - : s) - .collect(Collectors.joining(" ")); - } - - String getExecutableName(); - default boolean isSupportedShell() { return true; } @@ -44,6 +31,8 @@ public interface ShellDialect { return this; } + String getExecutableName(); + String getCatchAllVariable(); String queryVersion(ShellControl shellControl) throws Exception; diff --git a/core/src/main/java/io/xpipe/core/process/ShellDialects.java b/core/src/main/java/io/xpipe/core/process/ShellDialects.java index 1cf9fbd4c..4b207f012 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellDialects.java +++ b/core/src/main/java/io/xpipe/core/process/ShellDialects.java @@ -4,6 +4,7 @@ import io.xpipe.core.util.ModuleLayerLoader; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.ServiceLoader; public class ShellDialects { @@ -71,15 +72,19 @@ public class ShellDialects { .filter(shellType -> shellType.getId().equals(name)) .findFirst() .orElseThrow(); + } + + public static boolean isPowershell(ShellControl sc) { + return sc.getShellDialect().equals(POWERSHELL) || sc.getShellDialect().equals(POWERSHELL_CORE); } - public static ShellDialect getPlatformDefault() { - if (OsType.getLocal().equals(OsType.WINDOWS)) { - return CMD; - } else if (OsType.getLocal().equals(OsType.LINUX)) { - return BASH; - } else { - return ZSH; - } + public static ShellDialect byName(String name) { + return byNameIfPresent(name).orElseThrow(); + } + + public static Optional byNameIfPresent(String name) { + return ALL.stream() + .filter(shellType -> shellType.getId().equals(name)) + .findFirst(); } } diff --git a/core/src/main/java/io/xpipe/core/process/ShellProperties.java b/core/src/main/java/io/xpipe/core/process/ShellProperties.java index b8df6d34d..db1313082 100644 --- a/core/src/main/java/io/xpipe/core/process/ShellProperties.java +++ b/core/src/main/java/io/xpipe/core/process/ShellProperties.java @@ -1,10 +1,19 @@ package io.xpipe.core.process; +import lombok.AllArgsConstructor; import lombok.Value; @Value +@AllArgsConstructor public class ShellProperties { + public ShellProperties(ShellDialect dialect, boolean ansiEscapes) { + this.dialect = dialect; + this.ansiEscapes = ansiEscapes; + this.supported = true; + } + ShellDialect dialect; boolean ansiEscapes; + boolean supported; } diff --git a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java index 7f351ba98..b385263ef 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java @@ -10,7 +10,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; -import java.util.List; import java.util.Optional; public class XPipeInstallation { @@ -212,7 +211,7 @@ public class XPipeInstallation { } public static String queryInstallationVersion(ShellControl p, String exec) throws Exception { - try (CommandControl c = p.command(List.of(exec, "version")).start()) { + try (CommandControl c = p.command(CommandBuilder.of().addFile(exec).add("version")).start()) { return c.readStdoutOrThrow(); } catch (ProcessOutputException ex) { return "?";