From c0abdf968ac61629730e1e5fe787bec6a221c8bf Mon Sep 17 00:00:00 2001 From: crschnick Date: Fri, 3 Feb 2023 13:56:11 +0000 Subject: [PATCH] Rework external application handling --- .../app/prefs/ExternalApplicationType.java | 100 ++++++++++++ .../xpipe/app/prefs/ExternalEditorType.java | 152 +++++------------- .../java/io/xpipe/ext/proc/TerminalType.java | 62 ++++++- 3 files changed, 196 insertions(+), 118 deletions(-) create mode 100644 app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java new file mode 100644 index 00000000..9b9d53d8 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java @@ -0,0 +1,100 @@ +package io.xpipe.app.prefs; + +import io.xpipe.core.process.OsType; +import io.xpipe.core.process.ShellProcessControl; +import io.xpipe.core.store.ShellStore; +import io.xpipe.extension.event.ErrorEvent; +import io.xpipe.extension.prefs.PrefsChoiceValue; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + +public abstract class ExternalApplicationType implements PrefsChoiceValue { + + private final String id; + + public ExternalApplicationType(String id) { + this.id = id; + } + + @Override + public String getId() { + return id; + } + + public abstract boolean isSelectable(); + + public abstract boolean isAvailable(); + + public static class MacApplication extends ExternalApplicationType { + + protected final String applicationName; + + public MacApplication(String id, String applicationName) { + super(id); + this.applicationName = applicationName; + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.MAC); + } + + @Override + public boolean isAvailable() { + try { + return ShellStore.local() + .create() + .executeBooleanSimpleCommand(String.format("mdfind -name '%s.app'", applicationName)); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + return false; + } + } + } + + public static class LinuxPathApplication extends ExternalApplicationType { + + protected final String command; + + public LinuxPathApplication(String id, String command) { + super(id); + this.command = command; + } + + public boolean isAvailable() { + try (ShellProcessControl pc = ShellStore.local().create().start()) { + return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(command)); + } catch (Exception e) { + ErrorEvent.fromThrowable(e).omit().handle(); + return false; + } + } + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.LINUX); + } + } + + public abstract static class WindowsFullPathType extends ExternalApplicationType { + + public WindowsFullPathType(String id) { + super(id); + } + + protected abstract Optional determinePath(); + + @Override + public boolean isSelectable() { + return OsType.getLocal().equals(OsType.WINDOWS); + } + + @Override + public boolean isAvailable() { + var path = determinePath(); + return path.isPresent() && Files.exists(path.get()); + } + } +} diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java index 06cb8901..93488551 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalEditorType.java @@ -1,27 +1,20 @@ package io.xpipe.app.prefs; import io.xpipe.core.process.OsType; -import io.xpipe.core.process.ShellProcessControl; import io.xpipe.core.process.ShellTypes; -import io.xpipe.core.store.ShellStore; -import io.xpipe.extension.event.ErrorEvent; import io.xpipe.extension.prefs.PrefsChoiceValue; import io.xpipe.extension.util.ApplicationHelper; import io.xpipe.extension.util.WindowsRegistry; -import lombok.AllArgsConstructor; -import lombok.Getter; import org.apache.commons.lang3.SystemUtils; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.function.Supplier; -@Getter -@AllArgsConstructor -public abstract class ExternalEditorType implements PrefsChoiceValue { +public interface ExternalEditorType extends PrefsChoiceValue { public static final ExternalEditorType NOTEPAD = new WindowsFullPathType("app.notepad") { @Override @@ -56,49 +49,39 @@ public abstract class ExternalEditorType implements PrefsChoiceValue { } }; - public static final PathType NOTEPADPLUSPLUS_LINUX = new PathType("app.notepad++", "notepad++"); + public static final LinuxPathType NOTEPADPLUSPLUS_LINUX = new LinuxPathType("app.notepad++", "notepad++"); - public static final PathType VSCODE_LINUX = new PathType("app.vscode", "code"); + public static final LinuxPathType VSCODE_LINUX = new LinuxPathType("app.vscode", "code"); - public static final PathType KATE = new PathType("app.kate", "kate"); + public static final LinuxPathType KATE = new LinuxPathType("app.kate", "kate"); - public static final PathType GEDIT = new PathType("app.gedit", "gedit"); + public static final LinuxPathType GEDIT = new LinuxPathType("app.gedit", "gedit"); - public static final PathType LEAFPAD = new PathType("app.leafpad", "leafpad"); + public static final LinuxPathType LEAFPAD = new LinuxPathType("app.leafpad", "leafpad"); - public static final PathType MOUSEPAD = new PathType("app.mousepad", "mousepad"); + public static final LinuxPathType MOUSEPAD = new LinuxPathType("app.mousepad", "mousepad"); - public static final PathType PLUMA = new PathType("app.pluma", "pluma"); + public static final LinuxPathType PLUMA = new LinuxPathType("app.pluma", "pluma"); - public static final ExternalEditorType TEXT_EDIT = new MacOsFullPathType("app.textEdit") { - @Override - protected Path determinePath() { - return Path.of("/System/Applications/TextEdit.app"); + class MacOsEditor extends ExternalApplicationType.MacApplication implements ExternalEditorType { + + public MacOsEditor(String id, String applicationName) { + super(id, applicationName); } - }; - public static final ExternalEditorType NOTEPADPP_MACOS = new MacOsFullPathType("app.notepad++") { @Override - protected Path determinePath() { - return Path.of("/Applications/Notepad++.app"); + public void launch(Path file) throws Exception { + ApplicationHelper.executeLocalApplication(List.of("open", "-a", applicationName, file.toString())); } - }; + } - public static final ExternalEditorType SUBLIME_MACOS = new MacOsFullPathType("app.sublime") { - @Override - protected Path determinePath() { - return Path.of("/Applications/Sublime.app"); - } - }; + public static final ExternalEditorType TEXT_EDIT = new MacOsEditor("app.textEdit", "TextEdit"); - public static final ExternalEditorType VSCODE_MACOS = new MacOsFullPathType("app.vscode") { - @Override - protected Path determinePath() { - return Path.of("/Applications/VSCode.app"); - } - }; + public static final ExternalEditorType SUBLIME_MACOS = new MacOsEditor("app.sublime", "Sublime Text"); - public static final ExternalEditorType CUSTOM = new ExternalEditorType("app.custom") { + public static final ExternalEditorType VSCODE_MACOS = new MacOsEditor("app.vscode", "VSCode"); + + public static final ExternalEditorType CUSTOM = new ExternalEditorType() { @Override public void launch(Path file) throws Exception { @@ -116,21 +99,20 @@ public abstract class ExternalEditorType implements PrefsChoiceValue { public boolean isSelectable() { return true; } + + @Override + public String getId() { + return "app.custom"; + } }; - private String id; + public void launch(Path file) throws Exception; - public abstract void launch(Path file) throws Exception; - public abstract boolean isSelectable(); + public static class LinuxPathType extends ExternalApplicationType.LinuxPathApplication implements ExternalEditorType { - public static class PathType extends ExternalEditorType { - - private final String command; - - public PathType(String id, String command) { - super(id); - this.command = command; + public LinuxPathType(String id, String command) { + super(id, command); } @Override @@ -138,30 +120,14 @@ public abstract class ExternalEditorType implements PrefsChoiceValue { var list = ShellTypes.getPlatformDefault().executeCommandListWithShell(command + " \"" + file + "\""); new ProcessBuilder(list).start(); } - - public boolean isAvailable() { - try (ShellProcessControl pc = ShellStore.local().create().start()) { - return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(command)); - } catch (Exception e) { - ErrorEvent.fromThrowable(e).omit().handle(); - return false; - } - } - - @Override - public boolean isSelectable() { - return OsType.getLocal().equals(OsType.LINUX); - } } - public abstract static class WindowsFullPathType extends ExternalEditorType { + public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType implements ExternalEditorType { public WindowsFullPathType(String id) { super(id); } - protected abstract Optional determinePath(); - @Override public void launch(Path file) throws Exception { var path = determinePath(); @@ -171,64 +137,28 @@ public abstract class ExternalEditorType implements PrefsChoiceValue { ApplicationHelper.executeLocalApplication(List.of(path.get().toString(), file.toString())); } - - @Override - public boolean isSelectable() { - return OsType.getLocal().equals(OsType.WINDOWS); - } - - @Override - public boolean isAvailable() { - var path = determinePath(); - return path.isPresent() && Files.exists(path.get()); - } - } - - public abstract static class MacOsFullPathType extends ExternalEditorType { - - public MacOsFullPathType(String id) { - super(id); - } - - protected abstract Path determinePath(); - - @Override - public void launch(Path file) throws Exception { - var path = determinePath(); - ApplicationHelper.executeLocalApplication(List.of("open", path.toString(), file.toString())); - } - - @Override - public boolean isSelectable() { - return OsType.getLocal().equals(OsType.MAC); - } - - @Override - public boolean isAvailable() { - var path = determinePath(); - return Files.exists(path); - } } public static final List WINDOWS_EDITORS = List.of(VSCODE, NOTEPADPLUSPLUS_WINDOWS, NOTEPAD); - public static final List LINUX_EDITORS = + public static final List LINUX_EDITORS = List.of(VSCODE_LINUX, NOTEPADPLUSPLUS_LINUX, KATE, GEDIT, PLUMA, LEAFPAD, MOUSEPAD); public static final List MACOS_EDITORS = - List.of(VSCODE_MACOS, SUBLIME_MACOS, NOTEPADPP_MACOS, TEXT_EDIT); + List.of(VSCODE_MACOS, SUBLIME_MACOS, TEXT_EDIT); - public static final List ALL = new ArrayList<>(); - static { + public static final List ALL = ((Supplier>) () -> { + var all = new ArrayList(); if (OsType.getLocal().equals(OsType.WINDOWS)) { - ALL.addAll(WINDOWS_EDITORS); + all.addAll(WINDOWS_EDITORS); } if (OsType.getLocal().equals(OsType.LINUX)) { - ALL.addAll(LINUX_EDITORS); + all.addAll(LINUX_EDITORS); } if (OsType.getLocal().equals(OsType.MAC)) { - ALL.addAll(MACOS_EDITORS); + all.addAll(MACOS_EDITORS); } - ALL.add(CUSTOM); - } + all.add(CUSTOM); + return all; + }).get(); public static void detectDefault() { var typeProperty = AppPrefs.get().externalEditor; diff --git a/ext/proc/src/main/java/io/xpipe/ext/proc/TerminalType.java b/ext/proc/src/main/java/io/xpipe/ext/proc/TerminalType.java index 42213bf0..f86ddfe2 100644 --- a/ext/proc/src/main/java/io/xpipe/ext/proc/TerminalType.java +++ b/ext/proc/src/main/java/io/xpipe/ext/proc/TerminalType.java @@ -102,7 +102,7 @@ public abstract class TerminalType implements PrefsChoiceValue { public static final TerminalType ITERM2 = new ITerm2Type(); - public static final TerminalType WARP = new MacType("proc.warp", "Warp"); + public static final TerminalType WARP = new WarpType(); public static final TerminalType CUSTOM = new TerminalType("app.custom") { @@ -130,9 +130,15 @@ public abstract class TerminalType implements PrefsChoiceValue { }; public static final List ALL = List.of( - WINDOWS_TERMINAL, POWERSHELL, CMD, - KONSOLE, XFCE, GNOME_TERMINAL, - WARP, ITERM2, MACOS_TERMINAL, + WINDOWS_TERMINAL, + POWERSHELL, + CMD, + KONSOLE, + XFCE, + GNOME_TERMINAL, + WARP, + ITERM2, + MACOS_TERMINAL, CUSTOM) .stream() .filter(terminalType -> terminalType.isSelectable()) @@ -140,7 +146,9 @@ public abstract class TerminalType implements PrefsChoiceValue { public static TerminalType getDefault() { return ALL.stream() - .filter(terminalType -> terminalType.isAvailable()).findFirst().orElse(null); + .filter(terminalType -> terminalType.isAvailable()) + .findFirst() + .orElse(null); } private String id; @@ -189,7 +197,8 @@ public abstract class TerminalType implements PrefsChoiceValue { @Override public void launch(String name, String command) throws Exception { try (ShellProcessControl pc = ShellStore.local().create().start()) { - var cmd = String.format(""" + var cmd = String.format( + """ osascript - "$@" <