Compare commits
16 Commits
ec841445ed
...
main
Author | SHA1 | Date | |
---|---|---|---|
73f25aae1c | |||
3c3a5d2f50 | |||
d44e7d4e51 | |||
60289953ec | |||
df5f2d481a | |||
2ede33f3c2 | |||
822d778008 | |||
90c8c9b3ee | |||
79adb86d25 | |||
a0914e8096 | |||
a4d602f98a | |||
d6f766753c | |||
ae60905eb4 | |||
080cc22841 | |||
c5fdab59f6 | |||
ab17e48338 |
@@ -1,9 +1,10 @@
|
||||
const { app } = require('electron');
|
||||
|
||||
|
||||
let startType = "build";
|
||||
let isDebug = false;
|
||||
let args = [];
|
||||
let startType = "build";
|
||||
let ipcPort = "4563";
|
||||
let isDebug = false;
|
||||
let args = [];
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +18,13 @@ const loadKWArgs = () => {
|
||||
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");
|
||||
if (hasDebug) {
|
||||
isDebug = app.commandLine.getSwitchValue("app-debug");
|
||||
@@ -25,38 +33,29 @@ const loadKWArgs = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const loadVArgs = () => {
|
||||
console.log("\n\nStart VArgs:");
|
||||
|
||||
const filterOutLaunchAndKWArgs = () => {
|
||||
if (
|
||||
process.argv[0].endsWith("electron")
|
||||
) {
|
||||
process.argv = process.argv.slice(2);
|
||||
}
|
||||
|
||||
if (
|
||||
process.argv[0].endsWith("/newton") ||
|
||||
process.argv[0].endsWith(".AppImage")
|
||||
) {
|
||||
do {
|
||||
process.argv = process.argv.slice(1);
|
||||
}
|
||||
|
||||
if ( process.argv.length > 0 && (
|
||||
process.argv[0].includes("--trace-warnings") ||
|
||||
process.argv[0].includes("--start-as")
|
||||
} while (
|
||||
process.argv.length > 0 &&
|
||||
(
|
||||
process.argv[0].endsWith("/newton") ||
|
||||
process.argv[0].endsWith(".AppImage") ||
|
||||
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.forEach((val, index, array) => {
|
||||
console.log(index + ': ' + val);
|
||||
@@ -67,6 +66,7 @@ const loadVArgs = () => {
|
||||
|
||||
const loadArgs = () => {
|
||||
loadKWArgs();
|
||||
filterOutLaunchAndKWArgs();
|
||||
loadVArgs();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,10 @@ const getDebugMode = () => {
|
||||
return isDebug;
|
||||
}
|
||||
|
||||
const getIpcPort = () => {
|
||||
return ipcPort;
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
argsParser: {
|
||||
@@ -90,5 +94,6 @@ module.exports = {
|
||||
getArgs: getArgs,
|
||||
getStartType: getStartType,
|
||||
getDebugMode: getDebugMode,
|
||||
getIpcPort: getIpcPort,
|
||||
}
|
||||
};
|
@@ -114,7 +114,6 @@ const chooseFolder = () => {
|
||||
console.debug("Canceled folder selection...");
|
||||
return "";
|
||||
}
|
||||
console.log(response)
|
||||
|
||||
return response.filePaths[0];
|
||||
});
|
||||
|
@@ -8,12 +8,17 @@ const fetch = require('electron-fetch').default
|
||||
const IPC_SERVER_IP = "127.0.0.1";
|
||||
let window = null;
|
||||
let ipcServer = null;
|
||||
let ipcServerPort = "4563";
|
||||
let ipcServerURL = `http://${IPC_SERVER_IP}:${ipcServerPort}`;
|
||||
let ipcServerPort = "";
|
||||
let ipcServerURL = "";
|
||||
|
||||
|
||||
const setWindow = (win) => {
|
||||
window = win;
|
||||
window = win;
|
||||
}
|
||||
|
||||
const configure = (ipcPort) => {
|
||||
ipcServerPort = ipcPort;
|
||||
ipcServerURL = `http://${IPC_SERVER_IP}:${ipcServerPort}`;
|
||||
}
|
||||
|
||||
const loadIPCServer = (fpath) => {
|
||||
@@ -47,7 +52,8 @@ const loadIPCServer = (fpath) => {
|
||||
}
|
||||
|
||||
const isIPCServerUp = async () => {
|
||||
const response = await fetch(`${ipcServerURL}/is-up`).catch((err) => {
|
||||
const response = await fetch(`${ipcServerURL}/is-up`)
|
||||
.catch((err) => {
|
||||
console.debug("IPCServer (status) : Not up; okay to start.");
|
||||
return {
|
||||
text: () => {
|
||||
@@ -73,9 +79,10 @@ const sendFilesToIPC = async (files) => {
|
||||
|
||||
module.exports = {
|
||||
newtonIPC: {
|
||||
setWindow: setWindow,
|
||||
configure: configure,
|
||||
loadIPCServer: loadIPCServer,
|
||||
isIPCServerUp: isIPCServerUp,
|
||||
sendFilesToIPC: sendFilesToIPC,
|
||||
setWindow: setWindow
|
||||
}
|
||||
};
|
@@ -80,6 +80,7 @@ app.whenReady().then(async () => {
|
||||
loadProcessSignalHandlers();
|
||||
newton.args.loadArgs();
|
||||
|
||||
newton.ipc.configure( newton.args.getIpcPort() );
|
||||
if ( !await newton.ipc.isIPCServerUp() ) {
|
||||
newton.ipc.loadIPCServer();
|
||||
} else {
|
||||
|
@@ -22,6 +22,9 @@ const load = (win) => {
|
||||
}, {
|
||||
label: 'Terminal',
|
||||
click: () => {}
|
||||
}, {
|
||||
label: "Quit",
|
||||
click: () => win.webContents.send('menu-actions', "quit")
|
||||
}
|
||||
]
|
||||
}, {
|
||||
|
@@ -33,6 +33,9 @@ const load = (win) => {
|
||||
}, {
|
||||
label: 'Help',
|
||||
click: () => win.webContents.send('menu-actions', "show-about")
|
||||
}, {
|
||||
label: 'Quit',
|
||||
click: () => win.webContents.send('menu-actions', "quit")
|
||||
}
|
||||
];
|
||||
|
||||
|
@@ -9,8 +9,8 @@
|
||||
"main": "newton/main.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"app": "ng build --base-href ./ && electron . --trace-warnings --start-as=build",
|
||||
"electron-start": "electron . --trace-warnings --start-as=build",
|
||||
"app": "ng build --base-href ./ && electron . --trace-warnings --start-as=build --ipc-port=4588",
|
||||
"electron-start": "electron . --trace-warnings --start-as=build --ipc-port=4588",
|
||||
"electron-pack": "ng build --base-href ./ && electron-builder --dir",
|
||||
"electron-dist": "ng build --base-href ./ && electron-builder",
|
||||
"electron-dist-linux": "ng build --base-href ./ && electron-builder --linux deb zip AppImage",
|
||||
@@ -54,7 +54,7 @@
|
||||
"ace-builds": "1.43.0",
|
||||
"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-icons": "1.12.1",
|
||||
"chokidar": "4.0.3",
|
||||
@@ -64,7 +64,6 @@
|
||||
"rxjs": "7.8.0",
|
||||
"socket.io": "4.8.1",
|
||||
"uuid": "11.1.0",
|
||||
"web-tree-sitter": "0.25.8",
|
||||
"zone.js": "0.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -106,4 +105,4 @@
|
||||
"tslib": "2.3.0",
|
||||
"typescript": "5.7.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -13,58 +13,73 @@
|
||||
"alt-socket": "ws://127.0.0.1:9999/?name=java-language-server",
|
||||
"initialization-options": {
|
||||
"bundles": [
|
||||
"intellicode-core.jar"
|
||||
],
|
||||
"workspaceFolders": [
|
||||
"file://{workspace.folder}"
|
||||
],
|
||||
"extendedClientCapabilities": {
|
||||
"classFileContentsSupport": true,
|
||||
"executeClientCommandSupport": true
|
||||
"executeClientCommandSupport": false
|
||||
},
|
||||
"settings": {
|
||||
"java": {
|
||||
"autobuild": {
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
"completion": {
|
||||
"enabled": true,
|
||||
"importOrder": [
|
||||
"java",
|
||||
"javax",
|
||||
"org",
|
||||
"com"
|
||||
]
|
||||
"jdt": {
|
||||
"ls": {
|
||||
"javac": {
|
||||
"enabled": true
|
||||
},
|
||||
"java": {
|
||||
"home": "{user.home}/Portable_Apps/sdks/javasdk/jdk-22.0.2"
|
||||
},
|
||||
"lombokSupport": {
|
||||
"enabled": true
|
||||
},
|
||||
"protobufSupport":{
|
||||
"enabled": true
|
||||
},
|
||||
"androidSupport": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"configuration": {
|
||||
"updateBuildConfiguration": "automatic",
|
||||
"maven": {
|
||||
"userSettings": "{user.home}/.config/jdtls/settings.xml",
|
||||
"globalSettings": "{user.home}/.config/jdtls/settings.xml"
|
||||
"userSettings": "{user.home}/.config/lsps/jdtls/settings.xml",
|
||||
"globalSettings": "{user.home}/.config/lsps/jdtls/settings.xml"
|
||||
},
|
||||
"runtimes": [
|
||||
{
|
||||
"name": "JavaSE-17",
|
||||
"path": "/usr/lib/jvm/default-runtime",
|
||||
"path": "/usr/lib/jvm/java-17-openjdk",
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
"classPath": [
|
||||
"{user.home}/.config/jdtls/m2/repository/**/*-sources.jar",
|
||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*-sources.jar",
|
||||
"lib/**/*-sources.jar"
|
||||
],
|
||||
"docPath": [
|
||||
"{user.home}/.config/jdtls/m2/repository/**/*-javadoc.jar",
|
||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*-javadoc.jar",
|
||||
"lib/**/*-javadoc.jar"
|
||||
],
|
||||
"silentNotification": true,
|
||||
"project": {
|
||||
"encoding": "ignore",
|
||||
"outputPath": "bin",
|
||||
"referencedLibraries": [
|
||||
"lib/**/*.jar",
|
||||
"{user.home}/.config/jdtls/m2/repository/**/*.jar"
|
||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*.jar",
|
||||
"lib/**/*.jar"
|
||||
],
|
||||
"importOnFirstTimeStartup": "automatic",
|
||||
"importHint": true,
|
||||
@@ -74,7 +89,7 @@
|
||||
],
|
||||
"sourcePaths": [
|
||||
"src",
|
||||
"{user.home}/.config/jdtls/m2/repository/**/*.jar"
|
||||
"{user.home}/.config/lsps/jdtls/m2/repository/**/*.jar"
|
||||
]
|
||||
},
|
||||
"sources": {
|
||||
@@ -104,9 +119,9 @@
|
||||
"enabled": true
|
||||
},
|
||||
"version": "",
|
||||
"home": "abs(static/gradle-7.3.3)",
|
||||
"home": "{user.home}/Portable_Apps/sdks/gradle/gradle-9.0.0",
|
||||
"java": {
|
||||
"home": "abs(static/launch_jres/17.0.6-linux-x86_64)"
|
||||
"home": "{user.home}/Portable_Apps/sdks/javasdk/jdk-22.0.2"
|
||||
},
|
||||
"offline": {
|
||||
"enabled": false
|
||||
@@ -132,14 +147,65 @@
|
||||
"downloadSources": true,
|
||||
"updateSnapshots": true
|
||||
},
|
||||
"silentNotification": true,
|
||||
"contentProvider": {
|
||||
"preferred": "fernflower"
|
||||
},
|
||||
"signatureHelp": {
|
||||
"enabled": true,
|
||||
"description": {
|
||||
"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": {
|
||||
"enabled": true
|
||||
},
|
||||
"referencesCodeLens": {
|
||||
"enabled": true
|
||||
},
|
||||
"progressReports": {
|
||||
"enabled": false
|
||||
},
|
||||
"saveActions": {
|
||||
"organizeImports": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,51 +220,36 @@
|
||||
"socket": "ws://127.0.0.1:9999/python",
|
||||
"socket-two": "ws://127.0.0.1:9999/?name=pylsp",
|
||||
"initialization-options": {
|
||||
"pyls": {
|
||||
"plugins": {
|
||||
"pycodestyle": {
|
||||
"enabled": false
|
||||
},
|
||||
"pydocstyle": {
|
||||
"enabled": false
|
||||
},
|
||||
"pyflakes": {
|
||||
"enabled": false
|
||||
},
|
||||
"pylint": {
|
||||
"enabled": false
|
||||
},
|
||||
"mccabe": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"pylsp": {
|
||||
"rope": {
|
||||
"ropeFolder": "{user.home}/.config/lsps/ropeproject"
|
||||
},
|
||||
"plugins": {
|
||||
"pycodestyle": {
|
||||
"enabled": false
|
||||
"ruff": {
|
||||
"enabled": true,
|
||||
"extendSelect": ["I"],
|
||||
"lineLength": 80
|
||||
},
|
||||
"pydocstyle": {
|
||||
"pycodestyle": {
|
||||
"enabled": false
|
||||
},
|
||||
"pyflakes": {
|
||||
"enabled": false
|
||||
},
|
||||
"pylint": {
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
"mccabe": {
|
||||
"enabled": false
|
||||
},
|
||||
"ruff": true,
|
||||
"pylsp_rope": {
|
||||
"rename": true
|
||||
"rename": false
|
||||
},
|
||||
"rope_rename": {
|
||||
"enabled": true
|
||||
"enabled": false
|
||||
},
|
||||
"rope_autoimport": {
|
||||
"enabled": true
|
||||
"enabled": false
|
||||
},
|
||||
"rope_completion": {
|
||||
"enabled": false,
|
||||
@@ -213,7 +264,7 @@
|
||||
"include_function_objects": true,
|
||||
"fuzzy": false
|
||||
},
|
||||
"jedi":{
|
||||
"jedi": {
|
||||
"root_dir": "file://{workspace.folder}",
|
||||
"extra_paths": [
|
||||
"{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages"
|
||||
@@ -248,7 +299,13 @@
|
||||
],
|
||||
"environmentPath": "{user.home}/Portable_Apps/py-venvs/gtk-apps-venv/venv/bin/python",
|
||||
"symbols": {
|
||||
"ignoreFolders": [".nox", ".tox", ".venv", "__pycache__", "venv"],
|
||||
"ignoreFolders": [
|
||||
".nox",
|
||||
".tox",
|
||||
".venv",
|
||||
"__pycache__",
|
||||
"venv"
|
||||
],
|
||||
"maxSymbols": 20
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,11 @@
|
||||
import { Component, inject } from "@angular/core";
|
||||
import {
|
||||
Component,
|
||||
DestroyRef,
|
||||
inject
|
||||
} from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
import * as bootstrap from "bootstrap";
|
||||
|
||||
@@ -25,17 +29,18 @@ import 'ace-diff/dist/ace-diff-dark.min.css';
|
||||
}
|
||||
})
|
||||
export class DiffModalComponent {
|
||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
||||
|
||||
diffModal!: bootstrap.Modal;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.loadDiffView();
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
private loadDiffView() {
|
||||
|
5
src/app/common/constants/button.map.ts
Normal file
5
src/app/common/constants/button.map.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
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 {
|
||||
@HostBinding('class.fileover') fileOver!: boolean;
|
||||
@Output() fileDropped = new EventEmitter<any>();
|
||||
@Output() fileDropped: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
@HostListener('dragover', ['$event'])
|
||||
onDragOver(evt: any) {
|
||||
|
@@ -11,11 +11,11 @@ import {
|
||||
selector: '[draggable-item]'
|
||||
})
|
||||
export class DraggableDirective {
|
||||
@Output() dragStart = new EventEmitter<PointerEvent>();
|
||||
@Output() dragMove = new EventEmitter<PointerEvent>();
|
||||
@Output() dragEnd = new EventEmitter<PointerEvent>();
|
||||
@Output() dragStart: EventEmitter<PointerEvent> = new EventEmitter();
|
||||
@Output() dragMove: EventEmitter<PointerEvent> = new EventEmitter();
|
||||
@Output() dragEnd: EventEmitter<PointerEvent> = new EventEmitter();
|
||||
|
||||
private dragging = false;
|
||||
private dragging: boolean = false;
|
||||
selected: any;
|
||||
|
||||
|
||||
|
@@ -11,9 +11,9 @@ import {
|
||||
selector: '[pane-handle]'
|
||||
})
|
||||
export class PaneHandleDirective {
|
||||
@Output() dragStart = new EventEmitter<PointerEvent>();
|
||||
@Output() dragMove = new EventEmitter<PointerEvent>();
|
||||
@Output() dragEnd = new EventEmitter<PointerEvent>();
|
||||
@Output() dragStart: EventEmitter<PointerEvent> = new EventEmitter();
|
||||
@Output() dragMove: EventEmitter<PointerEvent> = new EventEmitter();
|
||||
@Output() dragEnd: EventEmitter<PointerEvent> = new EventEmitter();
|
||||
|
||||
private dragging: boolean = false;
|
||||
private isHrPane: boolean = false;
|
||||
|
64
src/app/common/services/color-tokenizer.service.ts
Normal file
64
src/app/common/services/color-tokenizer.service.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
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,21 +15,15 @@ import { EditorType } from '../../types/editor.type';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class EditorsService {
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
||||
|
||||
editors: Map<string, CodeViewComponent>;
|
||||
editorSettings: typeof EditorSettings;
|
||||
editors: Map<string, CodeViewComponent> = new Map();
|
||||
editorSettings: typeof EditorSettings = EditorSettings;
|
||||
|
||||
activeEditor!: string;
|
||||
activeEditor: string = "";
|
||||
miniMapView!: CodeViewComponent;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.editorSettings = EditorSettings;
|
||||
this.editors = new Map<string, CodeViewComponent>();
|
||||
}
|
||||
|
||||
|
||||
public getEditorsAsArray(): CodeViewComponent[] {
|
||||
return [...this.editors.values()];
|
||||
}
|
||||
|
@@ -8,14 +8,11 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class InfoBarService {
|
||||
private dataSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
private fpathSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||
private cursorPosSubject: ReplaySubject<any> = new ReplaySubject<any>(1);
|
||||
private encodeingSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||
private ftypeSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||
|
||||
|
||||
constructor() {}
|
||||
private dataSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
||||
private fpathSubject: ReplaySubject<string> = new ReplaySubject(1);
|
||||
private cursorPosSubject: ReplaySubject<any> = new ReplaySubject(1);
|
||||
private encodeingSubject: ReplaySubject<string> = new ReplaySubject(1);
|
||||
private ftypeSubject: ReplaySubject<string> = new ReplaySubject(1);
|
||||
|
||||
|
||||
public setData(data: ServiceMessage): void {
|
||||
|
@@ -1,9 +1,15 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
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 { LanguageProvider } from "ace-linters";
|
||||
|
||||
|
||||
|
||||
import { ServiceMessage } from '../../../types/service-message.type';
|
||||
|
||||
|
||||
@@ -12,17 +18,13 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LspManagerService {
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
||||
|
||||
workspaceFolder: string = "";
|
||||
lspConfigDataStr: string = "";
|
||||
languageProviders: {} = {};
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
public loadLspConfigData(): Promise<string | void> {
|
||||
return this.getLspConfigData().then((lspConfigData: string) => {
|
||||
this.lspConfigDataStr = lspConfigData;
|
||||
@@ -33,12 +35,10 @@ export class LspManagerService {
|
||||
public registerEditorToLSPClient(editor: any) {
|
||||
let mode = this.getMode(editor.session);
|
||||
|
||||
if ( this.languageProviders[mode] ) {
|
||||
this.languageProviders[mode].registerEditor(editor);
|
||||
return;
|
||||
}
|
||||
|
||||
this.languageProviders[mode]?.registerEditor(editor);
|
||||
this.languageProviders[mode]?.registerEditor(
|
||||
editor,
|
||||
editor.session.lspConfig
|
||||
);
|
||||
}
|
||||
|
||||
private getLspConfigData(): Promise<string> {
|
||||
@@ -63,13 +63,13 @@ export class LspManagerService {
|
||||
}
|
||||
|
||||
private getInitializationOptions(mode: string, configData: {}): {} {
|
||||
let _initializationOptions = {};
|
||||
let initializationOptions = {};
|
||||
|
||||
if ( Object.keys(configData).length !== 0 && configData[mode] ) {
|
||||
_initializationOptions = configData[mode]["initialization-options"];
|
||||
initializationOptions = configData[mode]["initialization-options"];
|
||||
}
|
||||
|
||||
return _initializationOptions;
|
||||
return initializationOptions;
|
||||
}
|
||||
|
||||
public createLanguageProviderWithClientServer(mode: string): LanguageProvider {
|
||||
@@ -77,15 +77,15 @@ export class LspManagerService {
|
||||
let servers: LanguageClientConfig[] = [];
|
||||
|
||||
try {
|
||||
let configData = this.parseAndReturnLSPConfigData();
|
||||
let _initializationOptions = this.getInitializationOptions(mode, configData);
|
||||
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( configData[mode]["socket"] ),
|
||||
initializationOptions: _initializationOptions
|
||||
socket: new WebSocket( lspConfigData[mode]["socket"] ),
|
||||
initializationOptions: initializationOptions
|
||||
}
|
||||
];
|
||||
} catch(error) {
|
||||
@@ -96,22 +96,68 @@ export class LspManagerService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.languageProviders[mode] = AceLanguageClient.for(servers);
|
||||
// this.languageProviders[mode].requireFilePath = true;
|
||||
this.languageProviders[mode].changeWorkspaceFolder(this.workspaceFolder);
|
||||
this.languageProviders[mode] = AceLanguageClient.for(
|
||||
servers,
|
||||
{
|
||||
workspacePath: this.workspaceFolder,
|
||||
functionality: {
|
||||
hover: true,
|
||||
completion: {
|
||||
overwriteCompleters: true,
|
||||
lspCompleterOptions: {
|
||||
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];
|
||||
}
|
||||
|
||||
public closeLanguageProviderWithClientServer(mode: string): LanguageProvider {
|
||||
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));
|
||||
return LanguageProvider.create(worker);
|
||||
}
|
||||
|
||||
public setSessionFilePath(session: any, filePath: string = "") {
|
||||
if ( !session || !filePath ) return;
|
||||
let mode = this.getMode(session);
|
||||
public registerSession(editor: any) {
|
||||
let mode = this.getMode(editor.session);
|
||||
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 {
|
||||
|
@@ -9,11 +9,7 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MarkdownPreviewService {
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
||||
|
||||
|
||||
public sendMessage(data: ServiceMessage): void {
|
||||
|
@@ -8,11 +8,7 @@ import { ReplaySubject, Observable } from 'rxjs';
|
||||
})
|
||||
export class FilesModalService {
|
||||
private showFilesModalSubject: ReplaySubject<null> = new ReplaySubject<null>(1);
|
||||
private addFileSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
private addFileSubject: ReplaySubject<string> = new ReplaySubject<string>(1);
|
||||
|
||||
|
||||
public showFilesModal(): void {
|
||||
|
@@ -12,10 +12,6 @@ export class SearchReplaceService {
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
public sendMessage(data: ServiceMessage): void {
|
||||
this.messageSubject.next(data);
|
||||
}
|
||||
|
@@ -11,15 +11,13 @@ import { ServiceMessage } from '../../../types/service-message.type';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TabsService {
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
||||
|
||||
private editorsService: EditorsService = inject(EditorsService);
|
||||
|
||||
tabs: any[] = [];
|
||||
newIndex: number = -1;
|
||||
|
||||
constructor() {}
|
||||
|
||||
|
||||
public push(tabData: {}): void {
|
||||
this.tabs.push(tabData);
|
||||
@@ -45,45 +43,21 @@ export class TabsService {
|
||||
}
|
||||
|
||||
public getLeftSiblingTab(fpath: string): string {
|
||||
let size = this.tabs.length;
|
||||
let i = 0;
|
||||
if (this.tabs.length === 0 ) return;
|
||||
|
||||
for (; i < size; i++) {
|
||||
if (this.tabs[i].path == fpath) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let i = this.tabs.indexOf(fpath);
|
||||
|
||||
if ( !(size > 1) ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if ( i === 0 ) {
|
||||
return this.tabs[i + 1].path;
|
||||
}
|
||||
|
||||
return this.tabs[i - 1].path;
|
||||
(i === 0) ? i = this.tabs.length - 1 : i -= 1;
|
||||
return this.tabs[i].path;
|
||||
}
|
||||
|
||||
public getRightSiblingTab(fpath: string): string {
|
||||
let size = this.tabs.length;
|
||||
let i = 0;
|
||||
if (this.tabs.length === 0 ) return;
|
||||
|
||||
for (; i < size; i++) {
|
||||
if (this.tabs[i].path == fpath) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let i = this.tabs.indexOf(fpath);
|
||||
|
||||
if ( !(size > 1) ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if ( i === (size - 1) ) {
|
||||
return this.tabs[i - 1].path;
|
||||
}
|
||||
|
||||
return this.tabs[i + 1].path;
|
||||
(i === (this.tabs.length - 1)) ? i = 0 : i += 1;
|
||||
return this.tabs[i].path;
|
||||
}
|
||||
|
||||
public setNewTargetIndex(fpath: string): void {
|
||||
|
@@ -5,6 +5,7 @@ import { EditSession, UndoManager } from 'ace-builds';
|
||||
import { getModeForPath } from 'ace-builds/src-noconflict/ext-modelist';
|
||||
|
||||
import { TabsService } from './editor/tabs/tabs.service';
|
||||
import { ColorTokenizerService } from './color-tokenizer.service';
|
||||
|
||||
import { NewtonFile } from '../types/file.type';
|
||||
import { ServiceMessage } from '../types/service-message.type';
|
||||
@@ -15,16 +16,11 @@ import { ServiceMessage } from '../types/service-message.type';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FilesService {
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject(1);
|
||||
|
||||
private tabsService: TabsService = inject(TabsService);
|
||||
|
||||
files: Map<string, NewtonFile>;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.files = new Map<string, NewtonFile>();
|
||||
}
|
||||
files: Map<string, NewtonFile> = new Map();
|
||||
|
||||
|
||||
public get(path: string): NewtonFile {
|
||||
@@ -39,7 +35,25 @@ export class FilesService {
|
||||
return [...this.files.values()];
|
||||
}
|
||||
|
||||
public delete(file: NewtonFile) {
|
||||
public getPreviousFile(path: string): 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();
|
||||
window.fs.closeFile(file.path);
|
||||
this.files.delete(file.path);
|
||||
@@ -93,6 +107,12 @@ export class FilesService {
|
||||
file.session["id"] = path;
|
||||
file.session.setUndoManager( new UndoManager() );
|
||||
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);
|
||||
} catch (error) {
|
||||
|
@@ -1,4 +1,10 @@
|
||||
import { Directive, ElementRef, Input, ViewChild, inject } from '@angular/core';
|
||||
import {
|
||||
Directive,
|
||||
ElementRef,
|
||||
Input,
|
||||
ViewChild,
|
||||
inject
|
||||
} from '@angular/core';
|
||||
import * as uuid from 'uuid';
|
||||
|
||||
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
|
||||
@@ -46,9 +52,8 @@ export class CodeViewBase {
|
||||
public debounceId: number = -1;
|
||||
public debounceWait: number = 800;
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
@ViewChild('contextMenu') contextMenu!: ElementRef;
|
||||
public showContextMenu: boolean = false;
|
||||
|
||||
|
||||
public selectLeftEditor() {
|
||||
@@ -200,8 +205,8 @@ export class CodeViewBase {
|
||||
this.editor.setHighlightGutterLine(false);
|
||||
this.editor.setShowFoldWidgets(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("zero-margin-padding");
|
||||
|
||||
|
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
.editor {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.editor {
|
||||
height: 100vh;
|
||||
width: auto;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
.editor {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
@@ -25,4 +9,25 @@
|
||||
border-style: solid;
|
||||
border-width: thin;
|
||||
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,2 +1,15 @@
|
||||
<div class="editor" #editor >
|
||||
</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>
|
@@ -25,6 +25,7 @@ import { CodeViewBase } from './view.base';
|
||||
import { NewtonFile } from '../../common/types/file.type';
|
||||
import { EditorType } from '../../common/types/editor.type';
|
||||
import { ServiceMessage } from '../../common/types/service-message.type';
|
||||
import { ButtonMap } from '../../common/constants/button.map';
|
||||
|
||||
|
||||
|
||||
@@ -159,10 +160,30 @@ export class CodeViewComponent extends CodeViewBase {
|
||||
this.updateInfoBar();
|
||||
});
|
||||
|
||||
this.editor.on("click", () => {
|
||||
this.editor.on("click", (event) => {
|
||||
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.updateInfoBar();
|
||||
});
|
||||
@@ -182,6 +203,18 @@ 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", () => {
|
||||
if (this.debounceId) { clearTimeout(this.debounceId); }
|
||||
this.setDebounceTimeout();
|
||||
@@ -207,6 +240,28 @@ 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) {
|
||||
if (!file) return;
|
||||
|
||||
@@ -217,10 +272,17 @@ export class CodeViewComponent extends CodeViewBase {
|
||||
public cloneSession(file: NewtonFile) {
|
||||
if (!file) return;
|
||||
|
||||
this.activeFile = file;
|
||||
let session = this.aceApi.createEditSession(file.session.getValue());
|
||||
this.activeFile = file;
|
||||
let session = this.aceApi.createEditSession(file.session.getValue());
|
||||
session["$config"] = {
|
||||
"lsp": {
|
||||
"filePath": file.path
|
||||
}
|
||||
}
|
||||
|
||||
session.setMode( file.session.getMode()["$id"] );
|
||||
session.setUseWrapMode(true);
|
||||
|
||||
this.editor.setSession(session);
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { Component, DestroyRef, inject } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
import { EditorsService } from '../common/services/editor/editors.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 {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
||||
|
||||
private editorsService: EditorsService = inject(EditorsService);
|
||||
private tabsService: TabsService = inject(TabsService);
|
||||
@@ -37,117 +37,89 @@ export class EditorsComponent {
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.loadSubscribers();
|
||||
this.loadMainSubscribers();
|
||||
}
|
||||
|
||||
private ngOnDestroy() {
|
||||
this.unsubscribe.next();
|
||||
this.unsubscribe.complete();
|
||||
}
|
||||
|
||||
private loadSubscribers() {
|
||||
|
||||
this.editorsService.getMessage$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((message: ServiceMessage) => {
|
||||
if (message.action === "select-left-editor") {
|
||||
let editorComponent = this.editorsService.get(message.editorUUID);
|
||||
if (!editorComponent.leftSiblingUUID) return;
|
||||
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
||||
siblingComponent.editor.focus()
|
||||
} else if (message.action === "select-right-editor") {
|
||||
let editorComponent = this.editorsService.get(message.editorUUID);
|
||||
if (!editorComponent.rightSiblingUUID) return;
|
||||
let siblingComponent = this.editorsService.get(editorComponent.rightSiblingUUID);
|
||||
siblingComponent.editor.focus()
|
||||
} else if (message.action === "move-session-left") {
|
||||
let editorComponent = this.editorsService.get(message.editorUUID);
|
||||
if (!editorComponent.leftSiblingUUID) return;
|
||||
|
||||
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
||||
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 === "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();
|
||||
}
|
||||
}
|
||||
|
||||
activeComponent.lspManagerService.closeDocument(file.session);
|
||||
this.filesService.delete(file);
|
||||
switch ( message.action ) {
|
||||
case "select-left-editor":
|
||||
this.selectLeftEditor(message);
|
||||
break;
|
||||
case "select-right-editor":
|
||||
this.selectRightEditor(message);
|
||||
break;
|
||||
case "move-session-left":
|
||||
this.moveSessionLeft(message);
|
||||
break;
|
||||
case "move-session-right":
|
||||
this.moveSessionRight(message);
|
||||
break;
|
||||
case "set-active-editor":
|
||||
this.setActiveEditor(message);
|
||||
break;
|
||||
case "set-tab-to-editor":
|
||||
this.setTabToEditor(message);
|
||||
break;
|
||||
case "close-tab":
|
||||
this.closeTab(message);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
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: []) => {
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
let file = new File([], "") as NewtonFile;
|
||||
@@ -198,45 +170,6 @@ export class EditorsComponent {
|
||||
// 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) {
|
||||
@@ -249,4 +182,104 @@ 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, inject } from '@angular/core';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { Component, DestroyRef, inject } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
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 {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
||||
|
||||
private infoBarService: InfoBarService = inject(InfoBarService);
|
||||
|
||||
@@ -28,18 +28,14 @@ export class InfoBarComponent {
|
||||
ftype: string = "";
|
||||
|
||||
|
||||
constructor() {}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
constructor() {
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
|
||||
private loadSubscribers() {
|
||||
|
||||
this.infoBarService.updateInfoBarFPath$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((fpath: string) => {
|
||||
this.fpath = fpath;
|
||||
let _path = fpath;
|
||||
@@ -52,19 +48,19 @@ export class InfoBarComponent {
|
||||
});
|
||||
|
||||
this.infoBarService.updateInfoBarCursorPos$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((cursorPos: any) => {
|
||||
this.cursorPos = `${cursorPos.row + 1}:${cursorPos.column}`;
|
||||
});
|
||||
|
||||
this.infoBarService.updateInfoBarEncodeing$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((encodeing: string) => {
|
||||
this.encodeing = encodeing;
|
||||
});
|
||||
|
||||
this.infoBarService.updateInfoBarFType$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((ftype: string) => {
|
||||
let mode = ftype.split("/");
|
||||
this.ftype = mode[ mode.length - 1 ];
|
||||
|
@@ -37,12 +37,12 @@
|
||||
<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">
|
||||
Target Editor: <label [innerText]="editor?.id || '...'"></label>
|
||||
</div>
|
||||
|
||||
<div class="col-sm" [hidden]="!lspManagerService.workspaceFolder">
|
||||
<button class="btn btn-sm btn-dark"
|
||||
(click)="registerEditorToLanguageClient()">
|
||||
|
@@ -1,5 +1,12 @@
|
||||
import { Component, ChangeDetectorRef, ElementRef, HostBinding, ViewChild, inject } from '@angular/core';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import {
|
||||
Component,
|
||||
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';
|
||||
|
||||
@@ -23,8 +30,8 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
||||
}
|
||||
})
|
||||
export class LspManagerComponent {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
|
||||
readonly #destroyRef = inject(DestroyRef);
|
||||
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
|
||||
|
||||
lspManagerService: LspManagerService = inject(LspManagerService);
|
||||
|
||||
@@ -37,26 +44,23 @@ export class LspManagerComponent {
|
||||
activeFile: any;
|
||||
|
||||
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.mapEditorsAndLoadConfig();
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
private ngOnDestroy() {
|
||||
this.unsubscribe.next();
|
||||
this.unsubscribe.complete();
|
||||
private ngAfterViewInit(): void {
|
||||
this.mapEditorsAndLoadConfig();
|
||||
}
|
||||
|
||||
private mapEditorsAndLoadConfig() {
|
||||
this.lspTextEditor = this.lspEditorComponent.editor;
|
||||
this.innerEditor = this.sessionEditorComponent.editor;
|
||||
|
||||
this.lspTextEditor.on("input", () => {
|
||||
this.lspManagerService.lspConfigDataStr =
|
||||
this.lspTextEditor.session.getValue();
|
||||
});
|
||||
|
||||
this.lspManagerService.loadLspConfigData().then((lspConfigData) => {
|
||||
this.lspTextEditor.session.setMode("ace/mode/json");
|
||||
this.lspTextEditor.session.setValue(lspConfigData);
|
||||
@@ -65,7 +69,7 @@ export class LspManagerComponent {
|
||||
|
||||
private loadSubscribers() {
|
||||
this.lspManagerService.getMessage$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((message: ServiceMessage) => {
|
||||
if (message.action === "toggle-lsp-manager") {
|
||||
this.toggleLspManager(message);
|
||||
@@ -96,14 +100,13 @@ export class LspManagerComponent {
|
||||
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);
|
||||
/*
|
||||
this.lspManagerService.setSessionFilePath(
|
||||
this.editor.session,
|
||||
this.activeFile.path
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -130,8 +133,8 @@ export class LspManagerComponent {
|
||||
}
|
||||
|
||||
private setActiveEditor(message: ServiceMessage) {
|
||||
this.editor = message.rawData.editor;
|
||||
this.activeFile = message.rawData.activeFile;
|
||||
this.editor = message.rawData.editor;
|
||||
this.activeFile = message.rawData.activeFile;
|
||||
|
||||
// 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.
|
||||
@@ -139,18 +142,15 @@ export class LspManagerComponent {
|
||||
}
|
||||
|
||||
private editorUpdate(message: ServiceMessage) {
|
||||
if (!message.rawData.activeFile) return;
|
||||
if (
|
||||
!this.editor ||
|
||||
!message.rawData.activeFile
|
||||
) return;
|
||||
|
||||
this.editor.setSession(message.rawData.editor.getSession())
|
||||
this.activeFile = message.rawData.activeFile;
|
||||
|
||||
/*
|
||||
this.lspManagerService.setSessionFilePath(
|
||||
this.editor.session,
|
||||
this.activeFile.path
|
||||
);
|
||||
*/
|
||||
this.activeFile = message.rawData.activeFile;
|
||||
|
||||
this.lspManagerService.registerSession(this.editor);
|
||||
}
|
||||
|
||||
private closeFile(message: ServiceMessage) {
|
||||
|
@@ -1,5 +1,10 @@
|
||||
import { Component, HostBinding, inject } from '@angular/core';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import {
|
||||
Component,
|
||||
DestroyRef,
|
||||
HostBinding,
|
||||
inject
|
||||
} from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
import { MarkdownPreviewService } from '../../common/services/editor/markdown-preview/markdown-preview.service';
|
||||
|
||||
@@ -19,7 +24,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
||||
}
|
||||
})
|
||||
export class MarkdownPreviewComponent {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
||||
|
||||
private markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
|
||||
|
||||
@@ -32,26 +37,22 @@ export class MarkdownPreviewComponent {
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
private ngOnDestroy() {
|
||||
this.unsubscribe.next();
|
||||
this.unsubscribe.complete();
|
||||
}
|
||||
|
||||
private loadSubscribers() {
|
||||
this.markdownPreviewService.getMessage$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((message: ServiceMessage) => {
|
||||
if (message.action === "toggle-markdown-preview") {
|
||||
this.toggleMarkdownPreview(message);
|
||||
} else if (message.action === "set-active-editor") {
|
||||
this.setActiveEditor(message);
|
||||
switch ( message.action ) {
|
||||
case "toggle-markdown-preview":
|
||||
this.toggleMarkdownPreview(message);
|
||||
break;
|
||||
case "set-active-editor":
|
||||
this.setActiveEditor(message);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -1,5 +1,13 @@
|
||||
import { Component, ElementRef, HostBinding, Input, ViewChild, inject } from '@angular/core';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import {
|
||||
Component,
|
||||
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';
|
||||
|
||||
@@ -20,7 +28,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
||||
}
|
||||
})
|
||||
export class SearchReplaceComponent {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
readonly #destroyRef: DestroyRef = inject(DestroyRef);
|
||||
|
||||
private searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
|
||||
|
||||
@@ -45,26 +53,22 @@ export class SearchReplaceComponent {
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
private ngOnDestroy() {
|
||||
this.unsubscribe.next();
|
||||
this.unsubscribe.complete();
|
||||
}
|
||||
|
||||
private loadSubscribers() {
|
||||
this.searchReplaceService.getMessage$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((message: ServiceMessage) => {
|
||||
if (message.action === "toggle-search-replace") {
|
||||
this.toggleSearchReplace(message);
|
||||
} else if (message.action === "set-active-editor") {
|
||||
this.setActiveEditor(message);
|
||||
switch ( message.action ) {
|
||||
case "toggle-search-replace":
|
||||
this.toggleSearchReplace(message);
|
||||
break;
|
||||
case "set-active-editor":
|
||||
this.setActiveEditor(message);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -42,6 +42,7 @@
|
||||
margin-left: 2em;
|
||||
margin-right: 2em;
|
||||
font-size: 4em;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
|
@@ -1,7 +1,12 @@
|
||||
import { Component, ChangeDetectorRef, inject } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
ChangeDetectorRef,
|
||||
DestroyRef,
|
||||
inject
|
||||
} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
import { TabsService } from '../../common/services/editor/tabs/tabs.service';
|
||||
|
||||
@@ -24,7 +29,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
|
||||
}
|
||||
})
|
||||
export class TabsComponent {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
readonly #destroyRef = inject(DestroyRef);
|
||||
|
||||
private tabsService: TabsService = inject(TabsService);
|
||||
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
|
||||
@@ -33,36 +38,36 @@ export class TabsComponent {
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
private ngOnDestroy(): void {
|
||||
this.unsubscribe.next();
|
||||
this.unsubscribe.complete();
|
||||
}
|
||||
|
||||
private loadSubscribers() {
|
||||
this.tabsService.getMessage$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
takeUntilDestroyed(this.#destroyRef)
|
||||
).subscribe((message: ServiceMessage) => {
|
||||
if (message.action === "create-tab") {
|
||||
this.createTab(message.fileName, message.fileUUID, message.filePath);
|
||||
} else if (message.action === "file-changed") {
|
||||
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
||||
elm.classList.add("file-changed");
|
||||
elm.classList.remove("file-deleted");
|
||||
} else if (message.action === "file-deleted") {
|
||||
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
||||
elm.classList.add("file-deleted");
|
||||
elm.classList.remove("file-changed");
|
||||
} else if (message.action === "file-saved") {
|
||||
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
||||
elm.classList.remove("file-deleted");
|
||||
elm.classList.remove("file-changed");
|
||||
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
|
||||
|
||||
switch ( message.action ) {
|
||||
case "create-tab":
|
||||
this.createTab(message.fileName, message.fileUUID, message.filePath);
|
||||
break;
|
||||
case "file-changed":
|
||||
elm.classList.add("file-changed");
|
||||
elm.classList.remove("file-deleted");
|
||||
break;
|
||||
case "file-deleted":
|
||||
elm.classList.add("file-deleted");
|
||||
elm.classList.remove("file-changed");
|
||||
break;
|
||||
case "file-saved":
|
||||
elm.classList.remove("file-deleted");
|
||||
elm.classList.remove("file-changed");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -61,3 +61,15 @@
|
||||
.ace_sb-h {
|
||||
width: 0.8em !important;
|
||||
}
|
||||
|
||||
|
||||
.ace_cursor {
|
||||
color: rgba(249, 148, 6, 0.64);
|
||||
animation: blinker 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,10 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
ul, li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
/* IDs */
|
||||
|
||||
|
Reference in New Issue
Block a user