diff --git a/newton/fs.js b/newton/fs.js index dda2ac8..ab4b043 100644 --- a/newton/fs.js +++ b/newton/fs.js @@ -100,6 +100,26 @@ const saveFileAs = () => { }); } +const chooseFolder = () => { + return dialog.showOpenDialog( + { + title: "Choose Folder:", + defaultPath: HOME_DIR, + properties: [ + 'openDirectory' + ] + } + ).then((response) => { + if (response.canceled) { + console.debug("Canceled folder selection..."); + return ""; + } + console.log(response) + + return response.filePaths[0]; + }); +} + const openFiles = (startPath) => { dialog.showOpenDialog( { @@ -171,6 +191,7 @@ const closeFile = (fpath) => { module.exports = { newtonFs: { setWindow: setWindow, + chooseFolder: chooseFolder, openFiles: openFiles, saveFile: saveFile, saveFileAs: saveFileAs, diff --git a/newton/main.js b/newton/main.js index f5df620..346ce7f 100644 --- a/newton/main.js +++ b/newton/main.js @@ -72,7 +72,8 @@ const loadHandlers = () => { ipcMain.handle('openFiles', (eve, startPath) => newton.fs.openFiles(startPath)); ipcMain.handle('saveFile', (eve, path, content) => newton.fs.saveFile(path, content)); ipcMain.handle('closeFile', (eve, path) => newton.fs.closeFile(path)); - ipcMain.handle('saveFileAs', (eve, content) => newton.fs.saveFileAs(content)); + ipcMain.handle('saveFileAs', (eve) => newton.fs.saveFileAs()); + ipcMain.handle('chooseFolder', (eve) => newton.fs.chooseFolder()); } app.whenReady().then(async () => { diff --git a/newton/preload.js b/newton/preload.js index 047a0ad..e69c620 100644 --- a/newton/preload.js +++ b/newton/preload.js @@ -19,6 +19,7 @@ contextBridge.exposeInMainWorld('fs', { openFiles: (startPath) => ipcRenderer.invoke("openFiles", startPath), saveFile: (path, content) => ipcRenderer.invoke("saveFile", path, content), saveFileAs: () => ipcRenderer.invoke("saveFileAs"), + chooseFolder: () => ipcRenderer.invoke("chooseFolder"), closeFile: (path) => ipcRenderer.invoke("closeFile", path), getPathForFile: (file) => webUtils.getPathForFile(file), onLoadFiles: (callback) => ipcRenderer.on('load-files', (_event, paths) => callback(paths)), diff --git a/src/app/common/services/editor/lsp-manager/lsp-manager.service.ts b/src/app/common/services/editor/lsp-manager/lsp-manager.service.ts index f9e7491..97b41e3 100644 --- a/src/app/common/services/editor/lsp-manager/lsp-manager.service.ts +++ b/src/app/common/services/editor/lsp-manager/lsp-manager.service.ts @@ -15,7 +15,8 @@ export class LspManagerService { private messageSubject: ReplaySubject = new ReplaySubject(1); lspConfigData!: {}; - languageProviders: {} = {}; + languageProviders: {} = {}; + workspaceFolder: string = ""; constructor() { @@ -40,7 +41,7 @@ export class LspManagerService { } public registerEditor(editor: any): void { - let modeParts = editor.getSession()["$modeId"].split("/"); + let modeParts = editor.session.getMode()["$Id"].split("/"); let mode = modeParts[ modeParts.length - 1 ]; if ( !this.languageProviders[mode] ) { @@ -80,13 +81,17 @@ export class LspManagerService { return LanguageProvider.create(worker); } - protected setSessionFilePath(session: any, mode: string = "", filePath: string = "") { - if ( !session || !mode || !filePath || !this.languageProviders[mode] ) return; + protected setSessionFilePath(session: any, filePath: string = "") { + if ( !session || !filePath ) return; + let mode = session.getMode()["$Id"]; + if ( !this.languageProviders[mode] ) return; this.languageProviders[mode].setSessionFilePath(session, filePath); } - protected closeDocument(session: any, mode: string) { - if ( !session || !mode || !this.languageProviders[mode] ) return; + protected closeDocument(session: any) { + if ( !session ) return; + let mode = session.getMode()["$Id"]; + if ( !this.languageProviders[mode] ) return; this.languageProviders[mode].closeDocument(session); } diff --git a/src/app/common/types/editor.type.ts b/src/app/common/types/editor.type.ts index 1c109dd..8b4a7ca 100644 --- a/src/app/common/types/editor.type.ts +++ b/src/app/common/types/editor.type.ts @@ -2,4 +2,4 @@ export abstract class EditorType { static MiniMap: string = "mini-map"; static ReadOnly: string = "read-only"; static Standalone: string = "standalone"; -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/app/editor/code-view/view.component.ts b/src/app/editor/code-view/view.component.ts index 543394c..77e08a6 100644 --- a/src/app/editor/code-view/view.component.ts +++ b/src/app/editor/code-view/view.component.ts @@ -59,8 +59,8 @@ export class CodeViewComponent extends CodeViewBase { this.editor = ace.edit( this.editorElm.nativeElement ); this.editor.setOptions( this.editorSettings.CONFIG ); + this.editorsService.set(this.uuid, this); if (this.isDefault) { - this.editorsService.set(this.uuid, this); this.editorsService.setActiveEditor(this.uuid); this.addActiveStyling(); this.editor.focus(); @@ -128,7 +128,7 @@ export class CodeViewComponent extends CodeViewBase { this.editorsService.sendMessage(message); this.searchReplaceService.sendMessage(message); - this.editorsService.sendMessage(message); + this.lspManagerService.sendMessage(message); message = new ServiceMessage(); message.action = "set-active-editor"; @@ -175,6 +175,12 @@ export class CodeViewComponent extends CodeViewBase { }); this.editor.on("changeSession", (session) => { + let message = new ServiceMessage(); + message.action = "set-active-editor"; + message.rawData = this.editor; + + this.lspManagerService.sendMessage(message); + this.updateInfoBar(); }); } diff --git a/src/app/editor/lsp-manager/lsp-manager.component.css b/src/app/editor/lsp-manager/lsp-manager.component.css index d40084e..8328daa 100644 --- a/src/app/editor/lsp-manager/lsp-manager.component.css +++ b/src/app/editor/lsp-manager/lsp-manager.component.css @@ -1,4 +1,11 @@ .lsp-config-text { display: grid; min-height: 25em; -} \ No newline at end of file +} + +.clear-left-padding { + padding-left: 0px; +} +.clear-right-padding { + padding-right: 0px; +} diff --git a/src/app/editor/lsp-manager/lsp-manager.component.html b/src/app/editor/lsp-manager/lsp-manager.component.html index a7ddbfb..0bc2aaa 100644 --- a/src/app/editor/lsp-manager/lsp-manager.component.html +++ b/src/app/editor/lsp-manager/lsp-manager.component.html @@ -2,24 +2,51 @@
-
+
- +
+
+ +
+
- + +
+
+
+ LSP Configs: +
+
+ +
+
+ +
+
+ +
+
+ Target Editor: +
+
+ Active Editor Session: +
+
+
- +
diff --git a/src/app/editor/lsp-manager/lsp-manager.component.ts b/src/app/editor/lsp-manager/lsp-manager.component.ts index c057cb5..3962e27 100644 --- a/src/app/editor/lsp-manager/lsp-manager.component.ts +++ b/src/app/editor/lsp-manager/lsp-manager.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, HostBinding, ViewChild, inject } from '@angular/core'; +import { Component, ChangeDetectorRef, ElementRef, HostBinding, ViewChild, inject } from '@angular/core'; import { Subject, takeUntil } from 'rxjs'; import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service'; @@ -23,14 +23,19 @@ import { ServiceMessage } from '../../common/types/service-message.type'; } }) export class LspManagerComponent { - private unsubscribe: Subject = new Subject(); + private unsubscribe: Subject = new Subject(); + private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef); - private lspManagerService: LspManagerService = inject(LspManagerService); + lspManagerService: LspManagerService = inject(LspManagerService); @HostBinding("class.hidden") isHidden: boolean = true; - @ViewChild('editorComponent') editorComponent!: CodeViewComponent; - lspTextEditor!: any; - private editor: any; + @ViewChild('lspEditorComponent') lspEditorComponent!: CodeViewComponent; + @ViewChild('sessionEditorComponent') sessionEditorComponent!: CodeViewComponent; + lspTextEditor: any; + innerEditor: any; + editor: any; + + constructor() { @@ -38,7 +43,8 @@ export class LspManagerComponent { private ngAfterViewInit(): void { - this.lspTextEditor = this.editorComponent.editor; + this.lspTextEditor = this.lspEditorComponent.editor; + this.innerEditor = this.sessionEditorComponent.editor; this.lspManagerService.loadLspConfigData().then((lspConfigData) => { this.lspTextEditor.session.setMode("ace/mode/json"); @@ -65,24 +71,47 @@ export class LspManagerComponent { }); } - public hideLspManager() { - this.isHidden = true; - this.editor.focus(); + public clearWorkspaceFolder() { + this.lspManagerService.workspaceFolder = ""; } + public setWorkspaceFolder() { + window.fs.chooseFolder().then((folder: string) => { + if (!folder) return; + + this.lspManagerService.workspaceFolder = folder; + }); + } + + + public globalLspManagerKeyHandler(event: any) { if (event.ctrlKey && event.shiftKey && event.key === "l") { this.hideLspManager(); } } + public hideLspManager() { + this.isHidden = true; + this.editor.focus(); + } private toggleLspManager(message: ServiceMessage) { this.isHidden = !this.isHidden; + + if (this.isHidden) return; + + // Note: hack for issue with setActiveEditor TODO + setTimeout(() => { + this.innerEditor.setSession(this.editor.session); + }, 10); } private setActiveEditor(message: ServiceMessage) { this.editor = message.rawData; + // 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. + // this.innerEditor.setSession(this.editor.session); } } \ No newline at end of file diff --git a/src/app/editor/markdown-preview/markdown-preview.component.ts b/src/app/editor/markdown-preview/markdown-preview.component.ts index 81812e1..9d1489b 100644 --- a/src/app/editor/markdown-preview/markdown-preview.component.ts +++ b/src/app/editor/markdown-preview/markdown-preview.component.ts @@ -61,7 +61,7 @@ export class MarkdownPreviewComponent { setTimeout(() => { this.updatePreview(); - }, 200); + }, 10); } private setActiveEditor(message: ServiceMessage) { diff --git a/src/polyfills.ts b/src/polyfills.ts index 7b409b5..c158352 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -29,6 +29,7 @@ declare global { openFiles: (arg0) => Promise, saveFile: (arg0: any, arg1: any) => Promise, saveFileAs: () => Promise, + chooseFolder: () => Promise, closeFile: (arg0: any) => Promise, getPathForFile: any, onLoadFiles: (arg0: any) => Promise,