WIP lsp-manager effort
This commit is contained in:
parent
23d9bb24f2
commit
7b4529e8f3
@ -2,8 +2,8 @@
|
||||
<info-bar></info-bar>
|
||||
<tabs></tabs>
|
||||
<editors></editors>
|
||||
<markdown-preview></markdown-preview>
|
||||
<search-replace></search-replace>
|
||||
<markdown-preview></markdown-preview>
|
||||
|
||||
<files-modal></files-modal>
|
||||
<lsp-manager></lsp-manager>
|
||||
</div>
|
@ -5,7 +5,7 @@ import { TabsComponent } from './editor/tabs/tabs.component';
|
||||
import { EditorsComponent } from './editor/editors.component';
|
||||
import { SearchReplaceComponent } from "./editor/search-replace/search-replace.component";
|
||||
import { MarkdownPreviewComponent } from "./editor/markdown-preview/markdown-preview.component";
|
||||
import { FilesModalComponent } from "./common/components/modals/files/files-modal.component";
|
||||
import { LspManagerComponent } from "./editor/lsp-manager/lsp-manager.component";
|
||||
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ import { FilesModalComponent } from "./common/components/modals/files/files-moda
|
||||
EditorsComponent,
|
||||
SearchReplaceComponent,
|
||||
MarkdownPreviewComponent,
|
||||
FilesModalComponent
|
||||
LspManagerComponent,
|
||||
],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
|
@ -1,16 +0,0 @@
|
||||
.modal-column {
|
||||
min-height: 24em;
|
||||
max-height: 24em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
background: rgba(116, 0, 0, 0.64);
|
||||
border-style: solid;
|
||||
border-color: rgba(0, 0, 0, 0.64);
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.close-button:hover {
|
||||
background: rgba(256, 0, 0, 0.64);
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<div #filesModal
|
||||
id="filesModal" class="modal fade" tabindex="-1" role="dialog"
|
||||
>
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Files:</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<div class="row">
|
||||
<div class="col modal-column">
|
||||
|
||||
<div #filesList *ngFor="let file of files" class="row">
|
||||
<div class="col-11 title"
|
||||
title="{{file.path}}"
|
||||
uuid="{{file.uuid}}"
|
||||
path="{{file.path}}"
|
||||
>
|
||||
{{file.title}}
|
||||
</div>
|
||||
<div class="col-1 close-button">
|
||||
X
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<input #filesSearch type="text" placeholder="Search..." />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col modal-column">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,85 +0,0 @@
|
||||
import { Component, inject } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
|
||||
import * as bootstrap from "bootstrap";
|
||||
|
||||
import { FilesModalService } from "../../../services/editor/modals/files-modal.service";
|
||||
import { TabsService } from '../../../services/editor/tabs/tabs.service';
|
||||
|
||||
import { ServiceMessage } from '../../../types/service-message.type';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'files-modal',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
templateUrl: './files-modal.component.html',
|
||||
styleUrl: './files-modal.component.css',
|
||||
host: {
|
||||
'class': ''
|
||||
}
|
||||
})
|
||||
export class FilesModalComponent {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
|
||||
private filesModalService: FilesModalService = inject(FilesModalService);
|
||||
private tabsService: TabsService = inject(TabsService);
|
||||
|
||||
filesModal!: bootstrap.Modal;
|
||||
files: any[] = [];
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
private loadSubscribers() {
|
||||
this.tabsService.getMessage$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
).subscribe((data: ServiceMessage) => {
|
||||
if (data.action === "create-tab") {
|
||||
this.createFileRow(data.fileName, data.fileUUID, data.filePath);
|
||||
}
|
||||
});
|
||||
|
||||
this.filesModalService.showFilesModalRequested$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
).subscribe(() => {
|
||||
if (!this.filesModal) {
|
||||
this.createModal();
|
||||
}
|
||||
|
||||
this.showModal();
|
||||
});
|
||||
|
||||
this.filesModalService.addFileToModalRequested$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
).subscribe((uuid: string) => {
|
||||
if (!this.filesModal) {
|
||||
this.createModal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private createModal() {
|
||||
this.filesModal = new bootstrap.Modal("#filesModal", {});
|
||||
}
|
||||
|
||||
public createFileRow(title: string, uuid: string, path: string): void {
|
||||
this.files.push({title: title, uuid: uuid, path: path})
|
||||
}
|
||||
|
||||
public showModal() {
|
||||
this.filesModal?.toggle();
|
||||
}
|
||||
|
||||
}
|
@ -15,18 +15,14 @@ export const Keybindings: Array<{}> = [
|
||||
name: "openCommandPalette2",
|
||||
bindKey: {linux: "command-shift-/|F1", win: "ctrl-shift-/|F1"},
|
||||
readOnly: false
|
||||
}, {
|
||||
name: "showFilesModal",
|
||||
bindKey: {win: "ctrl-shift-b", mac: "ctrl-shift-b"},
|
||||
service: "filesModalService",
|
||||
readOnly: false
|
||||
}, {
|
||||
name: "showFilesList",
|
||||
bindKey: {win: "ctrl-b", mac: "ctrl-b"},
|
||||
readOnly: false
|
||||
}, {
|
||||
name: "showLSPModal",
|
||||
name: "lspManagerPopup",
|
||||
bindKey: {win: "ctrl-shift-l", mac: "ctrl-shift-l"},
|
||||
service: "",
|
||||
readOnly: false
|
||||
}, {
|
||||
name: "markdownPreviewPopup",
|
||||
|
@ -1,15 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, ReplaySubject, Observable } from 'rxjs';
|
||||
import { ReplaySubject, Observable } from 'rxjs';
|
||||
|
||||
import { AceLanguageClient, LanguageClientConfig } from 'ace-linters/build/ace-language-client';
|
||||
import { LanguageProvider } from "ace-linters";
|
||||
|
||||
import { ServiceMessage } from '../../../types/service-message.type';
|
||||
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LSPService {
|
||||
export class LspManagerService {
|
||||
private messageSubject: ReplaySubject<ServiceMessage> = new ReplaySubject<ServiceMessage>(1);
|
||||
|
||||
lspConfigData!: {};
|
||||
languageProviders: {} = {};
|
||||
|
||||
@ -75,14 +79,22 @@ export class LSPService {
|
||||
return LanguageProvider.create(worker);
|
||||
}
|
||||
|
||||
protected setSessionFilePath(session: any, mode: string = "", filePath: string = "") => {
|
||||
protected setSessionFilePath(session: any, mode: string = "", filePath: string = "") {
|
||||
if ( !session || !mode || !filePath || !this.languageProviders[mode] ) return;
|
||||
this.languageProviders[mode].setSessionFilePath(session, filePath);
|
||||
}
|
||||
|
||||
protected closeDocument(session: any, mode: string) => {
|
||||
protected closeDocument(session: any, mode: string) {
|
||||
if ( !session || !mode || !this.languageProviders[mode] ) return;
|
||||
this.languageProviders[mode].closeDocument(session);
|
||||
}
|
||||
|
||||
public sendMessage(data: ServiceMessage): void {
|
||||
this.messageSubject.next(data);
|
||||
}
|
||||
|
||||
public getMessage$(): Observable<ServiceMessage> {
|
||||
return this.messageSubject.asObservable();
|
||||
}
|
||||
|
||||
}
|
@ -8,6 +8,7 @@ import { EditorsService } from '../../common/services/editor/editors.service';
|
||||
import { FilesService } from '../../common/services/files.service';
|
||||
import { SearchReplaceService } from '../../common/services/editor/search-replace/search-replace.service';
|
||||
import { MarkdownPreviewService } from '../../common/services/editor/markdown-preview/markdown-preview.service';
|
||||
import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service';
|
||||
|
||||
import { EditorSettings } from "../../common/configs/editor.config";
|
||||
import { NewtonFile } from '../../common/types/file.type';
|
||||
@ -31,6 +32,7 @@ export class CodeViewBase {
|
||||
protected filesService: FilesService = inject(FilesService);
|
||||
protected searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
|
||||
protected markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
|
||||
protected lspManagerService: LspManagerService = inject(LspManagerService);
|
||||
|
||||
@ViewChild('editor') editorElm!: ElementRef;
|
||||
@Input() editorSettings!: typeof EditorSettings;
|
||||
@ -97,6 +99,12 @@ export class CodeViewBase {
|
||||
this.editor.showKeyboardShortcuts();
|
||||
}
|
||||
|
||||
public lspManagerPopup() {
|
||||
let message = new ServiceMessage();
|
||||
message.action = "toggle-lsp-manager";
|
||||
this.lspManagerService.sendMessage(message);
|
||||
}
|
||||
|
||||
public markdownPreviewPopup() {
|
||||
let message = new ServiceMessage();
|
||||
message.action = "toggle-markdown-preview";
|
||||
|
@ -59,6 +59,12 @@ export class CodeViewComponent extends CodeViewBase {
|
||||
return;
|
||||
}
|
||||
|
||||
let message = new ServiceMessage();
|
||||
message.action = "register-editor";
|
||||
message.rawData = this;
|
||||
|
||||
this.lspManagerService.sendMessage(message);
|
||||
|
||||
this.loadAceKeyBindings();
|
||||
this.loadAceEventBindings();
|
||||
}
|
||||
@ -116,6 +122,7 @@ 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";
|
||||
|
3
src/app/editor/lsp-manager/lsp-manager.component.css
Normal file
3
src/app/editor/lsp-manager/lsp-manager.component.css
Normal file
@ -0,0 +1,3 @@
|
||||
.lsp-config-text {
|
||||
min-height: 25em;
|
||||
}
|
27
src/app/editor/lsp-manager/lsp-manager.component.html
Normal file
27
src/app/editor/lsp-manager/lsp-manager.component.html
Normal file
@ -0,0 +1,27 @@
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row mt-2 mb-3">
|
||||
|
||||
<div class="col">
|
||||
<div class="input-group-sm">
|
||||
<input class="form-control" placeholder="Project Path..." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col col-auto">
|
||||
<div class="input-group-sm">
|
||||
<button class="btn btn-sm btn-dark">Choose Directory</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
<textarea #lspConfigText class="form-control form-control-sm lsp-config-text" placeholder="LSP Config..."> </textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
87
src/app/editor/lsp-manager/lsp-manager.component.ts
Normal file
87
src/app/editor/lsp-manager/lsp-manager.component.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import { Component, ElementRef, HostBinding, ViewChild, inject } from '@angular/core';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
|
||||
import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service';
|
||||
|
||||
import { ServiceMessage } from '../../common/types/service-message.type';
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'lsp-manager',
|
||||
standalone: true,
|
||||
imports: [
|
||||
],
|
||||
templateUrl: './lsp-manager.component.html',
|
||||
styleUrl: './lsp-manager.component.css',
|
||||
host: {
|
||||
'class': 'lsp-manager',
|
||||
"(keyup)": "globalLspManagerKeyHandler($event)"
|
||||
}
|
||||
})
|
||||
export class LspManagerComponent {
|
||||
private unsubscribe: Subject<void> = new Subject();
|
||||
|
||||
private lspManagerService: LspManagerService = inject(LspManagerService);
|
||||
|
||||
@HostBinding("class.hidden") isHidden: boolean = true;
|
||||
@ViewChild('lspConfigText') lspConfigText!: ElementRef;
|
||||
private editors: any = {};
|
||||
private editor: any;
|
||||
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
|
||||
private ngAfterViewInit(): void {
|
||||
this.lspConfigText.nativeElement.value = this.lspManagerService.lspConfigData;
|
||||
|
||||
this.loadSubscribers();
|
||||
}
|
||||
|
||||
private ngOnDestroy() {
|
||||
this.unsubscribe.next();
|
||||
this.unsubscribe.complete();
|
||||
}
|
||||
|
||||
private loadSubscribers() {
|
||||
this.lspManagerService.getMessage$().pipe(
|
||||
takeUntil(this.unsubscribe)
|
||||
).subscribe((message: ServiceMessage) => {
|
||||
if (message.action === "toggle-lsp-manager") {
|
||||
this.toggleLspManager(message);
|
||||
} else if (message.action === "set-active-editor") {
|
||||
this.setActiveEditor(message);
|
||||
} else if (message.action === "register-editor") {
|
||||
this.registerEditor(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public hideLspManager() {
|
||||
this.isHidden = true;
|
||||
this.editor.focus();
|
||||
}
|
||||
|
||||
public globalLspManagerKeyHandler(event: any) {
|
||||
if (event.ctrlKey && event.shiftKey && event.key === "l") {
|
||||
this.hideLspManager();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private toggleLspManager(message: ServiceMessage) {
|
||||
this.isHidden = !this.isHidden;
|
||||
}
|
||||
|
||||
private setActiveEditor(message: ServiceMessage) {
|
||||
this.editor = this.editors[message.editorUUID];
|
||||
}
|
||||
|
||||
private registerEditor(message: ServiceMessage) {
|
||||
let _editor = message.rawData;
|
||||
this.editors[_editor.uuid] = _editor.editor;
|
||||
}
|
||||
|
||||
}
|
@ -6,28 +6,40 @@
|
||||
|
||||
/* CLASSES */
|
||||
|
||||
.markdown-preview {
|
||||
top: 2em;
|
||||
bottom: 2em;
|
||||
right: 2em;
|
||||
z-index: 900;
|
||||
position: fixed;
|
||||
.search-replace,
|
||||
.markdown-preview,
|
||||
.lsp-manager {
|
||||
display: inline-block;
|
||||
width: 50vw;
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
background-color: rgba(64, 64, 64, 0.84);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.search-replace {
|
||||
bottom: 2em;
|
||||
left: 2em;
|
||||
right: 2em;
|
||||
z-index: 800;
|
||||
display: inline-block;
|
||||
position: fixed;
|
||||
background-color: rgba(64, 64, 64, 0.64);
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
.markdown-preview {
|
||||
top: 2em;
|
||||
bottom: 2em;
|
||||
right: 2em;
|
||||
z-index: 700;
|
||||
width: 50vw;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.lsp-manager {
|
||||
top: 2em;
|
||||
bottom: 2em;
|
||||
left: 2em;
|
||||
right: 2em;
|
||||
z-index: 800;
|
||||
}
|
||||
|
||||
|
||||
.info-bar {
|
||||
font-size: 0.8em;
|
||||
color: rgba(255, 255, 255, 0.84);
|
||||
|
Loading…
Reference in New Issue
Block a user