From 766e70d7666532d02ddd08cfe98177221487fefc Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 13 Jul 2025 14:41:46 -0500 Subject: [PATCH] WIP lsp-manager effort 2 --- newton/fs.js | 21 ++++ newton/main.js | 3 +- newton/preload.js | 1 + package.json | 1 + public/lsp-servers-config.json | 78 +++++++----- .../directives/pane-handle.directive.ts | 2 +- .../editor/lsp-manager/lsp-manager.service.ts | 115 ++++++++++++------ src/app/common/services/files.service.ts | 5 +- src/app/common/types/editor.type.ts | 2 +- src/app/editor/code-view/view.component.ts | 14 ++- src/app/editor/editors.component.ts | 3 +- .../lsp-manager/lsp-manager.component.css | 9 +- .../lsp-manager/lsp-manager.component.html | 47 ++++++- .../lsp-manager/lsp-manager.component.ts | 106 +++++++++++++--- .../markdown-preview.component.ts | 2 +- src/polyfills.ts | 1 + 16 files changed, 308 insertions(+), 102 deletions(-) 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/package.json b/package.json index c0b6556..bcae75d 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@angular/platform-browser": "19.2.0", "ace-builds": "1.43.0", "ace-diff": "3.0.3", + "ace-layout": "1.5.0", "ace-linters": "1.7.0", "bootstrap": "5.3.6", "bootstrap-icons": "1.12.1", diff --git a/public/lsp-servers-config.json b/public/lsp-servers-config.json index 6f1506b..07df84f 100644 --- a/public/lsp-servers-config.json +++ b/public/lsp-servers-config.json @@ -8,14 +8,15 @@ "command": "lsp-ws-proxy --listen 4114 -- jdtls", "alt-command": "lsp-ws-proxy -- jdtls", "alt-command2": "java-language-server", - "socket": "ws://127.0.0.1:4114/?name=jdtls", - "alt-socket": "ws://127.0.0.1:3030/?name=java-language-server", + "socket": "ws://127.0.0.1:4114/java", + "socket-two": "ws://127.0.0.1:4114/?name=jdtls", + "alt-socket": "ws://127.0.0.1:9999/?name=java-language-server", "initialization-options": { "bundles": [ "intellicode-core.jar" ], "workspaceFolders": [ - "file://" + "file://{workspace.folder}" ], "extendedClientCapabilities": { "classFileContentsSupport": true, @@ -150,7 +151,8 @@ "alt-command": "pylsp", "alt-command2": "lsp-ws-proxy --listen 4114 -- pylsp", "alt-command3": "pylsp --ws --port 4114", - "socket": "ws://127.0.0.1:9999/?name=pylsp", + "socket": "ws://127.0.0.1:9999/python", + "socket-two": "ws://127.0.0.1:9999/?name=pylsp", "initialization-options": { "pyls": { "plugins": { @@ -209,13 +211,13 @@ "enabled": true, "include_class_objects": true, "include_function_objects": true, - "fuzzy": true + "fuzzy": false }, "jedi":{ + "root_dir": "file://{workspace.folder}", "extra_paths": [ "{user.home}/Portable_Apps/py-venvs/pylsp-venv/venv/lib/python3.10/site-packages" - ], - "root_dir": "" + ] } } } @@ -226,7 +228,8 @@ "info": "https://pypi.org/project/jedi-language-server/", "command": "jedi-language-server", "alt-command": "lsp-ws-proxy --listen 3030 -- jedi-language-server", - "socket": "ws://127.0.0.1:3030/?name=jedi-language-server", + "socket": "ws://127.0.0.1:9999/python", + "socket-two": "ws://127.0.0.1:9999/?name=jedi-language-server", "initialization-options": { "jediSettings": { "autoImportModules": [], @@ -255,28 +258,8 @@ "info": "https://clangd.llvm.org/", "command": "lsp-ws-proxy -- clangd", "alt-command": "clangd", - "socket": "ws://127.0.0.1:3030/?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", + "socket": "ws://127.0.0.1:9999/cpp", + "socket-two": "ws://127.0.0.1:9999/?name=clangd", "initialization-options": {} }, "c": { @@ -284,7 +267,40 @@ "info": "https://clangd.llvm.org/", "command": "lsp-ws-proxy -- clangd", "alt-command": "clangd", - "socket": "ws://127.0.0.1:3030/?name=clangd", + "socket": "ws://127.0.0.1:9999/c", + "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": {} } } \ No newline at end of file diff --git a/src/app/common/directives/pane-handle.directive.ts b/src/app/common/directives/pane-handle.directive.ts index 39c9b0d..dcc4865 100644 --- a/src/app/common/directives/pane-handle.directive.ts +++ b/src/app/common/directives/pane-handle.directive.ts @@ -31,7 +31,7 @@ export class PaneHandleDirective { !target.classList.contains("hr-pane-handle") && !target.classList.contains("vr-pane-handle") ) { - console.log("Must have 'hr-pane-handle' or 'vr-pane-handle' in classList!"); + console.error("Must have 'hr-pane-handle' or 'vr-pane-handle' in classList!"); return; } 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..d087526 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 @@ -14,8 +14,9 @@ import { ServiceMessage } from '../../../types/service-message.type'; export class LspManagerService { private messageSubject: ReplaySubject = new ReplaySubject(1); - lspConfigData!: {}; - languageProviders: {} = {}; + workspaceFolder: string = ""; + lspConfigDataStr: string = ""; + languageProviders: {} = {}; constructor() { @@ -24,69 +25,103 @@ export class LspManagerService { public loadLspConfigData(): Promise { return this.getLspConfigData().then((lspConfigData: string) => { - this.lspConfigData = JSON.parse(lspConfigData); - - if (this.lspConfigData["message"]) { - console.log( - "Warning: LSP this.lspConfigData is a 'message'", - this.lspConfigData - ); - - this.lspConfigData = {}; - } - + this.lspConfigDataStr = lspConfigData; return lspConfigData; }); } - public registerEditor(editor: any): void { - let modeParts = editor.getSession()["$modeId"].split("/"); - let mode = modeParts[ modeParts.length - 1 ]; + public registerEditorToLSPClient(editor: any) { + let mode = this.getMode(editor.session); - if ( !this.languageProviders[mode] ) { - this.languageProviders[mode] = this.getLanguageProviderWithClientServer(mode); + if ( this.languageProviders[mode] ) { + this.languageProviders[mode].registerEditor(editor); + return; } - this.languageProviders[mode].registerEditor(editor); + this.languageProviders[mode]?.registerEditor(editor); } private getLspConfigData(): Promise { return window.fs.getLspConfigData(); } - private getLanguageProviderWithClientServer(mode: string) { - let _initializationOptions = {}; + private parseAndReturnLSPConfigData(): {} { + let configData = JSON.parse( + this.lspConfigDataStr.replaceAll("{workspace.folder}", this.workspaceFolder) + ); - if ( Object.keys(this.lspConfigData).length !== 0 && this.lspConfigData[mode] ) { - _initializationOptions = this.lspConfigData[mode]["initialization-options"]; + if (configData["message"]) { + console.warn( + "Warning: LSP this.lspConfigDataStr is a 'message'", + this.lspConfigDataStr + ); + + configData = {}; } - let servers: LanguageClientConfig[] = [ - { - module: () => import("ace-linters/build/language-client"), - modes: mode, - type: "socket", - socket: new WebSocket(`ws://127.0.0.1:9999/${mode}`), - // socket: new WebSocket("ws://127.0.0.1:9999/?name=pylsp"), - initializationOptions: _initializationOptions - } - ]; - - return AceLanguageClient.for(servers); + return configData; } - private getLanguageProviderWithWebWorker() { + 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 configData = this.parseAndReturnLSPConfigData(); + let _initializationOptions = this.getInitializationOptions(mode, configData); + servers = [ + { + module: () => import("ace-linters/build/language-client"), + modes: mode, + type: "socket", + socket: new WebSocket( configData[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); + // this.languageProviders[mode].requireFilePath = true; + this.languageProviders[mode].changeWorkspaceFolder(this.workspaceFolder); + return this.languageProviders[mode]; + } + + private getLanguageProviderWithWebWorker(): LanguageProvider { let worker = new Worker(new URL('./webworker.js', import.meta.url)); return LanguageProvider.create(worker); } - protected setSessionFilePath(session: any, mode: string = "", filePath: string = "") { - if ( !session || !mode || !filePath || !this.languageProviders[mode] ) return; + public setSessionFilePath(session: any, filePath: string = "") { + if ( !session || !filePath ) return; + let mode = this.getMode(session); + if ( !this.languageProviders[mode] ) return; this.languageProviders[mode].setSessionFilePath(session, filePath); } - protected closeDocument(session: any, mode: string) { - if ( !session || !mode || !this.languageProviders[mode] ) return; + public getMode(session: any): string { + return session.getMode()["$id"].replace("ace/mode/", ""); + } + + public closeDocument(session: any) { + if ( !session ) return; + let mode = this.getMode(session); + if ( !this.languageProviders[mode] ) return; this.languageProviders[mode].closeDocument(session); } diff --git a/src/app/common/services/files.service.ts b/src/app/common/services/files.service.ts index ea2997e..5375343 100644 --- a/src/app/common/services/files.service.ts +++ b/src/app/common/services/files.service.ts @@ -89,13 +89,14 @@ export class FilesService { if (loadFileContents) 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.setMode( getModeForPath( file.path ).mode ); this.files.set(file.path, file); } catch (error) { - console.log( + console.error( `---- Error ----\nPath: ${path}\nMessage: ${error}` ); } 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..7dc1394 100644 --- a/src/app/editor/code-view/view.component.ts +++ b/src/app/editor/code-view/view.component.ts @@ -2,6 +2,10 @@ import { Component } from "@angular/core"; // Import Ace and its modes/themes so that `ace` global is defined 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-keybinding_menu"; import "ace-builds/src-min-noconflict/ext-command_bar"; @@ -59,8 +63,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,11 +132,11 @@ export class CodeViewComponent extends CodeViewBase { this.editorsService.sendMessage(message); this.searchReplaceService.sendMessage(message); - this.editorsService.sendMessage(message); message = new ServiceMessage(); message.action = "set-active-editor"; message.rawData = this; + this.lspManagerService.sendMessage(message); this.markdownPreviewService.sendMessage(message); this.updateInfoBar(); @@ -175,6 +179,12 @@ export class CodeViewComponent extends CodeViewBase { }); this.editor.on("changeSession", (session) => { + let message = new ServiceMessage(); + message.action = "editor-update"; + message.rawData = this; + + this.lspManagerService.sendMessage(message); + this.updateInfoBar(); }); } diff --git a/src/app/editor/editors.component.ts b/src/app/editor/editors.component.ts index f6b0b5e..a821f75 100644 --- a/src/app/editor/editors.component.ts +++ b/src/app/editor/editors.component.ts @@ -139,6 +139,7 @@ export class EditorsComponent { } } + activeComponent.lspManagerService.closeDocument(file.session); this.filesService.delete(file); } @@ -192,7 +193,7 @@ export class EditorsComponent { }); window.fs.onUpdateFilePath(async (path: string) => { - console.log(path); + console.log("TODO (onUpdateFilePath) :", path); // this.tabsService.sendMessage(message); // this.filesService.sendMessage(message); }); 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..14e5b7d 100644 --- a/src/app/editor/lsp-manager/lsp-manager.component.html +++ b/src/app/editor/lsp-manager/lsp-manager.component.html @@ -2,24 +2,63 @@
-
+
- +
+
+ +
+
- + +
+
+
+ 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..77724aa 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,20 @@ 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; + activeFile: any; + + constructor() { @@ -38,13 +44,7 @@ export class LspManagerComponent { private ngAfterViewInit(): void { - this.lspTextEditor = this.editorComponent.editor; - - this.lspManagerService.loadLspConfigData().then((lspConfigData) => { - this.lspTextEditor.session.setMode("ace/mode/json"); - this.lspTextEditor.session.setValue(lspConfigData); - }); - + this.mapEditorsAndLoadConfig(); this.loadSubscribers(); } @@ -53,6 +53,16 @@ export class LspManagerComponent { this.unsubscribe.complete(); } + private mapEditorsAndLoadConfig() { + this.lspTextEditor = this.lspEditorComponent.editor; + this.innerEditor = this.sessionEditorComponent.editor; + + this.lspManagerService.loadLspConfigData().then((lspConfigData) => { + this.lspTextEditor.session.setMode("ace/mode/json"); + this.lspTextEditor.session.setValue(lspConfigData); + }); + } + private loadSubscribers() { this.lspManagerService.getMessage$().pipe( takeUntil(this.unsubscribe) @@ -61,28 +71,90 @@ export class LspManagerComponent { this.toggleLspManager(message); } else if (message.action === "set-active-editor") { this.setActiveEditor(message); + } else if (message.action === "editor-update") { + this.editorUpdate(message); + } else if (message.action === "close-file") { + this.closeFile(message); } }); } - 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 createLanguageClient() { + let mode = this.lspManagerService.getMode(this.editor.session); + this.lspManagerService.createLanguageProviderWithClientServer(mode); + } + + public registerEditorToLanguageClient() { + this.lspManagerService.registerEditorToLSPClient(this.editor); +/* + this.lspManagerService.setSessionFilePath( + this.editor.session, + this.activeFile.path + ); +*/ + } + + 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.getSession()); + }, 10); } private setActiveEditor(message: ServiceMessage) { - this.editor = message.rawData; + 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. + // this.innerEditor.setSession(this.editor.session); + } + + private editorUpdate(message: ServiceMessage) { + if (!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 + ); +*/ + + } + + private closeFile(message: ServiceMessage) { + this.lspManagerService.closeDocument(message.rawData); } } \ 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,