More shell rework

This commit is contained in:
crschnick 2023-03-19 19:38:29 +00:00
parent 11667d7876
commit 4bb7627488
21 changed files with 79 additions and 99 deletions

View file

@ -136,7 +136,7 @@ run {
systemProperty 'io.xpipe.app.writeLogs', "true" systemProperty 'io.xpipe.app.writeLogs', "true"
systemProperty 'io.xpipe.app.writeSysOut', "true" systemProperty 'io.xpipe.app.writeSysOut', "true"
systemProperty 'io.xpipe.app.developerMode', "true" systemProperty 'io.xpipe.app.developerMode', "true"
systemProperty 'io.xpipe.app.logLevel', "debug" systemProperty 'io.xpipe.app.logLevel', "trace"
systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion
// systemProperty "io.xpipe.beacon.port", "21724" // systemProperty "io.xpipe.beacon.port", "21724"
// systemProperty "io.xpipe.beacon.printMessages", "true" // systemProperty "io.xpipe.beacon.printMessages", "true"

View file

@ -209,7 +209,7 @@ public class FileBrowserComp extends SimpleComp {
? DataStorage.get() ? DataStorage.get()
.getStoreEntry(model.getStore().getValue()) .getStoreEntry(model.getStore().getValue())
.getProvider() .getProvider()
.getDisplayIconFileName() .getDisplayIconFileName(model.getStore().getValue())
: null; : null;
}, },
model.getStore()); model.getStore());

View file

@ -204,9 +204,9 @@ final class FileListComp extends AnchorPane {
} }
newItems.addAll(newValue); newItems.addAll(newValue);
table.getItems().setAll(newItems); table.getItems().setAll(newItems);
if (newValue.size() > 0) { // if (newValue.size() > 0) {
table.scrollTo(0); // table.scrollTo(0);
} // }
}); });
}); });

View file

@ -4,6 +4,7 @@ import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.impl.FileNames; import io.xpipe.core.impl.FileNames;
import io.xpipe.core.impl.LocalStore; import io.xpipe.core.impl.LocalStore;
import io.xpipe.core.process.OsType; import io.xpipe.core.process.OsType;
import io.xpipe.core.store.ConnectionFileSystem;
import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.FileSystem;
import java.nio.file.Files; import java.nio.file.Files;
@ -13,7 +14,25 @@ import java.util.List;
public class FileSystemHelper { public class FileSystemHelper {
public static String normalizeDirectoryPath(OpenFileSystemModel model, String path) { public static String getStartDirectory(OpenFileSystemModel model) throws Exception {
// Handle special case when file system creation has failed
if (model.getFileSystem() == null) {
return null;
}
ConnectionFileSystem fileSystem = (ConnectionFileSystem) model.getFileSystem();
var current = !(model.getStore().getValue() instanceof LocalStore)
? fileSystem
.getShellControl()
.executeStringSimpleCommand(fileSystem
.getShellControl()
.getShellDialect()
.getPrintWorkingDirectoryCommand())
: fileSystem.getShell().get().getOsType().getHomeDirectory(fileSystem.getShell().get());
return FileSystemHelper.normalizeDirectoryPath(model, current);
}
public static String normalizeDirectoryPath(OpenFileSystemModel model, String path) throws Exception {
if (path == null) { if (path == null) {
return null; return null;
} }
@ -37,7 +56,11 @@ public class FileSystemHelper {
return path + "\\"; return path + "\\";
} }
return FileNames.toDirectory(path); var normalized = shell.get()
.getShellDialect()
.normalizeDirectory(shell.get(), path)
.readOrThrow();
return FileNames.toDirectory(normalized);
} }
public static FileSystem.FileEntry getLocal(Path file) throws Exception { public static FileSystem.FileEntry getLocal(Path file) throws Exception {

View file

@ -7,7 +7,6 @@ import io.xpipe.app.util.BusyProperty;
import io.xpipe.app.util.TerminalHelper; import io.xpipe.app.util.TerminalHelper;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.impl.FileNames; import io.xpipe.core.impl.FileNames;
import io.xpipe.core.impl.LocalStore;
import io.xpipe.core.store.ConnectionFileSystem; import io.xpipe.core.store.ConnectionFileSystem;
import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.FileSystem;
import io.xpipe.core.store.FileSystemStore; import io.xpipe.core.store.FileSystemStore;
@ -76,7 +75,14 @@ final class OpenFileSystemModel {
} }
public Optional<String> cd(String path) { public Optional<String> cd(String path) {
var newPath = FileSystemHelper.normalizeDirectoryPath(this, path); String newPath = null;
try {
newPath = FileSystemHelper.normalizeDirectoryPath(this, path);
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).handle();
return Optional.of(currentPath.get());
}
if (!Objects.equals(path, newPath)) { if (!Objects.equals(path, newPath)) {
return Optional.of(newPath); return Optional.of(newPath);
} }
@ -96,7 +102,8 @@ final class OpenFileSystemModel {
this.fileSystem = fs; this.fileSystem = fs;
} }
path = FileSystemHelper.normalizeDirectoryPath(this, path); // Assumed that the path is normalized to improve performance!
// path = FileSystemHelper.normalizeDirectoryPath(this, path);
navigateToSync(path); navigateToSync(path);
filter.setValue(null); filter.setValue(null);
@ -218,14 +225,7 @@ final class OpenFileSystemModel {
fs.open(); fs.open();
this.fileSystem = fs; this.fileSystem = fs;
var current = !(fileSystem instanceof LocalStore) && fs instanceof ConnectionFileSystem connectionFileSystem var current = FileSystemHelper.getStartDirectory(this);
? connectionFileSystem
.getShellControl()
.executeStringSimpleCommand(connectionFileSystem
.getShellControl()
.getShellDialect()
.getPrintWorkingDirectoryCommand())
: null;
cdSync(current); cdSync(current);
} }

View file

@ -56,7 +56,7 @@ public class DataStoreSelectorComp extends Comp<CompStructure<Button>> {
? DataStoreProviders.byStoreClass(chosenStore.getValue().getClass()) ? DataStoreProviders.byStoreClass(chosenStore.getValue().getClass())
.orElse(null) .orElse(null)
: null; : null;
var graphic = provider != null ? provider.getDisplayIconFileName() : "file_icon.png"; var graphic = provider != null ? provider.getDisplayIconFileName(chosenStore.getValue()) : "file_icon.png";
if (chosenStore.getValue() == null || !(chosenStore.getValue() instanceof FileStore f)) { if (chosenStore.getValue() == null || !(chosenStore.getValue() instanceof FileStore f)) {
return JfxHelper.createNamedEntry( return JfxHelper.createNamedEntry(
AppI18n.get("selectStreamStore"), AppI18n.get("openStreamStoreWizard"), graphic); AppI18n.get("selectStreamStore"), AppI18n.get("openStreamStoreWizard"), graphic);

View file

@ -43,7 +43,7 @@ public class DsStoreProviderChoiceComp extends Comp<CompStructure<ComboBox<Node>
return createDefaultNode(); return createDefaultNode();
} }
var graphic = provider.getDisplayIconFileName(); var graphic = provider.getDisplayIconFileName(null);
return JfxHelper.createNamedEntry(provider.getDisplayName(), provider.getDisplayDescription(), graphic); return JfxHelper.createNamedEntry(provider.getDisplayName(), provider.getDisplayDescription(), graphic);
} }

View file

@ -125,7 +125,7 @@ public class NamedStoreChoiceComp extends SimpleComp implements Validatable {
var view = new ListViewComp<>(shown, list, prop, (DataStoreEntry e) -> { var view = new ListViewComp<>(shown, list, prop, (DataStoreEntry e) -> {
var provider = e.getProvider(); var provider = e.getProvider();
var graphic = provider.getDisplayIconFileName(); var graphic = provider.getDisplayIconFileName(e.getStore());
var top = String.format("%s (%s)", e.getName(), provider.getDisplayName()); var top = String.format("%s (%s)", e.getName(), provider.getDisplayName());
var bottom = provider.toSummaryString(e.getStore(), 50); var bottom = provider.toSummaryString(e.getStore(), 50);
var el = JfxHelper.createNamedEntry(top, bottom, graphic); var el = JfxHelper.createNamedEntry(top, bottom, graphic);

View file

@ -98,7 +98,7 @@ public class StoreEntryComp extends SimpleComp {
private Node createIcon() { private Node createIcon() {
var img = entry.isDisabled() var img = entry.isDisabled()
? "disabled_icon.png" ? "disabled_icon.png"
: entry.getEntry().getProvider().getDisplayIconFileName(); : entry.getEntry().getProvider().getDisplayIconFileName(entry.getEntry().getStore());
var imageComp = new PrettyImageComp(new SimpleStringProperty(img), 55, 45); var imageComp = new PrettyImageComp(new SimpleStringProperty(img), 55, 45);
var storeIcon = imageComp.createRegion(); var storeIcon = imageComp.createRegion();
storeIcon.getStyleClass().add("icon"); storeIcon.getStyleClass().add("icon");

View file

@ -41,7 +41,9 @@ public class StoreEntryFlatMiniSection extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var image = entry.getState() == DataStoreEntry.State.LOAD_FAILED ? "disabled_icon.png" : entry.getProvider().getDisplayIconFileName(); var image = entry.getState() == DataStoreEntry.State.LOAD_FAILED
? "disabled_icon.png"
: entry.getProvider().getDisplayIconFileName(entry.getStore());
var label = new Label(entry.getName(), new PrettyImageComp(new SimpleStringProperty(image), 20, 20).createRegion()); var label = new Label(entry.getName(), new PrettyImageComp(new SimpleStringProperty(image), 20, 20).createRegion());
var spacer = new Spacer(depth * 10, Orientation.HORIZONTAL); var spacer = new Spacer(depth * 10, Orientation.HORIZONTAL);
var box = new HBox(spacer, label); var box = new HBox(spacer, label);

View file

@ -100,7 +100,7 @@ public interface DataStoreProvider {
return i != -1 ? n.substring(i + 1) : n; return i != -1 ? n.substring(i + 1) : n;
} }
default String getDisplayIconFileName() { default String getDisplayIconFileName(DataStore store) {
return getModuleName() + ":" + getId() + "_icon.png"; return getModuleName() + ":" + getId() + "_icon.png";
} }

View file

@ -34,13 +34,13 @@ public class FileSystemStoreChoiceComp extends SimpleComp {
private Region createGraphic(FileSystemStore s) { private Region createGraphic(FileSystemStore s) {
var provider = DataStoreProviders.byStore(s); var provider = DataStoreProviders.byStore(s);
var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName()), 16, 16); var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName(s)), 16, 16);
return new Label(getName(s), img.createRegion()); return new Label(getName(s), img.createRegion());
} }
private Region createDisplayGraphic(FileSystemStore s) { private Region createDisplayGraphic(FileSystemStore s) {
var provider = DataStoreProviders.byStore(s); var provider = DataStoreProviders.byStore(s);
var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName()), 16, 16); var img = new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName(s)), 16, 16);
return new Label(null, img.createRegion()); return new Label(null, img.createRegion());
} }

View file

@ -54,7 +54,7 @@ public class ShellStoreChoiceComp<T extends ShellStore> extends SimpleComp {
protected Region createGraphic(T s) { protected Region createGraphic(T s) {
var provider = DataStoreProviders.byStore(s); var provider = DataStoreProviders.byStore(s);
var imgView = var imgView =
new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName()), 16, 16).createRegion(); new PrettyImageComp(new SimpleStringProperty(provider.getDisplayIconFileName(s)), 16, 16).createRegion();
var name = DataStorage.get().getUsableStores().stream() var name = DataStorage.get().getUsableStores().stream()
.filter(e -> e.equals(s)) .filter(e -> e.equals(s))

View file

@ -3,6 +3,9 @@ package io.xpipe.core.charsetter;
import io.xpipe.core.util.Identifiers; import io.xpipe.core.util.Identifiers;
import lombok.Value; import lombok.Value;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
@ -117,6 +120,17 @@ public class StreamCharset {
byte[] byteOrderMark; byte[] byteOrderMark;
List<String> names; List<String> names;
public Reader reader(InputStream stream) throws Exception {
if (hasByteOrderMark()) {
var bom = stream.readNBytes(getByteOrderMark().length);
if (bom.length != 0 && !Arrays.equals(bom, getByteOrderMark())) {
throw new IllegalStateException("Charset does not match: " + charset.toString());
}
}
return new InputStreamReader(stream, charset);
}
public static StreamCharset get(Charset charset, boolean byteOrderMark) { public static StreamCharset get(Charset charset, boolean byteOrderMark) {
return ALL.stream() return ALL.stream()
.filter(streamCharset -> .filter(streamCharset ->

View file

@ -9,6 +9,8 @@ import java.util.concurrent.ExecutorService;
public interface ProcessControl extends Closeable, AutoCloseable { public interface ProcessControl extends Closeable, AutoCloseable {
void resetData();
ExecutorService getStdoutReader(); ExecutorService getStdoutReader();
ExecutorService getStderrReader(); ExecutorService getStderrReader();

View file

@ -2,6 +2,7 @@ package io.xpipe.core.process;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.xpipe.core.charsetter.NewLine; import io.xpipe.core.charsetter.NewLine;
import io.xpipe.core.charsetter.StreamCharset;
import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.FileSystem;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -13,6 +14,12 @@ import java.util.stream.Stream;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface ShellDialect { public interface ShellDialect {
default StreamCharset getTextFileCharset(ShellControl sc) {
return StreamCharset.get(sc.getCharset(), false);
}
CommandControl normalizeDirectory(ShellControl shellControl, String directory);
String fileArgument(String s); String fileArgument(String s);
default String applyRcFileCommand() { default String applyRcFileCommand() {
@ -91,6 +98,10 @@ public interface ShellDialect {
String prepareInitFileOpenCommand(ShellControl parent, String file); String prepareInitFileOpenCommand(ShellControl parent, String file);
String runScript(String file);
String sourceScript(String file);
String executeCommandWithShell(String cmd); String executeCommandWithShell(String cmd);
String getMkdirsCommand(String dirs); String getMkdirsCommand(String dirs);

View file

@ -1,71 +0,0 @@
package io.xpipe.ext.base;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.StorageElement;
import io.xpipe.core.impl.LocalStore;
import io.xpipe.core.process.OsType;
import io.xpipe.core.store.DataStore;
import java.util.List;
import java.util.UUID;
public class LocalStoreProvider implements DataStoreProvider {
@Override
public String queryInformationString(DataStore store, int length) throws Exception {
try (var pc = LocalStore.getShell().start()) {
return OsType.getLocal().determineOperatingSystemName(pc);
}
}
@Override
public String toSummaryString(DataStore store, int length) {
return "localhost";
}
@Override
public boolean shouldShow() {
return false;
}
@Override
public void storageInit() throws Exception {
var hasLocal = DataStorage.get().getUsableStores().stream()
.anyMatch(dataStore -> dataStore instanceof LocalStore);
if (hasLocal) {
return;
}
var e = DataStoreEntry.createNew(UUID.randomUUID(), "Local Machine", new LocalStore());
DataStorage.get().addStoreEntry(e);
e.setConfiguration(StorageElement.Configuration.builder()
.deletable(false)
.editable(false)
.refreshable(true)
.renameable(false)
.build());
e.refresh(true);
}
@Override
public DataStore defaultStore() {
return new LocalStore();
}
@Override
public String getDisplayName() {
return null;
}
@Override
public List<String> getPossibleNames() {
return List.of("local", "localhost");
}
@Override
public List<Class<?>> getStoreClasses() {
return List.of(LocalStore.class);
}
}

View file

@ -44,7 +44,6 @@ open module io.xpipe.ext.base {
provides DataStoreProvider with provides DataStoreProvider with
SinkDrainStoreProvider, SinkDrainStoreProvider,
HttpStoreProvider, HttpStoreProvider,
LocalStoreProvider,
InternalStreamProvider, InternalStreamProvider,
FileStoreProvider, FileStoreProvider,
InMemoryStoreProvider; InMemoryStoreProvider;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB