Compare commits
1 Commits
main
...
f463970b6b
Author | SHA1 | Date | |
---|---|---|---|
f463970b6b |
@@ -1,10 +1 @@
|
|||||||
# Newton
|
# Newton
|
||||||
|
|
||||||
# Additional Tools
|
|
||||||
* [Fzf](https://github.com/junegunn/fzf)
|
|
||||||
* [bat (cat but has highlighting)](https://github.com/sharkdp/bat)
|
|
||||||
* [ripgrep (very fast grep alternative)](https://github.com/BurntSushi/ripgrep/tree/master)
|
|
||||||
|
|
||||||
`
|
|
||||||
sudo pacman -Sy bat ripgrep fzf
|
|
||||||
`
|
|
@@ -5,7 +5,6 @@ const { menu } = require('./menu');
|
|||||||
const { systemTray } = require('./system-tray');
|
const { systemTray } = require('./system-tray');
|
||||||
const { argsParser } = require('./args-parser');
|
const { argsParser } = require('./args-parser');
|
||||||
const { settingsManager } = require('./settings-manager');
|
const { settingsManager } = require('./settings-manager');
|
||||||
const { terminal } = require('./terminal');
|
|
||||||
const { newtonFs } = require('./fs');
|
const { newtonFs } = require('./fs');
|
||||||
const { newtonIPC } = require('./ipc');
|
const { newtonIPC } = require('./ipc');
|
||||||
|
|
||||||
@@ -56,7 +55,6 @@ const createWindow = (startType = "build", debug = false, args = []) => {
|
|||||||
|
|
||||||
menu.load(window);
|
menu.load(window);
|
||||||
systemTray.load(menu.menuStruct);
|
systemTray.load(menu.menuStruct);
|
||||||
terminal.load(window);
|
|
||||||
|
|
||||||
// window.setAutoHideMenuBar(true)
|
// window.setAutoHideMenuBar(true)
|
||||||
|
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
const { app } = require('electron');
|
const { app } = require('electron');
|
||||||
|
|
||||||
|
|
||||||
let startType = "build";
|
let startType = "build";
|
||||||
let ipcPort = "4563";
|
let isDebug = false;
|
||||||
let isDebug = false;
|
let args = [];
|
||||||
let args = [];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -18,13 +17,6 @@ const loadKWArgs = () => {
|
|||||||
console.log(startType);
|
console.log(startType);
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasIpcPort = app.commandLine.hasSwitch("ipc-port");
|
|
||||||
if (hasIpcPort) {
|
|
||||||
ipcPort = app.commandLine.getSwitchValue("ipc-port");
|
|
||||||
console.log("Has ipc-port switch...");
|
|
||||||
console.log(ipcPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasDebug = app.commandLine.hasSwitch("app-debug");
|
const hasDebug = app.commandLine.hasSwitch("app-debug");
|
||||||
if (hasDebug) {
|
if (hasDebug) {
|
||||||
isDebug = app.commandLine.getSwitchValue("app-debug");
|
isDebug = app.commandLine.getSwitchValue("app-debug");
|
||||||
@@ -33,29 +25,38 @@ const loadKWArgs = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterOutLaunchAndKWArgs = () => {
|
const loadVArgs = () => {
|
||||||
|
console.log("\n\nStart VArgs:");
|
||||||
|
|
||||||
if (
|
if (
|
||||||
process.argv[0].endsWith("electron")
|
process.argv[0].endsWith("electron")
|
||||||
) {
|
) {
|
||||||
process.argv = process.argv.slice(2);
|
process.argv = process.argv.slice(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
if (
|
||||||
|
process.argv[0].endsWith("/newton") ||
|
||||||
|
process.argv[0].endsWith(".AppImage")
|
||||||
|
) {
|
||||||
process.argv = process.argv.slice(1);
|
process.argv = process.argv.slice(1);
|
||||||
} while (
|
}
|
||||||
process.argv.length > 0 &&
|
|
||||||
(
|
if ( process.argv.length > 0 && (
|
||||||
process.argv[0].endsWith("/newton") ||
|
process.argv[0].includes("--trace-warnings") ||
|
||||||
process.argv[0].endsWith(".AppImage") ||
|
process.argv[0].includes("--start-as")
|
||||||
process.argv[0].includes("--trace-warnings") ||
|
)
|
||||||
process.argv[0].includes("--start-as") ||
|
) {
|
||||||
process.argv[0].includes("--ipc-port")
|
process.argv = process.argv.slice(1);
|
||||||
)
|
}
|
||||||
);
|
|
||||||
}
|
if ( process.argv.length > 0 && (
|
||||||
|
process.argv[0].includes("--trace-warnings") ||
|
||||||
|
process.argv[0].includes("--start-as")
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
process.argv = process.argv.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
const loadVArgs = () => {
|
|
||||||
console.log("\n\nStart VArgs:");
|
|
||||||
args = process.argv;
|
args = process.argv;
|
||||||
args.forEach((val, index, array) => {
|
args.forEach((val, index, array) => {
|
||||||
console.log(index + ': ' + val);
|
console.log(index + ': ' + val);
|
||||||
@@ -66,7 +67,6 @@ const loadVArgs = () => {
|
|||||||
|
|
||||||
const loadArgs = () => {
|
const loadArgs = () => {
|
||||||
loadKWArgs();
|
loadKWArgs();
|
||||||
filterOutLaunchAndKWArgs();
|
|
||||||
loadVArgs();
|
loadVArgs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,10 +83,6 @@ const getDebugMode = () => {
|
|||||||
return isDebug;
|
return isDebug;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getIpcPort = () => {
|
|
||||||
return ipcPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
argsParser: {
|
argsParser: {
|
||||||
@@ -94,6 +90,5 @@ module.exports = {
|
|||||||
getArgs: getArgs,
|
getArgs: getArgs,
|
||||||
getStartType: getStartType,
|
getStartType: getStartType,
|
||||||
getDebugMode: getDebugMode,
|
getDebugMode: getDebugMode,
|
||||||
getIpcPort: getIpcPort,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
@@ -114,6 +114,7 @@ const chooseFolder = () => {
|
|||||||
console.debug("Canceled folder selection...");
|
console.debug("Canceled folder selection...");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
console.log(response)
|
||||||
|
|
||||||
return response.filePaths[0];
|
return response.filePaths[0];
|
||||||
});
|
});
|
||||||
|
@@ -8,17 +8,12 @@ const fetch = require('electron-fetch').default
|
|||||||
const IPC_SERVER_IP = "127.0.0.1";
|
const IPC_SERVER_IP = "127.0.0.1";
|
||||||
let window = null;
|
let window = null;
|
||||||
let ipcServer = null;
|
let ipcServer = null;
|
||||||
let ipcServerPort = "";
|
let ipcServerPort = "4563";
|
||||||
let ipcServerURL = "";
|
let ipcServerURL = `http://${IPC_SERVER_IP}:${ipcServerPort}`;
|
||||||
|
|
||||||
|
|
||||||
const setWindow = (win) => {
|
const setWindow = (win) => {
|
||||||
window = win;
|
window = win;
|
||||||
}
|
|
||||||
|
|
||||||
const configure = (ipcPort) => {
|
|
||||||
ipcServerPort = ipcPort;
|
|
||||||
ipcServerURL = `http://${IPC_SERVER_IP}:${ipcServerPort}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadIPCServer = (fpath) => {
|
const loadIPCServer = (fpath) => {
|
||||||
@@ -52,8 +47,7 @@ const loadIPCServer = (fpath) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isIPCServerUp = async () => {
|
const isIPCServerUp = async () => {
|
||||||
const response = await fetch(`${ipcServerURL}/is-up`)
|
const response = await fetch(`${ipcServerURL}/is-up`).catch((err) => {
|
||||||
.catch((err) => {
|
|
||||||
console.debug("IPCServer (status) : Not up; okay to start.");
|
console.debug("IPCServer (status) : Not up; okay to start.");
|
||||||
return {
|
return {
|
||||||
text: () => {
|
text: () => {
|
||||||
@@ -79,10 +73,9 @@ const sendFilesToIPC = async (files) => {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
newtonIPC: {
|
newtonIPC: {
|
||||||
configure: configure,
|
setWindow: setWindow,
|
||||||
loadIPCServer: loadIPCServer,
|
loadIPCServer: loadIPCServer,
|
||||||
isIPCServerUp: isIPCServerUp,
|
isIPCServerUp: isIPCServerUp,
|
||||||
sendFilesToIPC: sendFilesToIPC,
|
sendFilesToIPC: sendFilesToIPC,
|
||||||
setWindow: setWindow
|
|
||||||
}
|
}
|
||||||
};
|
};
|
@@ -80,7 +80,6 @@ app.whenReady().then(async () => {
|
|||||||
loadProcessSignalHandlers();
|
loadProcessSignalHandlers();
|
||||||
newton.args.loadArgs();
|
newton.args.loadArgs();
|
||||||
|
|
||||||
newton.ipc.configure( newton.args.getIpcPort() );
|
|
||||||
if ( !await newton.ipc.isIPCServerUp() ) {
|
if ( !await newton.ipc.isIPCServerUp() ) {
|
||||||
newton.ipc.loadIPCServer();
|
newton.ipc.loadIPCServer();
|
||||||
} else {
|
} else {
|
||||||
|
@@ -22,9 +22,6 @@ const load = (win) => {
|
|||||||
}, {
|
}, {
|
||||||
label: 'Terminal',
|
label: 'Terminal',
|
||||||
click: () => {}
|
click: () => {}
|
||||||
}, {
|
|
||||||
label: "Quit",
|
|
||||||
click: () => win.webContents.send('menu-actions', "quit")
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
|
@@ -9,7 +9,6 @@ contextBridge.exposeInMainWorld('electron', {
|
|||||||
|
|
||||||
contextBridge.exposeInMainWorld('main', {
|
contextBridge.exposeInMainWorld('main', {
|
||||||
onMenuActions: (callback) => ipcRenderer.on('menu-actions', (_event, action) => callback(action)),
|
onMenuActions: (callback) => ipcRenderer.on('menu-actions', (_event, action) => callback(action)),
|
||||||
onTerminalActions: (callback) => ipcRenderer.on('terminal-actions', (_event, action) => callback(action)),
|
|
||||||
quit: () => ipcRenderer.invoke("quit"),
|
quit: () => ipcRenderer.invoke("quit"),
|
||||||
toggleFullScreen: () => ipcRenderer.invoke("toggleFullScreen"),
|
toggleFullScreen: () => ipcRenderer.invoke("toggleFullScreen"),
|
||||||
});
|
});
|
||||||
|
@@ -33,9 +33,6 @@ const load = (win) => {
|
|||||||
}, {
|
}, {
|
||||||
label: 'Help',
|
label: 'Help',
|
||||||
click: () => win.webContents.send('menu-actions', "show-about")
|
click: () => win.webContents.send('menu-actions', "show-about")
|
||||||
}, {
|
|
||||||
label: 'Quit',
|
|
||||||
click: () => win.webContents.send('menu-actions', "quit")
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
|
|
||||||
const { ipcMain } = require('electron');
|
|
||||||
// const pty = require('node-pty');
|
|
||||||
const os = require("os");
|
|
||||||
|
|
||||||
|
|
||||||
const shell = "win32" === os.platform() ? "powershell.exe" : "bash";
|
|
||||||
|
|
||||||
|
|
||||||
const load = (win) => {
|
|
||||||
// const ptyProcess = pty.spawn(shell, [], {
|
|
||||||
// name: "xterm-color",
|
|
||||||
// cols: 172,
|
|
||||||
// rows: 256,
|
|
||||||
// cwd: process.env.HOME,
|
|
||||||
// env: process.env
|
|
||||||
// });
|
|
||||||
|
|
||||||
// ptyProcess.on('data', function(data) {
|
|
||||||
// win.webContents.send("terminal-actions", data);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// ipcMain.on("terminal-keystroke", (event, key) => {
|
|
||||||
// ptyProcess.write(key);
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
terminal: {
|
|
||||||
load: load
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
29
package.json
29
package.json
@@ -9,8 +9,8 @@
|
|||||||
"main": "newton/main.js",
|
"main": "newton/main.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"app": "ng build --base-href ./ && electron . --trace-warnings --start-as=build --ipc-port=4588",
|
"app": "ng build --base-href ./ && electron . --trace-warnings --start-as=build",
|
||||||
"electron-start": "electron . --trace-warnings --start-as=build --ipc-port=4588",
|
"electron-start": "electron . --trace-warnings --start-as=build",
|
||||||
"electron-pack": "ng build --base-href ./ && electron-builder --dir",
|
"electron-pack": "ng build --base-href ./ && electron-builder --dir",
|
||||||
"electron-dist": "ng build --base-href ./ && electron-builder",
|
"electron-dist": "ng build --base-href ./ && electron-builder",
|
||||||
"electron-dist-linux": "ng build --base-href ./ && electron-builder --linux deb zip AppImage",
|
"electron-dist-linux": "ng build --base-href ./ && electron-builder --linux deb zip AppImage",
|
||||||
@@ -51,18 +51,15 @@
|
|||||||
"@angular/core": "19.2.0",
|
"@angular/core": "19.2.0",
|
||||||
"@angular/forms": "19.2.0",
|
"@angular/forms": "19.2.0",
|
||||||
"@angular/platform-browser": "19.2.0",
|
"@angular/platform-browser": "19.2.0",
|
||||||
"@xterm/xterm": "5.5.0",
|
|
||||||
"ace-builds": "1.43.0",
|
"ace-builds": "1.43.0",
|
||||||
"ace-diff": "3.0.3",
|
"ace-diff": "3.0.3",
|
||||||
"ace-layout": "1.5.0",
|
"ace-linters": "1.7.0",
|
||||||
"ace-linters": "1.8.3",
|
|
||||||
"bootstrap": "5.3.6",
|
"bootstrap": "5.3.6",
|
||||||
"bootstrap-icons": "1.12.1",
|
"bootstrap-icons": "1.12.1",
|
||||||
"chokidar": "4.0.3",
|
"chokidar": "4.0.3",
|
||||||
"electron-fetch": "1.9.1",
|
"electron-fetch": "1.9.1",
|
||||||
"express": "4.18.2",
|
"express": "4.18.2",
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
"node-pty": "^1.0.0",
|
|
||||||
"rxjs": "7.8.0",
|
"rxjs": "7.8.0",
|
||||||
"socket.io": "4.8.1",
|
"socket.io": "4.8.1",
|
||||||
"uuid": "11.1.0",
|
"uuid": "11.1.0",
|
||||||
@@ -84,26 +81,6 @@
|
|||||||
"karma-coverage": "2.2.0",
|
"karma-coverage": "2.2.0",
|
||||||
"karma-jasmine": "5.1.0",
|
"karma-jasmine": "5.1.0",
|
||||||
"karma-jasmine-html-reporter": "2.1.0",
|
"karma-jasmine-html-reporter": "2.1.0",
|
||||||
"tree-sitter": "0.21.1",
|
|
||||||
"tree-sitter-bash": "0.23.2",
|
|
||||||
"tree-sitter-c": "0.23.1",
|
|
||||||
"tree-sitter-cli": "0.25.8",
|
|
||||||
"tree-sitter-cpp": "0.23.4",
|
|
||||||
"tree-sitter-css": "0.23.0",
|
|
||||||
"tree-sitter-go": "0.23.4",
|
|
||||||
"tree-sitter-html": "0.23.2",
|
|
||||||
"tree-sitter-java": "0.23.5",
|
|
||||||
"tree-sitter-javascript": "0.23.1",
|
|
||||||
"tree-sitter-json": "0.24.8",
|
|
||||||
"tree-sitter-lua": "2.1.3",
|
|
||||||
"tree-sitter-php": "0.23.12",
|
|
||||||
"tree-sitter-python": "0.23.2",
|
|
||||||
"tree-sitter-r": "0.0.1-security",
|
|
||||||
"tree-sitter-sql": "0.1.0",
|
|
||||||
"tree-sitter-sqlite": "0.0.1-security",
|
|
||||||
"tree-sitter-toml": "0.5.1",
|
|
||||||
"tree-sitter-typescript": "0.23.2",
|
|
||||||
"tree-sitter-yaml": "0.5.0",
|
|
||||||
"tslib": "2.3.0",
|
"tslib": "2.3.0",
|
||||||
"typescript": "5.7.2"
|
"typescript": "5.7.2"
|
||||||
}
|
}
|
||||||
|
@@ -8,78 +8,62 @@
|
|||||||
"command": "lsp-ws-proxy --listen 4114 -- jdtls",
|
"command": "lsp-ws-proxy --listen 4114 -- jdtls",
|
||||||
"alt-command": "lsp-ws-proxy -- jdtls",
|
"alt-command": "lsp-ws-proxy -- jdtls",
|
||||||
"alt-command2": "java-language-server",
|
"alt-command2": "java-language-server",
|
||||||
"socket": "ws://127.0.0.1:9999/java",
|
"socket": "ws://127.0.0.1:4114/?name=jdtls",
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=jdtls",
|
"alt-socket": "ws://127.0.0.1:3030/?name=java-language-server",
|
||||||
"alt-socket": "ws://127.0.0.1:9999/?name=java-language-server",
|
|
||||||
"initialization-options": {
|
"initialization-options": {
|
||||||
"bundles": [
|
"bundles": [
|
||||||
|
"intellicode-core.jar"
|
||||||
],
|
],
|
||||||
"workspaceFolders": [
|
"workspaceFolders": [
|
||||||
"file://{workspace.folder}"
|
"file://"
|
||||||
],
|
],
|
||||||
"extendedClientCapabilities": {
|
"extendedClientCapabilities": {
|
||||||
"classFileContentsSupport": true,
|
"classFileContentsSupport": true,
|
||||||
"executeClientCommandSupport": false
|
"executeClientCommandSupport": true
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"java": {
|
"java": {
|
||||||
"autobuild": {
|
"autobuild": {
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
"jdt": {
|
"completion": {
|
||||||
"ls": {
|
"enabled": true,
|
||||||
"javac": {
|
"importOrder": [
|
||||||
"enabled": true
|
"java",
|
||||||
},
|
"javax",
|
||||||
"java": {
|
"org",
|
||||||
"home": "{user.home}/Portable_Apps/sdks/javasdk/jdk-22.0.2"
|
"com"
|
||||||
},
|
]
|
||||||
"lombokSupport": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"protobufSupport":{
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"androidSupport": {
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"updateBuildConfiguration": "automatic",
|
|
||||||
"maven": {
|
"maven": {
|
||||||
"userSettings": "{user.home}/.config/lsps/jdtls/settings.xml",
|
"userSettings": "{user.home}/.config/jdtls/settings.xml",
|
||||||
"globalSettings": "{user.home}/.config/lsps/jdtls/settings.xml"
|
"globalSettings": "{user.home}/.config/jdtls/settings.xml"
|
||||||
},
|
},
|
||||||
"runtimes": [
|
"runtimes": [
|
||||||
{
|
{
|
||||||
"name": "JavaSE-17",
|
"name": "JavaSE-17",
|
||||||
"path": "/usr/lib/jvm/java-17-openjdk",
|
"path": "/usr/lib/jvm/default-runtime",
|
||||||
"javadoc": "https://docs.oracle.com/en/java/javase/17/docs/api/",
|
"javadoc": "https://docs.oracle.com/en/java/javase/17/docs/api/",
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "JavaSE-22",
|
|
||||||
"path": "{user.home}/Portable_Apps/sdks/javasdk/jdk-22.0.2",
|
|
||||||
"javadoc": "https://docs.oracle.com/en/java/javase/22/docs/api/",
|
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"classPath": [
|
"classPath": [
|
||||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*-sources.jar",
|
"{user.home}/.config/jdtls/m2/repository/**/*-sources.jar",
|
||||||
"lib/**/*-sources.jar"
|
"lib/**/*-sources.jar"
|
||||||
],
|
],
|
||||||
"docPath": [
|
"docPath": [
|
||||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*-javadoc.jar",
|
"{user.home}/.config/jdtls/m2/repository/**/*-javadoc.jar",
|
||||||
"lib/**/*-javadoc.jar"
|
"lib/**/*-javadoc.jar"
|
||||||
],
|
],
|
||||||
|
"silentNotification": true,
|
||||||
"project": {
|
"project": {
|
||||||
"encoding": "ignore",
|
"encoding": "ignore",
|
||||||
"outputPath": "bin",
|
"outputPath": "bin",
|
||||||
"referencedLibraries": [
|
"referencedLibraries": [
|
||||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*.jar",
|
"lib/**/*.jar",
|
||||||
"lib/**/*.jar"
|
"{user.home}/.config/jdtls/m2/repository/**/*.jar"
|
||||||
],
|
],
|
||||||
"importOnFirstTimeStartup": "automatic",
|
"importOnFirstTimeStartup": "automatic",
|
||||||
"importHint": true,
|
"importHint": true,
|
||||||
@@ -89,7 +73,7 @@
|
|||||||
],
|
],
|
||||||
"sourcePaths": [
|
"sourcePaths": [
|
||||||
"src",
|
"src",
|
||||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*.jar"
|
"{user.home}/.config/jdtls/m2/repository/**/*.jar"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"sources": {
|
"sources": {
|
||||||
@@ -119,9 +103,9 @@
|
|||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
"version": "",
|
"version": "",
|
||||||
"home": "{user.home}/Portable_Apps/sdks/gradle/gradle-9.0.0",
|
"home": "abs(static/gradle-7.3.3)",
|
||||||
"java": {
|
"java": {
|
||||||
"home": "{user.home}/Portable_Apps/sdks/javasdk/jdk-22.0.2"
|
"home": "abs(static/launch_jres/17.0.6-linux-x86_64)"
|
||||||
},
|
},
|
||||||
"offline": {
|
"offline": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
@@ -147,65 +131,14 @@
|
|||||||
"downloadSources": true,
|
"downloadSources": true,
|
||||||
"updateSnapshots": true
|
"updateSnapshots": true
|
||||||
},
|
},
|
||||||
"silentNotification": true,
|
|
||||||
"contentProvider": {
|
|
||||||
"preferred": "fernflower"
|
|
||||||
},
|
|
||||||
"signatureHelp": {
|
"signatureHelp": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"description": {
|
"description": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"completion": {
|
|
||||||
"enabled": true,
|
|
||||||
"matchCase": "firstletter",
|
|
||||||
"maxResults": 25,
|
|
||||||
"guessMethodArguments": true,
|
|
||||||
"lazyResolveTextEdit": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"postfix": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"favoriteStaticMembers": [
|
|
||||||
"org.junit.Assert.*",
|
|
||||||
"org.junit.Assume.*",
|
|
||||||
"org.junit.jupiter.api.Assertions.*",
|
|
||||||
"org.junit.jupiter.api.Assumptions.*",
|
|
||||||
"org.junit.jupiter.api.DynamicContainer.*",
|
|
||||||
"org.junit.jupiter.api.DynamicTest.*"
|
|
||||||
],
|
|
||||||
"importOrder": [
|
|
||||||
"#",
|
|
||||||
"java",
|
|
||||||
"javax",
|
|
||||||
"org",
|
|
||||||
"com"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"references": {
|
|
||||||
"includeAccessors": true,
|
|
||||||
"includeDecompiledSources": true
|
|
||||||
},
|
|
||||||
"codeGeneration": {
|
|
||||||
"toString": {
|
|
||||||
"template": "${object.className}{${member.name()}=${member.value}, ${otherMembers}}"
|
|
||||||
},
|
|
||||||
"insertionLocation": "afterCursor",
|
|
||||||
"useBlocks": true
|
|
||||||
},
|
|
||||||
"implementationsCodeLens": {
|
"implementationsCodeLens": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
|
||||||
"referencesCodeLens": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"progressReports": {
|
|
||||||
"enabled": false
|
|
||||||
},
|
|
||||||
"saveActions": {
|
|
||||||
"organizeImports": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,39 +150,53 @@
|
|||||||
"alt-command": "pylsp",
|
"alt-command": "pylsp",
|
||||||
"alt-command2": "lsp-ws-proxy --listen 4114 -- pylsp",
|
"alt-command2": "lsp-ws-proxy --listen 4114 -- pylsp",
|
||||||
"alt-command3": "pylsp --ws --port 4114",
|
"alt-command3": "pylsp --ws --port 4114",
|
||||||
"socket": "ws://127.0.0.1:9999/python",
|
"socket": "ws://127.0.0.1:9999/?name=pylsp",
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=pylsp",
|
|
||||||
"initialization-options": {
|
"initialization-options": {
|
||||||
"pylsp": {
|
"pyls": {
|
||||||
"rope": {
|
|
||||||
"ropeFolder": "{user.home}/.config/lsps/ropeproject"
|
|
||||||
},
|
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"ruff": {
|
|
||||||
"enabled": true,
|
|
||||||
"extendSelect": ["I"],
|
|
||||||
"lineLength": 80
|
|
||||||
},
|
|
||||||
"pycodestyle": {
|
"pycodestyle": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
|
"pydocstyle": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
"pyflakes": {
|
"pyflakes": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
"pylint": {
|
"pylint": {
|
||||||
"enabled": true
|
"enabled": false
|
||||||
|
},
|
||||||
|
"mccabe": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pylsp": {
|
||||||
|
"plugins": {
|
||||||
|
"pycodestyle": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pydocstyle": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pyflakes": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"pylint": {
|
||||||
|
"enabled": false
|
||||||
},
|
},
|
||||||
"mccabe": {
|
"mccabe": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
|
"ruff": true,
|
||||||
"pylsp_rope": {
|
"pylsp_rope": {
|
||||||
"rename": false
|
"rename": true
|
||||||
},
|
},
|
||||||
"rope_rename": {
|
"rope_rename": {
|
||||||
"enabled": false
|
"enabled": true
|
||||||
},
|
},
|
||||||
"rope_autoimport": {
|
"rope_autoimport": {
|
||||||
"enabled": false
|
"enabled": true
|
||||||
},
|
},
|
||||||
"rope_completion": {
|
"rope_completion": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
@@ -262,13 +209,13 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"include_class_objects": true,
|
"include_class_objects": true,
|
||||||
"include_function_objects": true,
|
"include_function_objects": true,
|
||||||
"fuzzy": false
|
"fuzzy": true
|
||||||
},
|
},
|
||||||
"jedi": {
|
"jedi":{
|
||||||
"root_dir": "file://{workspace.folder}",
|
|
||||||
"extra_paths": [
|
"extra_paths": [
|
||||||
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
||||||
]
|
],
|
||||||
|
"root_dir": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -279,8 +226,7 @@
|
|||||||
"info": "https://pypi.org/project/jedi-language-server/",
|
"info": "https://pypi.org/project/jedi-language-server/",
|
||||||
"command": "jedi-language-server",
|
"command": "jedi-language-server",
|
||||||
"alt-command": "lsp-ws-proxy --listen 3030 -- jedi-language-server",
|
"alt-command": "lsp-ws-proxy --listen 3030 -- jedi-language-server",
|
||||||
"socket": "ws://127.0.0.1:9999/python",
|
"socket": "ws://127.0.0.1:3030/?name=jedi-language-server",
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=jedi-language-server",
|
|
||||||
"initialization-options": {
|
"initialization-options": {
|
||||||
"jediSettings": {
|
"jediSettings": {
|
||||||
"autoImportModules": [],
|
"autoImportModules": [],
|
||||||
@@ -299,13 +245,7 @@
|
|||||||
],
|
],
|
||||||
"environmentPath": "{user.home}/Portable_Apps/py-venvs/gtk-apps-venv/venv/bin/python",
|
"environmentPath": "{user.home}/Portable_Apps/py-venvs/gtk-apps-venv/venv/bin/python",
|
||||||
"symbols": {
|
"symbols": {
|
||||||
"ignoreFolders": [
|
"ignoreFolders": [".nox", ".tox", ".venv", "__pycache__", "venv"],
|
||||||
".nox",
|
|
||||||
".tox",
|
|
||||||
".venv",
|
|
||||||
"__pycache__",
|
|
||||||
"venv"
|
|
||||||
],
|
|
||||||
"maxSymbols": 20
|
"maxSymbols": 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,8 +255,28 @@
|
|||||||
"info": "https://clangd.llvm.org/",
|
"info": "https://clangd.llvm.org/",
|
||||||
"command": "lsp-ws-proxy -- clangd",
|
"command": "lsp-ws-proxy -- clangd",
|
||||||
"alt-command": "clangd",
|
"alt-command": "clangd",
|
||||||
"socket": "ws://127.0.0.1:9999/cpp",
|
"socket": "ws://127.0.0.1:3030/?name=clangd",
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=clangd",
|
"initialization-options": {}
|
||||||
|
},
|
||||||
|
"sh": {
|
||||||
|
"info": "",
|
||||||
|
"command": "",
|
||||||
|
"alt-command": "",
|
||||||
|
"socket": "ws://127.0.0.1:3030/?name=shell",
|
||||||
|
"initialization-options": {}
|
||||||
|
},
|
||||||
|
"go": {
|
||||||
|
"info": "https://pkg.go.dev/golang.org/x/tools/gopls#section-readme",
|
||||||
|
"command": "lsp-ws-proxy -- gopls",
|
||||||
|
"alt-command": "gopls",
|
||||||
|
"socket": "ws://127.0.0.1:3030/?name=gopls",
|
||||||
|
"initialization-options": {}
|
||||||
|
},
|
||||||
|
"lua": {
|
||||||
|
"info": "https://github.com/LuaLS/lua-language-server",
|
||||||
|
"command": "lsp-ws-proxy -- lua-language-server",
|
||||||
|
"alt-command": "lua-language-server",
|
||||||
|
"socket": "ws://127.0.0.1:3030/?name=gopls",
|
||||||
"initialization-options": {}
|
"initialization-options": {}
|
||||||
},
|
},
|
||||||
"c": {
|
"c": {
|
||||||
@@ -324,40 +284,7 @@
|
|||||||
"info": "https://clangd.llvm.org/",
|
"info": "https://clangd.llvm.org/",
|
||||||
"command": "lsp-ws-proxy -- clangd",
|
"command": "lsp-ws-proxy -- clangd",
|
||||||
"alt-command": "clangd",
|
"alt-command": "clangd",
|
||||||
"socket": "ws://127.0.0.1:9999/c",
|
"socket": "ws://127.0.0.1:3030/?name=clangd",
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=clangd",
|
|
||||||
"initialization-options": {}
|
|
||||||
},
|
|
||||||
"go": {
|
|
||||||
"info": "https://pkg.go.dev/golang.org/x/tools/gopls#section-readme",
|
|
||||||
"command": "lsp-ws-proxy -- gopls",
|
|
||||||
"alt-command": "gopls",
|
|
||||||
"socket": "ws://127.0.0.1:9999/go",
|
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=gopls",
|
|
||||||
"initialization-options": {}
|
|
||||||
},
|
|
||||||
"typescript": {
|
|
||||||
"info": "https://github.com/typescript-language-server/typescript-language-server",
|
|
||||||
"command": "lsp-ws-proxy -- typescript-language-server",
|
|
||||||
"alt-command": "typescript-language-server --stdio",
|
|
||||||
"socket": "ws://127.0.0.1:9999/typescript",
|
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=ts",
|
|
||||||
"initialization-options": {}
|
|
||||||
},
|
|
||||||
"sh": {
|
|
||||||
"info": "",
|
|
||||||
"command": "",
|
|
||||||
"alt-command": "",
|
|
||||||
"socket": "ws://127.0.0.1:9999/bash",
|
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=shell",
|
|
||||||
"initialization-options": {}
|
|
||||||
},
|
|
||||||
"lua": {
|
|
||||||
"info": "https://github.com/LuaLS/lua-language-server",
|
|
||||||
"command": "lsp-ws-proxy -- lua-language-server",
|
|
||||||
"alt-command": "lua-language-server",
|
|
||||||
"socket": "ws://127.0.0.1:9999/lua",
|
|
||||||
"socket-two": "ws://127.0.0.1:9999/?name=lua",
|
|
||||||
"initialization-options": {}
|
"initialization-options": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,7 +4,6 @@
|
|||||||
<editors></editors>
|
<editors></editors>
|
||||||
<search-replace></search-replace>
|
<search-replace></search-replace>
|
||||||
<markdown-preview></markdown-preview>
|
<markdown-preview></markdown-preview>
|
||||||
<terminal></terminal>
|
|
||||||
|
|
||||||
<lsp-manager></lsp-manager>
|
<lsp-manager></lsp-manager>
|
||||||
</div>
|
</div>
|
@@ -5,7 +5,6 @@ import { TabsComponent } from './editor/tabs/tabs.component';
|
|||||||
import { EditorsComponent } from './editor/editors.component';
|
import { EditorsComponent } from './editor/editors.component';
|
||||||
import { SearchReplaceComponent } from "./editor/search-replace/search-replace.component";
|
import { SearchReplaceComponent } from "./editor/search-replace/search-replace.component";
|
||||||
import { MarkdownPreviewComponent } from "./editor/markdown-preview/markdown-preview.component";
|
import { MarkdownPreviewComponent } from "./editor/markdown-preview/markdown-preview.component";
|
||||||
import { TerminalComponent } from "./editor/terminal/terminal.component";
|
|
||||||
import { LspManagerComponent } from "./editor/lsp-manager/lsp-manager.component";
|
import { LspManagerComponent } from "./editor/lsp-manager/lsp-manager.component";
|
||||||
|
|
||||||
|
|
||||||
@@ -18,7 +17,6 @@ import { LspManagerComponent } from "./editor/lsp-manager/lsp-manager.component"
|
|||||||
EditorsComponent,
|
EditorsComponent,
|
||||||
SearchReplaceComponent,
|
SearchReplaceComponent,
|
||||||
MarkdownPreviewComponent,
|
MarkdownPreviewComponent,
|
||||||
TerminalComponent,
|
|
||||||
LspManagerComponent,
|
LspManagerComponent,
|
||||||
],
|
],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
import {
|
import { Component, inject } from "@angular/core";
|
||||||
Component,
|
|
||||||
DestroyRef,
|
|
||||||
inject
|
|
||||||
} from "@angular/core";
|
|
||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
import * as bootstrap from "bootstrap";
|
import * as bootstrap from "bootstrap";
|
||||||
|
|
||||||
@@ -29,18 +25,17 @@ import 'ace-diff/dist/ace-diff-dark.min.css';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class DiffModalComponent {
|
export class DiffModalComponent {
|
||||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
|
||||||
|
|
||||||
diffModal!: bootstrap.Modal;
|
diffModal!: bootstrap.Modal;
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.loadSubscribers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ngAfterViewInit(): void {
|
private ngAfterViewInit(): void {
|
||||||
this.loadDiffView();
|
this.loadDiffView();
|
||||||
|
this.loadSubscribers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadDiffView() {
|
private loadDiffView() {
|
||||||
|
@@ -37,11 +37,6 @@ export const Keybindings: Array<{}> = [
|
|||||||
bindKey: {win: "ctrl-r", mac: "ctrl-r"},
|
bindKey: {win: "ctrl-r", mac: "ctrl-r"},
|
||||||
readOnly: false
|
readOnly: false
|
||||||
}, {
|
}, {
|
||||||
|
|
||||||
name: "terminalPopup",
|
|
||||||
bindKey: {win: "ctrl-shift-.", mac: "ctrl-shift-."},
|
|
||||||
readOnly: false
|
|
||||||
}, {
|
|
||||||
name: "newFile",
|
name: "newFile",
|
||||||
bindKey: {win: "ctrl-t", mac: "ctrl-t"},
|
bindKey: {win: "ctrl-t", mac: "ctrl-t"},
|
||||||
service: "editorsService",
|
service: "editorsService",
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
export abstract class ButtonMap {
|
|
||||||
static LEFT: number = 0;
|
|
||||||
static MIDDLE: number = 1;
|
|
||||||
static RIGHT: number = 2;
|
|
||||||
}
|
|
@@ -16,7 +16,7 @@ import { NewtonFile } from '../types/file.type';
|
|||||||
})
|
})
|
||||||
export class DndDirective {
|
export class DndDirective {
|
||||||
@HostBinding('class.fileover') fileOver!: boolean;
|
@HostBinding('class.fileover') fileOver!: boolean;
|
||||||
@Output() fileDropped: EventEmitter<any> = new EventEmitter();
|
@Output() fileDropped = new EventEmitter<any>();
|
||||||
|
|
||||||
@HostListener('dragover', ['$event'])
|
@HostListener('dragover', ['$event'])
|
||||||
onDragOver(evt: any) {
|
onDragOver(evt: any) {
|
||||||
|
@@ -11,11 +11,11 @@ import {
|
|||||||
selector: '[draggable-item]'
|
selector: '[draggable-item]'
|
||||||
})
|
})
|
||||||
export class DraggableDirective {
|
export class DraggableDirective {
|
||||||
@Output() dragStart: EventEmitter<PointerEvent> = new EventEmitter();
|
@Output() dragStart = new EventEmitter<PointerEvent>();
|
||||||
@Output() dragMove: EventEmitter<PointerEvent> = new EventEmitter();
|
@Output() dragMove = new EventEmitter<PointerEvent>();
|
||||||
@Output() dragEnd: EventEmitter<PointerEvent> = new EventEmitter();
|
@Output() dragEnd = new EventEmitter<PointerEvent>();
|
||||||
|
|
||||||
private dragging: boolean = false;
|
private dragging = false;
|
||||||
selected: any;
|
selected: any;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,9 +11,9 @@ import {
|
|||||||
selector: '[pane-handle]'
|
selector: '[pane-handle]'
|
||||||
})
|
})
|
||||||
export class PaneHandleDirective {
|
export class PaneHandleDirective {
|
||||||
@Output() dragStart: EventEmitter<PointerEvent> = new EventEmitter();
|
@Output() dragStart = new EventEmitter<PointerEvent>();
|
||||||
@Output() dragMove: EventEmitter<PointerEvent> = new EventEmitter();
|
@Output() dragMove = new EventEmitter<PointerEvent>();
|
||||||
@Output() dragEnd: EventEmitter<PointerEvent> = new EventEmitter();
|
@Output() dragEnd = new EventEmitter<PointerEvent>();
|
||||||
|
|
||||||
private dragging: boolean = false;
|
private dragging: boolean = false;
|
||||||
private isHrPane: boolean = false;
|
private isHrPane: boolean = false;
|
||||||
@@ -31,7 +31,7 @@ export class PaneHandleDirective {
|
|||||||
!target.classList.contains("hr-pane-handle") &&
|
!target.classList.contains("hr-pane-handle") &&
|
||||||
!target.classList.contains("vr-pane-handle")
|
!target.classList.contains("vr-pane-handle")
|
||||||
) {
|
) {
|
||||||
console.error("Must have 'hr-pane-handle' or 'vr-pane-handle' in classList!");
|
console.log("Must have 'hr-pane-handle' or 'vr-pane-handle' in classList!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,64 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
import * as ace from "ace-builds/src-min-noconflict/ace";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class ColorTokenizerService {
|
|
||||||
readonly #RULES: {} = {
|
|
||||||
start: [
|
|
||||||
{ token: "hex3", regex: "#[A-Fa-f0-9]{3}(?![A-Fa-f0-9])" },
|
|
||||||
{ token: "hex6", regex: "#[A-Fa-f0-9]{6}(?![A-Fa-f0-9])" },
|
|
||||||
{ token: "hex8", regex: "#[A-Fa-f0-9]{8}(?![A-Fa-f0-9])" },
|
|
||||||
{
|
|
||||||
token: "rgb",
|
|
||||||
regex: /rgb\s*\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)/
|
|
||||||
},
|
|
||||||
{
|
|
||||||
token: "rgba",
|
|
||||||
regex: /rgba\s*\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*(?:0(?:\.\d+)?|1(?:\.0+)?)\s*\)/
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
tokenizer!: any;
|
|
||||||
cssLines: {} = {};
|
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
Object.freeze(this.#RULES)
|
|
||||||
|
|
||||||
const Tokenizer = ace.require("ace/tokenizer").Tokenizer;
|
|
||||||
this.tokenizer = new Tokenizer(this.#RULES);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async parse(data: string) {
|
|
||||||
const lines = data.split("\n");
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
const token = this.parseLine( lines[i] );
|
|
||||||
if (!token) continue;
|
|
||||||
this.cssLines[i] = token;
|
|
||||||
this.cssLines[i]["hash"] = btoa(
|
|
||||||
token["value"]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(this.cssLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
public parseLine(line: string): {} | null {
|
|
||||||
const tokens = this.tokenizer.getLineTokens(line, "start").tokens;
|
|
||||||
|
|
||||||
for (let i = 0; i < tokens.length; i++) {
|
|
||||||
if ("text" === tokens[i]["type"]) continue;
|
|
||||||
return tokens[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -15,15 +15,21 @@ import { EditorType } from '../../types/editor.type';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class EditorsService {
|
export class EditorsService {
|
||||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||||
|
|
||||||
editors: Map<string, CodeViewComponent> = new Map();
|
editors: Map<string, CodeViewComponent>;
|
||||||
editorSettings: typeof EditorSettings = EditorSettings;
|
editorSettings: typeof EditorSettings;
|
||||||
|
|
||||||
activeEditor: string = "";
|
activeEditor!: string;
|
||||||
miniMapView!: CodeViewComponent;
|
miniMapView!: CodeViewComponent;
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.editorSettings = EditorSettings;
|
||||||
|
this.editors = new Map<string, CodeViewComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public getEditorsAsArray(): CodeViewComponent[] {
|
public getEditorsAsArray(): CodeViewComponent[] {
|
||||||
return [...this.editors.values()];
|
return [...this.editors.values()];
|
||||||
}
|
}
|
||||||
|
@@ -8,11 +8,14 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class InfoBarService {
|
export class InfoBarService {
|
||||||
private dataSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
private dataSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||||
private fpathSubject: ReplaySubject<string> = new ReplaySubject(1);
|
private fpathSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||||
private cursorPosSubject: ReplaySubject<any> = new ReplaySubject(1);
|
private cursorPosSubject: ReplaySubject<any> = new ReplaySubject<any>(1);
|
||||||
private encodeingSubject: ReplaySubject<string> = new ReplaySubject(1);
|
private encodeingSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||||
private ftypeSubject: ReplaySubject<string> = new ReplaySubject(1);
|
private ftypeSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
|
||||||
public setData(data: ServiceMessage): void {
|
public setData(data: ServiceMessage): void {
|
||||||
|
@@ -1,15 +1,9 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { ReplaySubject, Observable } from 'rxjs';
|
import { ReplaySubject, Observable } from 'rxjs';
|
||||||
|
|
||||||
import { CompletionProvider } from "ace-builds/src-min-noconflict/ace";
|
|
||||||
import { CommandBarTooltip } from "ace-builds/src-min-noconflict/ext-command_bar";
|
|
||||||
import { InlineAutocomplete } from "ace-builds/src-min-noconflict/ext-inline_autocomplete";
|
|
||||||
|
|
||||||
import { AceLanguageClient, LanguageClientConfig } from 'ace-linters/build/ace-language-client';
|
import { AceLanguageClient, LanguageClientConfig } from 'ace-linters/build/ace-language-client';
|
||||||
import { LanguageProvider } from "ace-linters";
|
import { LanguageProvider } from "ace-linters";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { ServiceMessage } from '../../../types/service-message.type';
|
import { ServiceMessage } from '../../../types/service-message.type';
|
||||||
|
|
||||||
|
|
||||||
@@ -18,155 +12,85 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class LspManagerService {
|
export class LspManagerService {
|
||||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||||
|
|
||||||
workspaceFolder: string = "";
|
lspConfigData!: {};
|
||||||
lspConfigDataStr: string = "";
|
languageProviders: {} = {};
|
||||||
languageProviders: {} = {};
|
workspaceFolder: string = "";
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public loadLspConfigData(): Promise<string | void> {
|
public loadLspConfigData(): Promise<string | void> {
|
||||||
return this.getLspConfigData().then((lspConfigData: string) => {
|
return this.getLspConfigData().then((lspConfigData: string) => {
|
||||||
this.lspConfigDataStr = lspConfigData;
|
this.lspConfigData = JSON.parse(lspConfigData);
|
||||||
|
|
||||||
|
if (this.lspConfigData["message"]) {
|
||||||
|
console.log(
|
||||||
|
"Warning: LSP this.lspConfigData is a 'message'",
|
||||||
|
this.lspConfigData
|
||||||
|
);
|
||||||
|
|
||||||
|
this.lspConfigData = {};
|
||||||
|
}
|
||||||
|
|
||||||
return lspConfigData;
|
return lspConfigData;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerEditorToLSPClient(editor: any) {
|
public registerEditor(editor: any): void {
|
||||||
let mode = this.getMode(editor.session);
|
let modeParts = editor.session.getMode()["$Id"].split("/");
|
||||||
|
let mode = modeParts[ modeParts.length - 1 ];
|
||||||
|
|
||||||
this.languageProviders[mode]?.registerEditor(
|
if ( !this.languageProviders[mode] ) {
|
||||||
editor,
|
this.languageProviders[mode] = this.getLanguageProviderWithClientServer(mode);
|
||||||
editor.session.lspConfig
|
}
|
||||||
);
|
|
||||||
|
this.languageProviders[mode].registerEditor(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLspConfigData(): Promise<string> {
|
private getLspConfigData(): Promise<string> {
|
||||||
return window.fs.getLspConfigData();
|
return window.fs.getLspConfigData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseAndReturnLSPConfigData(): {} {
|
private getLanguageProviderWithClientServer(mode: string) {
|
||||||
let configData = JSON.parse(
|
let _initializationOptions = {};
|
||||||
this.lspConfigDataStr.replaceAll("{workspace.folder}", this.workspaceFolder)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (configData["message"]) {
|
if ( Object.keys(this.lspConfigData).length !== 0 && this.lspConfigData[mode] ) {
|
||||||
console.warn(
|
_initializationOptions = this.lspConfigData[mode]["initialization-options"];
|
||||||
"Warning: LSP this.lspConfigDataStr is a 'message'",
|
|
||||||
this.lspConfigDataStr
|
|
||||||
);
|
|
||||||
|
|
||||||
configData = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return configData;
|
let servers: LanguageClientConfig[] = [
|
||||||
}
|
|
||||||
|
|
||||||
private getInitializationOptions(mode: string, configData: {}): {} {
|
|
||||||
let initializationOptions = {};
|
|
||||||
|
|
||||||
if ( Object.keys(configData).length !== 0 && configData[mode] ) {
|
|
||||||
initializationOptions = configData[mode]["initialization-options"];
|
|
||||||
}
|
|
||||||
|
|
||||||
return initializationOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public createLanguageProviderWithClientServer(mode: string): LanguageProvider {
|
|
||||||
if ( this.languageProviders[mode] ) return;
|
|
||||||
let servers: LanguageClientConfig[] = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
let lspConfigData = this.parseAndReturnLSPConfigData();
|
|
||||||
let initializationOptions = this.getInitializationOptions(mode, lspConfigData);
|
|
||||||
servers = [
|
|
||||||
{
|
|
||||||
module: () => import("ace-linters/build/language-client"),
|
|
||||||
modes: mode,
|
|
||||||
type: "socket",
|
|
||||||
socket: new WebSocket( lspConfigData[mode]["socket"] ),
|
|
||||||
initializationOptions: initializationOptions
|
|
||||||
}
|
|
||||||
];
|
|
||||||
} catch(error) {
|
|
||||||
console.error(
|
|
||||||
"Error: Language Server could not be loaded OR doesn't exist in Newton-LSP config setup...",
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.languageProviders[mode] = AceLanguageClient.for(
|
|
||||||
servers,
|
|
||||||
{
|
{
|
||||||
workspacePath: this.workspaceFolder,
|
module: () => import("ace-linters/build/language-client"),
|
||||||
functionality: {
|
modes: mode,
|
||||||
hover: true,
|
type: "socket",
|
||||||
completion: {
|
socket: new WebSocket(`ws://127.0.0.1:9999/${mode}`),
|
||||||
overwriteCompleters: true,
|
// socket: new WebSocket("ws://127.0.0.1:9999/?name=pylsp"),
|
||||||
lspCompleterOptions: {
|
initializationOptions: _initializationOptions
|
||||||
triggerCharacters: {
|
|
||||||
add: [
|
|
||||||
" ",
|
|
||||||
".",
|
|
||||||
"@"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// inlineCompletion: {
|
|
||||||
// overwriteCompleters: true
|
|
||||||
// },
|
|
||||||
completionResolve: true,
|
|
||||||
format: true,
|
|
||||||
documentHighlights: true,
|
|
||||||
signatureHelp: true,
|
|
||||||
semanticTokens: true,
|
|
||||||
codeActions: true
|
|
||||||
},
|
|
||||||
// aceComponents: {
|
|
||||||
// InlineAutocomplete,
|
|
||||||
// CommandBarTooltip,
|
|
||||||
// CompletionProvider
|
|
||||||
// },
|
|
||||||
manualSessionControl: true
|
|
||||||
}
|
}
|
||||||
);
|
];
|
||||||
|
|
||||||
return this.languageProviders[mode];
|
return AceLanguageClient.for(servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeLanguageProviderWithClientServer(mode: string): LanguageProvider {
|
private getLanguageProviderWithWebWorker() {
|
||||||
if ( !this.languageProviders[mode] ) return;
|
|
||||||
|
|
||||||
let connection = this.languageProviders[mode];
|
|
||||||
delete this.languageProviders[mode];
|
|
||||||
connection.closeConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
private getLanguageProviderWithWebWorker(): LanguageProvider {
|
|
||||||
let worker = new Worker(new URL('./webworker.js', import.meta.url));
|
let worker = new Worker(new URL('./webworker.js', import.meta.url));
|
||||||
return LanguageProvider.create(worker);
|
return LanguageProvider.create(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerSession(editor: any) {
|
protected setSessionFilePath(session: any, filePath: string = "") {
|
||||||
let mode = this.getMode(editor.session);
|
if ( !session || !filePath ) return;
|
||||||
|
let mode = session.getMode()["$Id"];
|
||||||
if ( !this.languageProviders[mode] ) return;
|
if ( !this.languageProviders[mode] ) return;
|
||||||
|
this.languageProviders[mode].setSessionFilePath(session, filePath);
|
||||||
this.languageProviders[mode].registerSession(
|
|
||||||
editor.session,
|
|
||||||
editor,
|
|
||||||
editor.session.lspConfig
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getMode(session: any): string {
|
protected closeDocument(session: any) {
|
||||||
return session.getMode()["$id"].replace("ace/mode/", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public closeDocument(session: any) {
|
|
||||||
if ( !session ) return;
|
if ( !session ) return;
|
||||||
let mode = this.getMode(session);
|
let mode = session.getMode()["$Id"];
|
||||||
if ( !this.languageProviders[mode] ) return;
|
if ( !this.languageProviders[mode] ) return;
|
||||||
this.languageProviders[mode].closeDocument(session);
|
this.languageProviders[mode].closeDocument(session);
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,11 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class MarkdownPreviewService {
|
export class MarkdownPreviewService {
|
||||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public sendMessage(data: ServiceMessage): void {
|
public sendMessage(data: ServiceMessage): void {
|
||||||
|
@@ -8,7 +8,11 @@ import { ReplaySubject, Observable } from 'rxjs';
|
|||||||
})
|
})
|
||||||
export class FilesModalService {
|
export class FilesModalService {
|
||||||
private showFilesModalSubject: ReplaySubject<null> = new ReplaySubject<null>(1);
|
private showFilesModalSubject: ReplaySubject<null> = new ReplaySubject<null>(1);
|
||||||
private addFileSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
private addFileSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public showFilesModal(): void {
|
public showFilesModal(): void {
|
||||||
|
@@ -12,6 +12,10 @@ export class SearchReplaceService {
|
|||||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public sendMessage(data: ServiceMessage): void {
|
public sendMessage(data: ServiceMessage): void {
|
||||||
this.messageSubject.next(data);
|
this.messageSubject.next(data);
|
||||||
}
|
}
|
||||||
|
@@ -11,13 +11,15 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class TabsService {
|
export class TabsService {
|
||||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||||
|
|
||||||
private editorsService: EditorsService = inject(EditorsService);
|
private editorsService: EditorsService = inject(EditorsService);
|
||||||
|
|
||||||
tabs: any[] = [];
|
tabs: any[] = [];
|
||||||
newIndex: number = -1;
|
newIndex: number = -1;
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
|
||||||
public push(tabData: {}): void {
|
public push(tabData: {}): void {
|
||||||
this.tabs.push(tabData);
|
this.tabs.push(tabData);
|
||||||
@@ -43,21 +45,45 @@ export class TabsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getLeftSiblingTab(fpath: string): string {
|
public getLeftSiblingTab(fpath: string): string {
|
||||||
if (this.tabs.length === 0 ) return;
|
let size = this.tabs.length;
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
let i = this.tabs.indexOf(fpath);
|
for (; i < size; i++) {
|
||||||
|
if (this.tabs[i].path == fpath) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(i === 0) ? i = this.tabs.length - 1 : i -= 1;
|
if ( !(size > 1) ) {
|
||||||
return this.tabs[i].path;
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i === 0 ) {
|
||||||
|
return this.tabs[i + 1].path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.tabs[i - 1].path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRightSiblingTab(fpath: string): string {
|
public getRightSiblingTab(fpath: string): string {
|
||||||
if (this.tabs.length === 0 ) return;
|
let size = this.tabs.length;
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
let i = this.tabs.indexOf(fpath);
|
for (; i < size; i++) {
|
||||||
|
if (this.tabs[i].path == fpath) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(i === (this.tabs.length - 1)) ? i = 0 : i += 1;
|
if ( !(size > 1) ) {
|
||||||
return this.tabs[i].path;
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i === (size - 1) ) {
|
||||||
|
return this.tabs[i - 1].path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.tabs[i + 1].path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setNewTargetIndex(fpath: string): void {
|
public setNewTargetIndex(fpath: string): void {
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { ReplaySubject, Observable } from 'rxjs';
|
|
||||||
|
|
||||||
import { ServiceMessage } from '../../../types/service-message.type';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class TerminalService {
|
|
||||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
|
||||||
|
|
||||||
|
|
||||||
public sendMessage(data: ServiceMessage): void {
|
|
||||||
this.messageSubject.next(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getMessage$(): Observable<ServiceMessage> {
|
|
||||||
return this.messageSubject.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -5,7 +5,6 @@ import { EditSession, UndoManager } from 'ace-builds';
|
|||||||
import { getModeForPath } from 'ace-builds/src-noconflict/ext-modelist';
|
import { getModeForPath } from 'ace-builds/src-noconflict/ext-modelist';
|
||||||
|
|
||||||
import { TabsService } from './editor/tabs/tabs.service';
|
import { TabsService } from './editor/tabs/tabs.service';
|
||||||
import { ColorTokenizerService } from './color-tokenizer.service';
|
|
||||||
|
|
||||||
import { NewtonFile } from '../types/file.type';
|
import { NewtonFile } from '../types/file.type';
|
||||||
import { ServiceMessage } from '../types/service-message.type';
|
import { ServiceMessage } from '../types/service-message.type';
|
||||||
@@ -16,11 +15,16 @@ import { ServiceMessage } from '../types/service-message.type';
|
|||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class FilesService {
|
export class FilesService {
|
||||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||||
|
|
||||||
private tabsService: TabsService = inject(TabsService);
|
private tabsService: TabsService = inject(TabsService);
|
||||||
|
|
||||||
files: Map<string, NewtonFile> = new Map();
|
files: Map<string, NewtonFile>;
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.files = new Map<string, NewtonFile>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public get(path: string): NewtonFile {
|
public get(path: string): NewtonFile {
|
||||||
@@ -35,25 +39,7 @@ export class FilesService {
|
|||||||
return [...this.files.values()];
|
return [...this.files.values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPreviousFile(path: string): NewtonFile {
|
public delete(file: NewtonFile) {
|
||||||
let paths = this.getAllPaths();
|
|
||||||
if (paths.length === 0 ) return;
|
|
||||||
|
|
||||||
let i = paths.indexOf(path);
|
|
||||||
(i === 0) ? i = paths.length - 1 : i -= 1;
|
|
||||||
return this.files.get( paths[i] );
|
|
||||||
}
|
|
||||||
|
|
||||||
public getNextFile(path: string): NewtonFile {
|
|
||||||
let paths = this.getAllPaths();
|
|
||||||
if (paths.length === 0 ) return;
|
|
||||||
|
|
||||||
let i = paths.indexOf(path);
|
|
||||||
(i === (paths.length - 1)) ? i = 0 : i += 1;
|
|
||||||
return this.files.get( paths[i] );
|
|
||||||
}
|
|
||||||
|
|
||||||
public unset(file: NewtonFile) {
|
|
||||||
file.session.destroy();
|
file.session.destroy();
|
||||||
window.fs.closeFile(file.path);
|
window.fs.closeFile(file.path);
|
||||||
this.files.delete(file.path);
|
this.files.delete(file.path);
|
||||||
@@ -103,20 +89,13 @@ export class FilesService {
|
|||||||
if (loadFileContents)
|
if (loadFileContents)
|
||||||
data = await window.fs.getFileContents(file.path);
|
data = await window.fs.getFileContents(file.path);
|
||||||
|
|
||||||
file.session = new EditSession(data);
|
file.session = new EditSession(data);
|
||||||
file.session["id"] = path;
|
|
||||||
file.session.setUndoManager( new UndoManager() );
|
file.session.setUndoManager( new UndoManager() );
|
||||||
file.session.setMode( getModeForPath( file.path ).mode );
|
file.session.setMode( getModeForPath( file.path ).mode );
|
||||||
file.session["lspConfig"] = {
|
|
||||||
filePath: path,
|
|
||||||
joinWorkspaceURI: false
|
|
||||||
}
|
|
||||||
file.session["colorTokenizer"] = new ColorTokenizerService();
|
|
||||||
file.session["colorTokenizer"].parse(data);
|
|
||||||
|
|
||||||
this.files.set(file.path, file);
|
this.files.set(file.path, file);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(
|
console.log(
|
||||||
`---- Error ----\nPath: ${path}\nMessage: ${error}`
|
`---- Error ----\nPath: ${path}\nMessage: ${error}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,4 @@
|
|||||||
import {
|
import { Directive, ElementRef, Input, ViewChild, inject } from '@angular/core';
|
||||||
Directive,
|
|
||||||
ElementRef,
|
|
||||||
Input,
|
|
||||||
ViewChild,
|
|
||||||
inject
|
|
||||||
} from '@angular/core';
|
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
|
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
|
||||||
@@ -14,7 +8,6 @@ import { EditorsService } from '../../common/services/editor/editors.service';
|
|||||||
import { FilesService } from '../../common/services/files.service';
|
import { FilesService } from '../../common/services/files.service';
|
||||||
import { SearchReplaceService } from '../../common/services/editor/search-replace/search-replace.service';
|
import { SearchReplaceService } from '../../common/services/editor/search-replace/search-replace.service';
|
||||||
import { MarkdownPreviewService } from '../../common/services/editor/markdown-preview/markdown-preview.service';
|
import { MarkdownPreviewService } from '../../common/services/editor/markdown-preview/markdown-preview.service';
|
||||||
import { TerminalService } from '../../common/services/editor/terminal/terminal.service';
|
|
||||||
import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service';
|
import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service';
|
||||||
|
|
||||||
import { EditorSettings } from "../../common/configs/editor.config";
|
import { EditorSettings } from "../../common/configs/editor.config";
|
||||||
@@ -39,7 +32,6 @@ export class CodeViewBase {
|
|||||||
protected filesService: FilesService = inject(FilesService);
|
protected filesService: FilesService = inject(FilesService);
|
||||||
protected searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
|
protected searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
|
||||||
protected markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
|
protected markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
|
||||||
protected terminalService: TerminalService = inject(TerminalService);
|
|
||||||
protected lspManagerService: LspManagerService = inject(LspManagerService);
|
protected lspManagerService: LspManagerService = inject(LspManagerService);
|
||||||
|
|
||||||
@ViewChild('editor') editorElm!: ElementRef;
|
@ViewChild('editor') editorElm!: ElementRef;
|
||||||
@@ -54,8 +46,9 @@ export class CodeViewBase {
|
|||||||
public debounceId: number = -1;
|
public debounceId: number = -1;
|
||||||
public debounceWait: number = 800;
|
public debounceWait: number = 800;
|
||||||
|
|
||||||
@ViewChild('contextMenu') contextMenu!: ElementRef;
|
|
||||||
public showContextMenu: boolean = false;
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public selectLeftEditor() {
|
public selectLeftEditor() {
|
||||||
@@ -134,12 +127,6 @@ export class CodeViewBase {
|
|||||||
// this.editor.execCommand("replace");
|
// this.editor.execCommand("replace");
|
||||||
}
|
}
|
||||||
|
|
||||||
public terminalPopup() {
|
|
||||||
let message = new ServiceMessage();
|
|
||||||
message.action = "toggle-terminal";
|
|
||||||
this.terminalService.sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public showFilesList() {
|
public showFilesList() {
|
||||||
let paths = this.filesService.getAllPaths();
|
let paths = this.filesService.getAllPaths();
|
||||||
let stubPaths = [];
|
let stubPaths = [];
|
||||||
@@ -213,8 +200,8 @@ export class CodeViewBase {
|
|||||||
this.editor.setHighlightGutterLine(false);
|
this.editor.setHighlightGutterLine(false);
|
||||||
this.editor.setShowFoldWidgets(false);
|
this.editor.setShowFoldWidgets(false);
|
||||||
this.editor.setShowPrintMargin(false);
|
this.editor.setShowPrintMargin(false);
|
||||||
this.editor.session.setUseWrapMode(true);
|
|
||||||
|
|
||||||
|
this.editorElm.nativeElement.parentElement.classList.remove("scroller");
|
||||||
this.editorElm.nativeElement.parentElement.classList.add("col-1");
|
this.editorElm.nativeElement.parentElement.classList.add("col-1");
|
||||||
this.editorElm.nativeElement.parentElement.classList.add("zero-margin-padding");
|
this.editorElm.nativeElement.parentElement.classList.add("zero-margin-padding");
|
||||||
|
|
||||||
|
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
.editor {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
height: 100vh;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -10,24 +26,3 @@
|
|||||||
border-width: thin;
|
border-width: thin;
|
||||||
border-color: rgba(124, 124, 124, 1);
|
border-color: rgba(124, 124, 124, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.contextMenu {
|
|
||||||
display: inline-table;
|
|
||||||
z-index: 500;
|
|
||||||
position: absolute;
|
|
||||||
min-width: 2em;
|
|
||||||
padding: 0.2em;
|
|
||||||
top: 0em;
|
|
||||||
right: 0em;
|
|
||||||
background-color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contextMenu li:hover {
|
|
||||||
background-color: rgba(0, 124, 0, 0.64);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contextMenu li {
|
|
||||||
padding: 0em 0.2em;
|
|
||||||
}
|
|
||||||
|
@@ -1,15 +1,2 @@
|
|||||||
<div class="editor" #editor >
|
<div class="editor" #editor >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul #contextMenu
|
|
||||||
class="contextMenu"
|
|
||||||
[hidden]="!showContextMenu"
|
|
||||||
(blur)="hideContextMenu"
|
|
||||||
(click)="contextMenuClicked($event)"
|
|
||||||
>
|
|
||||||
<li command="cutText">Cut</li>
|
|
||||||
<li command="copyText">Copy</li>
|
|
||||||
<li command="pasteText">Paste</li>
|
|
||||||
<hr/>
|
|
||||||
<li command="prettyJSON">Prettify JSON</li>
|
|
||||||
</ul>
|
|
@@ -2,10 +2,6 @@ import { Component } from "@angular/core";
|
|||||||
|
|
||||||
// Import Ace and its modes/themes so that `ace` global is defined
|
// Import Ace and its modes/themes so that `ace` global is defined
|
||||||
import * as ace from "ace-builds/src-min-noconflict/ace";
|
import * as ace from "ace-builds/src-min-noconflict/ace";
|
||||||
|
|
||||||
// Note: https://github.com/mkslanc/ace-linters/blob/c286d85c558530aa1b0597d02108bc782abd4736/packages/demo/file-api-websockets/client.ts#L27
|
|
||||||
// import { AceLayout, Box, TabManager, Button, dom, AceTreeWrapper, FileSystemWeb, Pane, AceEditor, Tab } from "ace-layout";
|
|
||||||
|
|
||||||
import "ace-builds/src-min-noconflict/ext-settings_menu";
|
import "ace-builds/src-min-noconflict/ext-settings_menu";
|
||||||
import "ace-builds/src-min-noconflict/ext-keybinding_menu";
|
import "ace-builds/src-min-noconflict/ext-keybinding_menu";
|
||||||
import "ace-builds/src-min-noconflict/ext-command_bar";
|
import "ace-builds/src-min-noconflict/ext-command_bar";
|
||||||
@@ -17,15 +13,11 @@ import "ace-builds/src-min-noconflict/ext-language_tools";
|
|||||||
// import "ace-builds/src-min-noconflict/theme-penguins_in_space";
|
// import "ace-builds/src-min-noconflict/theme-penguins_in_space";
|
||||||
import "ace-builds/src-min-noconflict/theme-gruvbox";
|
import "ace-builds/src-min-noconflict/theme-gruvbox";
|
||||||
|
|
||||||
// https://www.npmjs.com/package/web-tree-sitter
|
|
||||||
// import { Language, Parser } from 'web-tree-sitter';
|
|
||||||
|
|
||||||
import { CodeViewBase } from './view.base';
|
import { CodeViewBase } from './view.base';
|
||||||
|
|
||||||
import { NewtonFile } from '../../common/types/file.type';
|
import { NewtonFile } from '../../common/types/file.type';
|
||||||
import { EditorType } from '../../common/types/editor.type';
|
import { EditorType } from '../../common/types/editor.type';
|
||||||
import { ServiceMessage } from '../../common/types/service-message.type';
|
import { ServiceMessage } from '../../common/types/service-message.type';
|
||||||
import { ButtonMap } from '../../common/constants/button.map';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -46,20 +38,6 @@ export class CodeViewComponent extends CodeViewBase {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// const { Parser } = window.TreeSitter;
|
|
||||||
// const { Parser } = TreeSitter;
|
|
||||||
// console.log(treeSitter);
|
|
||||||
|
|
||||||
// treeSitter.Parser.init().then(() => {
|
|
||||||
// console.log("Parser ready...");
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const parser = new Parser();
|
|
||||||
// const JavaScript = await Language.load('/path/to/tree-sitter-javascript.wasm');
|
|
||||||
// Language.load('resources/wasm/tree-sitter-javascript.wasm').then((language) => {
|
|
||||||
// console.log(language);
|
|
||||||
// });
|
|
||||||
|
|
||||||
this.aceApi = ace;
|
this.aceApi = ace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,41 +128,20 @@ export class CodeViewComponent extends CodeViewBase {
|
|||||||
|
|
||||||
this.editorsService.sendMessage(message);
|
this.editorsService.sendMessage(message);
|
||||||
this.searchReplaceService.sendMessage(message);
|
this.searchReplaceService.sendMessage(message);
|
||||||
this.terminalService.sendMessage(message);
|
this.lspManagerService.sendMessage(message);
|
||||||
|
|
||||||
message = new ServiceMessage();
|
message = new ServiceMessage();
|
||||||
message.action = "set-active-editor";
|
message.action = "set-active-editor";
|
||||||
message.rawData = this;
|
message.rawData = this;
|
||||||
this.lspManagerService.sendMessage(message);
|
|
||||||
this.markdownPreviewService.sendMessage(message);
|
this.markdownPreviewService.sendMessage(message);
|
||||||
|
|
||||||
this.updateInfoBar();
|
this.updateInfoBar();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.on("click", (event) => {
|
this.editor.on("click", () => {
|
||||||
this.updateInfoBar();
|
this.updateInfoBar();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.addEventListener("mousedown", (event) => {
|
|
||||||
if (ButtonMap.LEFT === event.domEvent.button) {
|
|
||||||
this.showContextMenu = false;
|
|
||||||
} else if (ButtonMap.RIGHT === event.domEvent.button) {
|
|
||||||
let menuElm = this.contextMenu.nativeElement;
|
|
||||||
let pageX = event.domEvent.pageX;
|
|
||||||
let pageY = event.domEvent.pageY;
|
|
||||||
|
|
||||||
const origin = {
|
|
||||||
left: pageX + 5,
|
|
||||||
top: pageY - 5
|
|
||||||
};
|
|
||||||
|
|
||||||
menuElm.style.left = `${origin.left}px`;
|
|
||||||
menuElm.style.top = `${origin.top}px`;
|
|
||||||
this.showContextMenu = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.editor.on("input", () => {
|
this.editor.on("input", () => {
|
||||||
this.updateInfoBar();
|
this.updateInfoBar();
|
||||||
});
|
});
|
||||||
@@ -204,18 +161,6 @@ export class CodeViewComponent extends CodeViewBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.on("mousewheel", (event) => {
|
|
||||||
if (event.domEvent.ctrlKey && event.domEvent.deltaY < 0) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
this.zoomIn();
|
|
||||||
} else if (event.domEvent.ctrlKey && event.domEvent.deltaY > 0) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
this.zoomOut();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.editor.on("change", () => {
|
this.editor.on("change", () => {
|
||||||
if (this.debounceId) { clearTimeout(this.debounceId); }
|
if (this.debounceId) { clearTimeout(this.debounceId); }
|
||||||
this.setDebounceTimeout();
|
this.setDebounceTimeout();
|
||||||
@@ -231,8 +176,8 @@ export class CodeViewComponent extends CodeViewBase {
|
|||||||
|
|
||||||
this.editor.on("changeSession", (session) => {
|
this.editor.on("changeSession", (session) => {
|
||||||
let message = new ServiceMessage();
|
let message = new ServiceMessage();
|
||||||
message.action = "editor-update";
|
message.action = "set-active-editor";
|
||||||
message.rawData = this;
|
message.rawData = this.editor;
|
||||||
|
|
||||||
this.lspManagerService.sendMessage(message);
|
this.lspManagerService.sendMessage(message);
|
||||||
|
|
||||||
@@ -241,28 +186,6 @@ export class CodeViewComponent extends CodeViewBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public prettyJSON() {
|
|
||||||
let data = JSON.parse(this.editor.session.getValue());
|
|
||||||
this.editor.session.setValue(
|
|
||||||
JSON.stringify(data, null, 4)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public hideContextMenu() {
|
|
||||||
this.showContextMenu = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public contextMenuClicked(event: any) {
|
|
||||||
this.showContextMenu = false;
|
|
||||||
|
|
||||||
const command = event.target.getAttribute("command");
|
|
||||||
const args = event.target.getAttribute("args");
|
|
||||||
|
|
||||||
if (!command) return;
|
|
||||||
|
|
||||||
this[command]( (args) ? args : null );
|
|
||||||
}
|
|
||||||
|
|
||||||
public assignSession(file: NewtonFile) {
|
public assignSession(file: NewtonFile) {
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
@@ -273,17 +196,10 @@ export class CodeViewComponent extends CodeViewBase {
|
|||||||
public cloneSession(file: NewtonFile) {
|
public cloneSession(file: NewtonFile) {
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
this.activeFile = file;
|
this.activeFile = file;
|
||||||
let session = this.aceApi.createEditSession(file.session.getValue());
|
let session = this.aceApi.createEditSession(file.session.getValue());
|
||||||
session["$config"] = {
|
|
||||||
"lsp": {
|
|
||||||
"filePath": file.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session.setMode( file.session.getMode()["$id"] );
|
session.setMode( file.session.getMode()["$id"] );
|
||||||
session.setUseWrapMode(true);
|
|
||||||
|
|
||||||
this.editor.setSession(session);
|
this.editor.setSession(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,4 +7,4 @@
|
|||||||
<code-view [mode]="'mini-map'"></code-view>
|
<code-view [mode]="'mini-map'"></code-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
<div>
|
@@ -1,5 +1,5 @@
|
|||||||
import { Component, DestroyRef, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
import { EditorsService } from '../common/services/editor/editors.service';
|
import { EditorsService } from '../common/services/editor/editors.service';
|
||||||
import { TabsService } from '../common/services/editor/tabs/tabs.service';
|
import { TabsService } from '../common/services/editor/tabs/tabs.service';
|
||||||
@@ -29,7 +29,7 @@ import { ServiceMessage } from '../common/types/service-message.type';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class EditorsComponent {
|
export class EditorsComponent {
|
||||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
private unsubscribe: Subject<void> = new Subject();
|
||||||
|
|
||||||
private editorsService: EditorsService = inject(EditorsService);
|
private editorsService: EditorsService = inject(EditorsService);
|
||||||
private tabsService: TabsService = inject(TabsService);
|
private tabsService: TabsService = inject(TabsService);
|
||||||
@@ -37,89 +37,116 @@ export class EditorsComponent {
|
|||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ngAfterViewInit(): void {
|
||||||
this.loadSubscribers();
|
this.loadSubscribers();
|
||||||
this.loadMainSubscribers();
|
this.loadMainSubscribers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ngOnDestroy() {
|
||||||
|
this.unsubscribe.next();
|
||||||
|
this.unsubscribe.complete();
|
||||||
|
}
|
||||||
|
|
||||||
private loadSubscribers() {
|
private loadSubscribers() {
|
||||||
|
|
||||||
this.editorsService.getMessage$().pipe(
|
this.editorsService.getMessage$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((message: ServiceMessage) => {
|
).subscribe((message: ServiceMessage) => {
|
||||||
switch ( message.action ) {
|
if (message.action === "select-left-editor") {
|
||||||
case "select-left-editor":
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
||||||
this.selectLeftEditor(message);
|
if (!editorComponent.leftSiblingUUID) return;
|
||||||
break;
|
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
||||||
case "select-right-editor":
|
siblingComponent.editor.focus()
|
||||||
this.selectRightEditor(message);
|
} else if (message.action === "select-right-editor") {
|
||||||
break;
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
||||||
case "move-session-left":
|
if (!editorComponent.rightSiblingUUID) return;
|
||||||
this.moveSessionLeft(message);
|
let siblingComponent = this.editorsService.get(editorComponent.rightSiblingUUID);
|
||||||
break;
|
siblingComponent.editor.focus()
|
||||||
case "move-session-right":
|
} else if (message.action === "move-session-left") {
|
||||||
this.moveSessionRight(message);
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
||||||
break;
|
if (!editorComponent.leftSiblingUUID) return;
|
||||||
case "set-active-editor":
|
|
||||||
this.setActiveEditor(message);
|
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
||||||
break;
|
let session = editorComponent.editor.getSession();
|
||||||
case "set-tab-to-editor":
|
let siblingSession = siblingComponent.editor.getSession();
|
||||||
this.setTabToEditor(message);
|
|
||||||
break;
|
if (session == siblingSession) return;
|
||||||
case "close-tab":
|
|
||||||
this.closeTab(message);
|
siblingComponent.assignSession(editorComponent.activeFile);
|
||||||
break;
|
|
||||||
default:
|
let targetPath = this.tabsService.getRightSiblingTab(
|
||||||
break;
|
editorComponent.activeFile.path
|
||||||
|
)
|
||||||
|
if (targetPath) {
|
||||||
|
editorComponent.assignSession(
|
||||||
|
this.filesService.get(targetPath)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
editorComponent.newFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
siblingComponent.editor.focus()
|
||||||
|
} else if (message.action === "move-session-right") {
|
||||||
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
||||||
|
if (!editorComponent.rightSiblingUUID) return;
|
||||||
|
|
||||||
|
let siblingComponent = this.editorsService.get(editorComponent.rightSiblingUUID);
|
||||||
|
let session = editorComponent.editor.getSession();
|
||||||
|
let siblingSession = siblingComponent.editor.getSession();
|
||||||
|
|
||||||
|
if (session == siblingSession) return;
|
||||||
|
|
||||||
|
siblingComponent.assignSession(editorComponent.activeFile);
|
||||||
|
|
||||||
|
let targetPath = this.tabsService.getRightSiblingTab(
|
||||||
|
editorComponent.activeFile.path
|
||||||
|
)
|
||||||
|
if (targetPath) {
|
||||||
|
editorComponent.assignSession(
|
||||||
|
this.filesService.get(targetPath)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
editorComponent.newFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
siblingComponent.editor.focus()
|
||||||
|
} else if (message.action === "set-active-editor") {
|
||||||
|
this.editorsService.getActiveEditorComponent().removeActiveStyling();
|
||||||
|
this.editorsService.setActiveEditor(message.editorUUID);
|
||||||
|
this.editorsService.getActiveEditorComponent().addActiveStyling();
|
||||||
|
} else if (message.action === "set-tab-to-editor") {
|
||||||
|
let file = this.filesService.get(message.filePath);
|
||||||
|
let editorComponent = this.editorsService.getActiveEditorComponent();
|
||||||
|
let editor = editorComponent.editor;
|
||||||
|
|
||||||
|
editorComponent.assignSession(file);
|
||||||
|
this.editorsService.miniMapView.cloneSession(file);
|
||||||
|
} else if (message.action === "close-tab") {
|
||||||
|
let activeComponent = this.editorsService.getActiveEditorComponent();
|
||||||
|
let editors = this.editorsService.getEditorsAsArray();
|
||||||
|
let file = this.filesService.get(message.filePath);
|
||||||
|
|
||||||
|
for (let i = 0; i < editors.length; i++) {
|
||||||
|
let editorComponent = editors[i];
|
||||||
|
if (editorComponent.editor.session == file.session) {
|
||||||
|
if (activeComponent == editorComponent) {
|
||||||
|
this.editorsService.miniMapView.newFile();
|
||||||
|
}
|
||||||
|
editorComponent.newFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.filesService.delete(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadMainSubscribers() {
|
private loadMainSubscribers() {
|
||||||
window.main.onMenuActions(async (action: string) => {
|
|
||||||
let editorComponent = this.editorsService.getActiveEditorComponent();
|
|
||||||
let editor = editorComponent.editor;
|
|
||||||
|
|
||||||
switch ( action ) {
|
|
||||||
case "new-file":
|
|
||||||
break;
|
|
||||||
case "open-files":
|
|
||||||
editorComponent.openFiles();
|
|
||||||
break;
|
|
||||||
case "save-file":
|
|
||||||
editorComponent.saveFile();
|
|
||||||
break;
|
|
||||||
case "save-file-as":
|
|
||||||
editorComponent.saveFileAs();
|
|
||||||
break;
|
|
||||||
case "cut":
|
|
||||||
editorComponent.cutText();
|
|
||||||
break;
|
|
||||||
case "copy":
|
|
||||||
editorComponent.copyText();
|
|
||||||
break;
|
|
||||||
case "paste":
|
|
||||||
editorComponent.pasteText();
|
|
||||||
break;
|
|
||||||
case "zoom-in":
|
|
||||||
editorComponent.zoomIn()
|
|
||||||
break;
|
|
||||||
case "zoom-out":
|
|
||||||
editorComponent.zoomOut()
|
|
||||||
break;
|
|
||||||
case "open-settings":
|
|
||||||
editor.showSettingsMenu();
|
|
||||||
case "show-about":
|
|
||||||
break;
|
|
||||||
case "quit":
|
|
||||||
window.main.quit();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
editor.execCommand(action);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
window.fs.onLoadFiles(async (paths: []) => {
|
window.fs.onLoadFiles(async (paths: []) => {
|
||||||
for (let i = 0; i < paths.length; i++) {
|
for (let i = 0; i < paths.length; i++) {
|
||||||
let file = new File([], "") as NewtonFile;
|
let file = new File([], "") as NewtonFile;
|
||||||
@@ -165,11 +192,50 @@ export class EditorsComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.fs.onUpdateFilePath(async (path: string) => {
|
window.fs.onUpdateFilePath(async (path: string) => {
|
||||||
console.log("TODO (onUpdateFilePath) :", path);
|
console.log(path);
|
||||||
// this.tabsService.sendMessage(message);
|
// this.tabsService.sendMessage(message);
|
||||||
// this.filesService.sendMessage(message);
|
// this.filesService.sendMessage(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.main.onMenuActions(async (action: string) => {
|
||||||
|
let editorComponent = this.editorsService.getActiveEditorComponent();
|
||||||
|
let editor = editorComponent.editor;
|
||||||
|
|
||||||
|
switch ( action ) {
|
||||||
|
case "new-file":
|
||||||
|
break;
|
||||||
|
case "open-files":
|
||||||
|
editorComponent.openFiles();
|
||||||
|
break;
|
||||||
|
case "save-file":
|
||||||
|
editorComponent.saveFile();
|
||||||
|
break;
|
||||||
|
case "save-file-as":
|
||||||
|
editorComponent.saveFileAs();
|
||||||
|
break;
|
||||||
|
case "cut":
|
||||||
|
editorComponent.cutText();
|
||||||
|
break;
|
||||||
|
case "copy":
|
||||||
|
editorComponent.copyText();
|
||||||
|
break;
|
||||||
|
case "paste":
|
||||||
|
editorComponent.pasteText();
|
||||||
|
break;
|
||||||
|
case "zoom-in":
|
||||||
|
editorComponent.zoomIn()
|
||||||
|
break;
|
||||||
|
case "zoom-out":
|
||||||
|
editorComponent.zoomOut()
|
||||||
|
break;
|
||||||
|
case "open-settings":
|
||||||
|
editor.showSettingsMenu();
|
||||||
|
case "show-about":
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
editor.execCommand(action);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onFileDropped(files: any) {
|
protected onFileDropped(files: any) {
|
||||||
@@ -182,104 +248,4 @@ export class EditorsComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private selectLeftEditor(message: ServiceMessage) {
|
|
||||||
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
||||||
if (!editorComponent.leftSiblingUUID) return;
|
|
||||||
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
|
||||||
siblingComponent.editor.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private selectRightEditor(message: ServiceMessage) {
|
|
||||||
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
||||||
if (!editorComponent.rightSiblingUUID) return;
|
|
||||||
let siblingComponent = this.editorsService.get(editorComponent.rightSiblingUUID);
|
|
||||||
siblingComponent.editor.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private moveSessionLeft(message: ServiceMessage) {
|
|
||||||
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
||||||
if (!editorComponent.leftSiblingUUID) return;
|
|
||||||
|
|
||||||
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
|
||||||
this.moveSession("left", editorComponent, siblingComponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private moveSessionRight(message: ServiceMessage) {
|
|
||||||
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
||||||
if (!editorComponent.rightSiblingUUID) return;
|
|
||||||
|
|
||||||
let siblingComponent = this.editorsService.get(editorComponent.rightSiblingUUID);
|
|
||||||
this.moveSession("right", editorComponent, siblingComponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private moveSession(
|
|
||||||
direction: string,
|
|
||||||
editorComponent: CodeViewComponent,
|
|
||||||
siblingComponent: CodeViewComponent
|
|
||||||
) {
|
|
||||||
let session = editorComponent.editor.getSession();
|
|
||||||
let siblingSession = siblingComponent.editor.getSession();
|
|
||||||
|
|
||||||
if (session == siblingSession) return;
|
|
||||||
|
|
||||||
let targetPath: string = this.tabsService.getRightSiblingTab(
|
|
||||||
editorComponent.activeFile.path
|
|
||||||
);
|
|
||||||
|
|
||||||
siblingComponent.assignSession(editorComponent.activeFile);
|
|
||||||
if (targetPath) {
|
|
||||||
editorComponent.assignSession(
|
|
||||||
this.filesService.get(targetPath)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
editorComponent.newFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
siblingComponent.editor.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private setActiveEditor(message: ServiceMessage) {
|
|
||||||
this.editorsService.getActiveEditorComponent().removeActiveStyling();
|
|
||||||
this.editorsService.setActiveEditor(message.editorUUID);
|
|
||||||
this.editorsService.getActiveEditorComponent().addActiveStyling();
|
|
||||||
}
|
|
||||||
private setTabToEditor(message: ServiceMessage) {
|
|
||||||
let file = this.filesService.get(message.filePath);
|
|
||||||
let editorComponent = this.editorsService.getActiveEditorComponent();
|
|
||||||
let editor = editorComponent.editor;
|
|
||||||
|
|
||||||
editorComponent.assignSession(file);
|
|
||||||
this.editorsService.miniMapView.cloneSession(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
private closeTab(message: ServiceMessage) {
|
|
||||||
let activeComponent = this.editorsService.getActiveEditorComponent();
|
|
||||||
let editors = this.editorsService.getEditorsAsArray();
|
|
||||||
let file = this.filesService.get(message.filePath);
|
|
||||||
|
|
||||||
for (let i = 0; i < editors.length; i++) {
|
|
||||||
let editorComponent = editors[i];
|
|
||||||
|
|
||||||
if (editorComponent.editor.session !== file.session) continue;
|
|
||||||
|
|
||||||
let targetFile = this.filesService.getPreviousFile(file.path)
|
|
||||||
if (targetFile && (targetFile.path !== message.filePath)) {
|
|
||||||
editorComponent.assignSession(targetFile);
|
|
||||||
if (activeComponent == editorComponent) {
|
|
||||||
this.editorsService.miniMapView.cloneSession(targetFile);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
editorComponent.newFile();
|
|
||||||
if (activeComponent == editorComponent) {
|
|
||||||
this.editorsService.miniMapView.newFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
activeComponent.lspManagerService.closeDocument(file.session);
|
|
||||||
this.filesService.unset(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
import { Component, DestroyRef, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
|
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.s
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class InfoBarComponent {
|
export class InfoBarComponent {
|
||||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
private unsubscribe: Subject<void> = new Subject();
|
||||||
|
|
||||||
private infoBarService: InfoBarService = inject(InfoBarService);
|
private infoBarService: InfoBarService = inject(InfoBarService);
|
||||||
|
|
||||||
@@ -28,14 +28,18 @@ export class InfoBarComponent {
|
|||||||
ftype: string = "";
|
ftype: string = "";
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {}
|
||||||
|
|
||||||
|
|
||||||
|
private ngAfterViewInit(): void {
|
||||||
this.loadSubscribers();
|
this.loadSubscribers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private loadSubscribers() {
|
private loadSubscribers() {
|
||||||
|
|
||||||
this.infoBarService.updateInfoBarFPath$().pipe(
|
this.infoBarService.updateInfoBarFPath$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((fpath: string) => {
|
).subscribe((fpath: string) => {
|
||||||
this.fpath = fpath;
|
this.fpath = fpath;
|
||||||
let _path = fpath;
|
let _path = fpath;
|
||||||
@@ -48,19 +52,19 @@ export class InfoBarComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.infoBarService.updateInfoBarCursorPos$().pipe(
|
this.infoBarService.updateInfoBarCursorPos$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((cursorPos: any) => {
|
).subscribe((cursorPos: any) => {
|
||||||
this.cursorPos = `${cursorPos.row + 1}:${cursorPos.column}`;
|
this.cursorPos = `${cursorPos.row + 1}:${cursorPos.column}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.infoBarService.updateInfoBarEncodeing$().pipe(
|
this.infoBarService.updateInfoBarEncodeing$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((encodeing: string) => {
|
).subscribe((encodeing: string) => {
|
||||||
this.encodeing = encodeing;
|
this.encodeing = encodeing;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.infoBarService.updateInfoBarFType$().pipe(
|
this.infoBarService.updateInfoBarFType$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((ftype: string) => {
|
).subscribe((ftype: string) => {
|
||||||
let mode = ftype.split("/");
|
let mode = ftype.split("/");
|
||||||
this.ftype = mode[ mode.length - 1 ];
|
this.ftype = mode[ mode.length - 1 ];
|
||||||
|
@@ -35,21 +35,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mt-2 md-2">
|
<div class="row mt-2 md-2">
|
||||||
<div class="col col-sm" [hidden]="!lspManagerService.workspaceFolder">
|
|
||||||
<button class="btn btn-sm btn-dark" (click)="createLanguageClient()">Create Language Client</button>
|
|
||||||
<button class="btn btn-sm btn-dark" (click)="closeLanguageClient()">Close Language Client</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
Target Editor: <label [innerText]="editor?.id || '...'"></label>
|
Target Editor: <label [innerText]="editor?.id || 'Editor...'"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm" [hidden]="!lspManagerService.workspaceFolder">
|
|
||||||
<button class="btn btn-sm btn-dark"
|
|
||||||
(click)="registerEditorToLanguageClient()">
|
|
||||||
Register Editor To LSP
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
Active Editor Session:
|
Active Editor Session:
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,12 +1,5 @@
|
|||||||
import {
|
import { Component, ChangeDetectorRef, ElementRef, HostBinding, ViewChild, inject } from '@angular/core';
|
||||||
Component,
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
ChangeDetectorRef,
|
|
||||||
DestroyRef,
|
|
||||||
ElementRef,
|
|
||||||
HostBinding,
|
|
||||||
ViewChild,
|
|
||||||
inject } from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
|
|
||||||
import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service';
|
import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service';
|
||||||
|
|
||||||
@@ -30,8 +23,8 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class LspManagerComponent {
|
export class LspManagerComponent {
|
||||||
readonly #destroyRef = inject(DestroyRef);
|
private unsubscribe: Subject<void> = new Subject();
|
||||||
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
|
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
|
||||||
|
|
||||||
lspManagerService: LspManagerService = inject(LspManagerService);
|
lspManagerService: LspManagerService = inject(LspManagerService);
|
||||||
|
|
||||||
@@ -41,44 +34,39 @@ export class LspManagerComponent {
|
|||||||
lspTextEditor: any;
|
lspTextEditor: any;
|
||||||
innerEditor: any;
|
innerEditor: any;
|
||||||
editor: any;
|
editor: any;
|
||||||
activeFile: any;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.loadSubscribers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ngAfterViewInit(): void {
|
private ngAfterViewInit(): void {
|
||||||
this.mapEditorsAndLoadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
private mapEditorsAndLoadConfig() {
|
|
||||||
this.lspTextEditor = this.lspEditorComponent.editor;
|
this.lspTextEditor = this.lspEditorComponent.editor;
|
||||||
this.innerEditor = this.sessionEditorComponent.editor;
|
this.innerEditor = this.sessionEditorComponent.editor;
|
||||||
|
|
||||||
this.lspTextEditor.on("input", () => {
|
|
||||||
this.lspManagerService.lspConfigDataStr =
|
|
||||||
this.lspTextEditor.session.getValue();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.lspManagerService.loadLspConfigData().then((lspConfigData) => {
|
this.lspManagerService.loadLspConfigData().then((lspConfigData) => {
|
||||||
this.lspTextEditor.session.setMode("ace/mode/json");
|
this.lspTextEditor.session.setMode("ace/mode/json");
|
||||||
this.lspTextEditor.session.setValue(lspConfigData);
|
this.lspTextEditor.session.setValue(lspConfigData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.loadSubscribers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ngOnDestroy() {
|
||||||
|
this.unsubscribe.next();
|
||||||
|
this.unsubscribe.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadSubscribers() {
|
private loadSubscribers() {
|
||||||
this.lspManagerService.getMessage$().pipe(
|
this.lspManagerService.getMessage$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((message: ServiceMessage) => {
|
).subscribe((message: ServiceMessage) => {
|
||||||
if (message.action === "toggle-lsp-manager") {
|
if (message.action === "toggle-lsp-manager") {
|
||||||
this.toggleLspManager(message);
|
this.toggleLspManager(message);
|
||||||
} else if (message.action === "set-active-editor") {
|
} else if (message.action === "set-active-editor") {
|
||||||
this.setActiveEditor(message);
|
this.setActiveEditor(message);
|
||||||
} else if (message.action === "editor-update") {
|
|
||||||
this.editorUpdate(message);
|
|
||||||
} else if (message.action === "close-file") {
|
|
||||||
this.closeFile(message);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -95,19 +83,6 @@ export class LspManagerComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public createLanguageClient() {
|
|
||||||
let mode = this.lspManagerService.getMode(this.editor.session);
|
|
||||||
this.lspManagerService.createLanguageProviderWithClientServer(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public closeLanguageClient() {
|
|
||||||
let mode = this.lspManagerService.getMode(this.editor.session);
|
|
||||||
this.lspManagerService.closeLanguageProviderWithClientServer(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public registerEditorToLanguageClient() {
|
|
||||||
this.lspManagerService.registerEditorToLSPClient(this.editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public globalLspManagerKeyHandler(event: any) {
|
public globalLspManagerKeyHandler(event: any) {
|
||||||
@@ -128,33 +103,15 @@ export class LspManagerComponent {
|
|||||||
|
|
||||||
// Note: hack for issue with setActiveEditor TODO
|
// Note: hack for issue with setActiveEditor TODO
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.innerEditor.setSession(this.editor.getSession());
|
this.innerEditor.setSession(this.editor.session);
|
||||||
}, 10);
|
}, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setActiveEditor(message: ServiceMessage) {
|
private setActiveEditor(message: ServiceMessage) {
|
||||||
this.editor = message.rawData.editor;
|
this.editor = message.rawData;
|
||||||
this.activeFile = message.rawData.activeFile;
|
|
||||||
|
|
||||||
// TODO: figure out why this doesn't update the session consistently...
|
// TODO: figure out why this doesn't update the session consistently...
|
||||||
// It seems maybe bound to visible state as change detector ref didn't help either.
|
// It seems maybe bound to visible state as change detector ref didn't help either.
|
||||||
// this.innerEditor.setSession(this.editor.session);
|
// this.innerEditor.setSession(this.editor.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private editorUpdate(message: ServiceMessage) {
|
|
||||||
if (
|
|
||||||
!this.editor ||
|
|
||||||
!message.rawData.activeFile
|
|
||||||
) return;
|
|
||||||
|
|
||||||
this.editor.setSession(message.rawData.editor.getSession())
|
|
||||||
this.activeFile = message.rawData.activeFile;
|
|
||||||
|
|
||||||
this.lspManagerService.registerSession(this.editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private closeFile(message: ServiceMessage) {
|
|
||||||
this.lspManagerService.closeDocument(message.rawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@@ -1,10 +1,5 @@
|
|||||||
import {
|
import { Component, HostBinding, inject } from '@angular/core';
|
||||||
Component,
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
DestroyRef,
|
|
||||||
HostBinding,
|
|
||||||
inject
|
|
||||||
} from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
|
|
||||||
import { MarkdownPreviewService } from '../../common/services/editor/markdown-preview/markdown-preview.service';
|
import { MarkdownPreviewService } from '../../common/services/editor/markdown-preview/markdown-preview.service';
|
||||||
|
|
||||||
@@ -24,7 +19,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class MarkdownPreviewComponent {
|
export class MarkdownPreviewComponent {
|
||||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
private unsubscribe: Subject<void> = new Subject();
|
||||||
|
|
||||||
private markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
|
private markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
|
||||||
|
|
||||||
@@ -37,22 +32,26 @@ export class MarkdownPreviewComponent {
|
|||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ngAfterViewInit(): void {
|
||||||
this.loadSubscribers();
|
this.loadSubscribers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ngOnDestroy() {
|
||||||
|
this.unsubscribe.next();
|
||||||
|
this.unsubscribe.complete();
|
||||||
|
}
|
||||||
|
|
||||||
private loadSubscribers() {
|
private loadSubscribers() {
|
||||||
this.markdownPreviewService.getMessage$().pipe(
|
this.markdownPreviewService.getMessage$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((message: ServiceMessage) => {
|
).subscribe((message: ServiceMessage) => {
|
||||||
switch ( message.action ) {
|
if (message.action === "toggle-markdown-preview") {
|
||||||
case "toggle-markdown-preview":
|
this.toggleMarkdownPreview(message);
|
||||||
this.toggleMarkdownPreview(message);
|
} else if (message.action === "set-active-editor") {
|
||||||
break;
|
this.setActiveEditor(message);
|
||||||
case "set-active-editor":
|
|
||||||
this.setActiveEditor(message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,5 @@
|
|||||||
import {
|
import { Component, ElementRef, HostBinding, Input, ViewChild, inject } from '@angular/core';
|
||||||
Component,
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
DestroyRef,
|
|
||||||
ElementRef,
|
|
||||||
HostBinding,
|
|
||||||
Input,
|
|
||||||
ViewChild,
|
|
||||||
inject
|
|
||||||
} from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
|
|
||||||
import { SearchReplaceService } from '../../common/services/editor/search-replace/search-replace.service';
|
import { SearchReplaceService } from '../../common/services/editor/search-replace/search-replace.service';
|
||||||
|
|
||||||
@@ -28,7 +20,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class SearchReplaceComponent {
|
export class SearchReplaceComponent {
|
||||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
private unsubscribe: Subject<void> = new Subject();
|
||||||
|
|
||||||
private searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
|
private searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
|
||||||
|
|
||||||
@@ -53,22 +45,26 @@ export class SearchReplaceComponent {
|
|||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ngAfterViewInit(): void {
|
||||||
this.loadSubscribers();
|
this.loadSubscribers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ngOnDestroy() {
|
||||||
|
this.unsubscribe.next();
|
||||||
|
this.unsubscribe.complete();
|
||||||
|
}
|
||||||
|
|
||||||
private loadSubscribers() {
|
private loadSubscribers() {
|
||||||
this.searchReplaceService.getMessage$().pipe(
|
this.searchReplaceService.getMessage$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((message: ServiceMessage) => {
|
).subscribe((message: ServiceMessage) => {
|
||||||
switch ( message.action ) {
|
if (message.action === "toggle-search-replace") {
|
||||||
case "toggle-search-replace":
|
this.toggleSearchReplace(message);
|
||||||
this.toggleSearchReplace(message);
|
} else if (message.action === "set-active-editor") {
|
||||||
break;
|
this.setActiveEditor(message);
|
||||||
case "set-active-editor":
|
|
||||||
this.setActiveEditor(message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -42,7 +42,6 @@
|
|||||||
margin-left: 2em;
|
margin-left: 2em;
|
||||||
margin-right: 2em;
|
margin-right: 2em;
|
||||||
font-size: 4em;
|
font-size: 4em;
|
||||||
align-self: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-button {
|
.close-button {
|
||||||
|
@@ -1,12 +1,7 @@
|
|||||||
import {
|
import { Component, ChangeDetectorRef, inject } from '@angular/core';
|
||||||
Component,
|
|
||||||
ChangeDetectorRef,
|
|
||||||
DestroyRef,
|
|
||||||
inject
|
|
||||||
} from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
|
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
import { TabsService } from '../../common/services/editor/tabs/tabs.service';
|
import { TabsService } from '../../common/services/editor/tabs/tabs.service';
|
||||||
|
|
||||||
@@ -29,7 +24,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class TabsComponent {
|
export class TabsComponent {
|
||||||
readonly #destroyRef = inject(DestroyRef);
|
private unsubscribe: Subject<void> = new Subject();
|
||||||
|
|
||||||
private tabsService: TabsService = inject(TabsService);
|
private tabsService: TabsService = inject(TabsService);
|
||||||
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
|
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
|
||||||
@@ -38,36 +33,36 @@ export class TabsComponent {
|
|||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private ngAfterViewInit(): void {
|
||||||
this.loadSubscribers();
|
this.loadSubscribers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ngOnDestroy(): void {
|
||||||
|
this.unsubscribe.next();
|
||||||
|
this.unsubscribe.complete();
|
||||||
|
}
|
||||||
|
|
||||||
private loadSubscribers() {
|
private loadSubscribers() {
|
||||||
this.tabsService.getMessage$().pipe(
|
this.tabsService.getMessage$().pipe(
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
takeUntil(this.unsubscribe)
|
||||||
).subscribe((message: ServiceMessage) => {
|
).subscribe((message: ServiceMessage) => {
|
||||||
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
if (message.action === "create-tab") {
|
||||||
|
this.createTab(message.fileName, message.fileUUID, message.filePath);
|
||||||
switch ( message.action ) {
|
} else if (message.action === "file-changed") {
|
||||||
case "create-tab":
|
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
||||||
this.createTab(message.fileName, message.fileUUID, message.filePath);
|
elm.classList.add("file-changed");
|
||||||
break;
|
elm.classList.remove("file-deleted");
|
||||||
case "file-changed":
|
} else if (message.action === "file-deleted") {
|
||||||
elm.classList.add("file-changed");
|
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
||||||
elm.classList.remove("file-deleted");
|
elm.classList.add("file-deleted");
|
||||||
break;
|
elm.classList.remove("file-changed");
|
||||||
case "file-deleted":
|
} else if (message.action === "file-saved") {
|
||||||
elm.classList.add("file-deleted");
|
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
||||||
elm.classList.remove("file-changed");
|
elm.classList.remove("file-deleted");
|
||||||
break;
|
elm.classList.remove("file-changed");
|
||||||
case "file-saved":
|
|
||||||
elm.classList.remove("file-deleted");
|
|
||||||
elm.classList.remove("file-changed");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
<div class="col">
|
|
||||||
<div class="row">
|
|
||||||
<div class="terminal-container" #terminalElm>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1,137 +0,0 @@
|
|||||||
import {
|
|
||||||
Component,
|
|
||||||
DestroyRef,
|
|
||||||
ElementRef,
|
|
||||||
HostBinding,
|
|
||||||
ViewChild,
|
|
||||||
inject
|
|
||||||
} from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
|
|
||||||
// import { Terminal } from 'xterm';
|
|
||||||
import { Terminal } from '@xterm/xterm';
|
|
||||||
// import { FitAddon } from 'xterm-addon-fit';
|
|
||||||
|
|
||||||
import { TerminalService } from '../../common/services/editor/terminal/terminal.service';
|
|
||||||
|
|
||||||
import { ServiceMessage } from '../../common/types/service-message.type';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'terminal',
|
|
||||||
standalone: true,
|
|
||||||
imports: [
|
|
||||||
],
|
|
||||||
templateUrl: './terminal.component.html',
|
|
||||||
styleUrl: './terminal.component.css',
|
|
||||||
host: {
|
|
||||||
'class': 'row terminal',
|
|
||||||
"(keyup)": "globalTerminalKeyHandler($event)"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
export class TerminalComponent {
|
|
||||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
|
||||||
|
|
||||||
private terminalService: TerminalService = inject(TerminalService);
|
|
||||||
private terminal: Terminal = new Terminal();
|
|
||||||
|
|
||||||
@HostBinding("class.hidden") isHidden: boolean = true;
|
|
||||||
@ViewChild("terminalElm") terminalElm!: ElementRef;
|
|
||||||
|
|
||||||
private editor!: any;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.loadSubscribers();
|
|
||||||
this.loadMainSubscribers();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ngAfterViewInit(): void {
|
|
||||||
this.loadTerminal();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: https://stackoverflow.com/questions/63390143/how-do-i-connect-xterm-jsin-electron-to-a-real-working-command-prompt
|
|
||||||
private loadTerminal() {
|
|
||||||
// const fitAddon = new FitAddon();
|
|
||||||
// this.terminal.loadAddon(fitAddon);
|
|
||||||
|
|
||||||
this.terminal.open(this.terminalElm.nativeElement);
|
|
||||||
this.terminal.onData(e => {
|
|
||||||
console.log(e);
|
|
||||||
// ipcRenderer.send("terminal-into", e);
|
|
||||||
// window.main.quit();
|
|
||||||
} );
|
|
||||||
|
|
||||||
// ipcRenderer.on('terminal-actions', (event, data) => {
|
|
||||||
// this.terminal.write(data);
|
|
||||||
// })
|
|
||||||
|
|
||||||
// Make the terminal's size and geometry fit the size of #terminal-container
|
|
||||||
// fitAddon.fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private loadSubscribers() {
|
|
||||||
this.terminalService.getMessage$().pipe(
|
|
||||||
takeUntilDestroyed(this.#destroyRef)
|
|
||||||
).subscribe((message: ServiceMessage) => {
|
|
||||||
switch ( message.action ) {
|
|
||||||
case "toggle-terminal":
|
|
||||||
this.toggleTerminal(message);
|
|
||||||
break;
|
|
||||||
case "set-active-editor":
|
|
||||||
this.setActiveEditor(message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private loadMainSubscribers() {
|
|
||||||
window.main.onTerminalActions(async (action: string) => {
|
|
||||||
this.terminal.write(action);
|
|
||||||
// switch ( action ) {
|
|
||||||
// case "terminal-actions":
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private toggleTerminal(message: ServiceMessage) {
|
|
||||||
this.isHidden = !this.isHidden;
|
|
||||||
|
|
||||||
if (this.isHidden) {
|
|
||||||
this.editor.focus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setTimeout(() => {
|
|
||||||
// }, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private setActiveEditor(message: ServiceMessage) {
|
|
||||||
if (this.editor == message.rawData) return;
|
|
||||||
|
|
||||||
this.editor = message.rawData;
|
|
||||||
|
|
||||||
if (this.isHidden) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public hideTerminal() {
|
|
||||||
this.isHidden = true;
|
|
||||||
this.editor.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public globalTerminalKeyHandler(event: any) {
|
|
||||||
if (event.ctrlKey && event.key === ".") {
|
|
||||||
this.hideTerminal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@@ -61,15 +61,3 @@
|
|||||||
.ace_sb-h {
|
.ace_sb-h {
|
||||||
width: 0.8em !important;
|
width: 0.8em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.ace_cursor {
|
|
||||||
color: rgba(249, 148, 6, 0.64);
|
|
||||||
animation: blinker 1s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blinker {
|
|
||||||
50% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -10,10 +10,6 @@ body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul, li {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* IDs */
|
/* IDs */
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -20,7 +20,6 @@ declare global {
|
|||||||
},
|
},
|
||||||
main: {
|
main: {
|
||||||
onMenuActions: (arg0: any) => Promise<string>,
|
onMenuActions: (arg0: any) => Promise<string>,
|
||||||
onTerminalActions: (arg0: any) => Promise<string>,
|
|
||||||
quit: any,
|
quit: any,
|
||||||
toggleFullScreen: any,
|
toggleFullScreen: any,
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user