Wiring of info bar

This commit is contained in:
itdominator 2025-06-12 02:45:17 -05:00
parent dbbc6deaae
commit 0675985a5e
13 changed files with 242 additions and 45 deletions

View File

@ -1,4 +1,5 @@
<div class="col">
<info-bar></info-bar>
<tabs></tabs>
<editors></editors>
</div>

View File

@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { InfoBarComponent } from './editor/info-bar/info-bar.component';
import { TabsComponent } from './editor/tabs/tabs.component';
import { EditorsComponent } from './editor/editors.component';
@ -9,6 +10,7 @@ import { EditorsComponent } from './editor/editors.component';
@Component({
selector: 'app-root',
imports: [
InfoBarComponent,
TabsComponent,
EditorsComponent
],

View File

@ -0,0 +1,61 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, ReplaySubject, Observable } from 'rxjs';
import { ServiceMessage } from '../../../types/service-message.type';
@Injectable({
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() {}
setData(data: ServiceMessage): void {
this.dataSubject.next(data);
}
getData$(): Observable<ServiceMessage> {
return this.dataSubject.asObservable();
}
setInfoBarFPath(data: string): void {
this.fpathSubject.next(data);
}
updateInfoBarFPath$(): Observable<string> {
return this.fpathSubject.asObservable();
}
setInfoBarCursorPos(data: any): void {
this.cursorPosSubject.next(data);
}
updateInfoBarCursorPos$(): Observable<any> {
return this.cursorPosSubject.asObservable();
}
setInfoBarEncodeing(data: string): void {
this.encodeingSubject.next(data);
}
updateInfoBarEncodeing$(): Observable<string> {
return this.encodeingSubject.asObservable();
}
setInfoBarFType(data: string): void {
this.ftypeSubject.next(data);
}
updateInfoBarFType$(): Observable<string> {
return this.ftypeSubject.asObservable();
}
}

View File

@ -33,7 +33,7 @@ export class AceEditorBase {
}
protected search() {
console.log(this.editor.getSession()["$modeId"])
console.log(this.editor.session.getMode()["$id"]);
}
protected openFiles() {

View File

@ -1,10 +1,12 @@
import { Component } from '@angular/core';
import { Component } from "@angular/core";
// Import Ace and its modes/themes so that `ace` global is defined
import * as ace from 'ace-builds/src-noconflict/ace';
import 'ace-builds/src-noconflict/theme-one_dark';
import * as ace from "ace-builds/src-noconflict/ace";
import "ace-builds/src-noconflict/theme-one_dark";
import "ace-builds/src-noconflict/theme-dracula";
import "ace-builds/src-noconflict/ext-language_tools";
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
import { EditorsService } from '../../common/services/editor/editors.service';
import { LSPService } from '../../common/services/lsp.service';
@ -27,6 +29,7 @@ export class AceEditorComponent extends AceEditorBase {
constructor(
private infoBarService: InfoBarService,
private editorsService: EditorsService,
private lspService: LSPService
) {
@ -62,14 +65,14 @@ export class AceEditorComponent extends AceEditorBase {
exec: () => {
this.movelinesUp();
},
readOnly: true
readOnly: false
}, {
name: "movelinesDown",
bindKey: {win: "ctrl-down", mac: "ctrl-down"},
exec: () => {
this.movelinesDown();
},
readOnly: true
readOnly: false
},
{
name: "duplicateLines",
@ -77,7 +80,7 @@ export class AceEditorComponent extends AceEditorBase {
exec: () => {
this.duplicateLines();
},
readOnly: true
readOnly: false
}, {
name: "zoomIn",
bindKey: {win: "ctrl-=", mac: "ctrl-="},
@ -98,61 +101,95 @@ export class AceEditorComponent extends AceEditorBase {
exec: () => {
this.cutToBuffer();
},
readOnly: true
readOnly: false
}, {
name: "pasteCutBuffer",
bindKey: {win: "ctrl-u", mac: "ctrl-u"},
exec: () => {
this.pasteCutBuffer();
},
readOnly: true
readOnly: false
}, {
name: "destroySession",
bindKey: {win: "ctrl-w", mac: "ctrl-w"},
exec: () => {
this.editor.session.destroy();
},
readOnly: true
readOnly: false
}, {
name: "openFiles",
bindKey: {win: "ctrl-o", mac: "ctrl-o"},
exec: () => {
this.openFiles();
},
readOnly: true
readOnly: false
}, {
name: "saveFile",
bindKey: {win: "ctrl-s", mac: "ctrl-s"},
exec: () => {
this.saveFile();
},
readOnly: true
readOnly: false
}, {
name: "saveFileAs",
bindKey: {win: "ctrl-shift-s", mac: "ctrl-shift-s"},
exec: () => {
this.saveFileAs();
},
readOnly: true
readOnly: false
}
]);
// Note: https://github.com/mkslanc/ace-linters/blob/c286d85c558530aa1b0597d02108bc782abd4736/packages/ace-linters/src/language-provider.ts#L277
// found on focus ^ might have other signals we can watch like session being set, etc.
// Note: https://ajaxorg.github.io/ace-api-docs/interfaces/ace.Ace.EditorEvents.html
this.editor.on("click", () => {
this.updateInfoBar();
});
this.editor.on("input", () => {
this.updateInfoBar();
});
this.editor.on("keyboardActivity", (e) => {
switch(e.command.name) {
case "golineup":
case "golinedown":
case "gotoleft":
case "gotoright":
this.infoBarService.setInfoBarCursorPos(
this.editor.getCursorPosition()
);
break;
default:
break;
}
});
this.editor.on("focus", () => {
this.editorsService.setActiveEditor(this.uuid);
});
this.editor.on("changeSession", (session) => {
this.lspService.registerEditor(this.editor);
this.updateInfoBar();
});
}
public updateInfoBar() {
this.infoBarService.setInfoBarFPath(this.activeFile?.path)
this.infoBarService.setInfoBarCursorPos(
this.editor.getCursorPosition()
);
this.infoBarService.setInfoBarFType(
this.editor.session.getMode()["$id"]
);
}
public newBuffer() {
let buffer = ace.createEditSession([""]);
this.editor.setSession(buffer);
this.activeFile = null;
this.updateInfoBar();
}
}

View File

@ -1,3 +1,3 @@
.dropzone {
height: 95vh;
height: 92vh;
}

View File

@ -0,0 +1,15 @@
<div class="col col-md-6" title="{{fpath || '...'}}">
{{path || "..."}}
</div>
<div class="col col-md-2">
{{cursorPos || "1:1"}}
</div>
<div class="col col-md-2">
{{encodeing || "utf-8"}}
</div>
<div class="col col-md-2">
{{ftype || "text"}}
</div>

View File

@ -0,0 +1,76 @@
import { Component } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
@Component({
selector: 'info-bar',
standalone: true,
imports: [
],
templateUrl: './info-bar.component.html',
styleUrl: './info-bar.component.css',
host: {
'class': 'row info-bar'
}
})
export class InfoBarComponent {
private unsubscribe = new Subject<void>();
fpath: string = "";
path: string = "";
cursorPos: string = "";
encodeing: string = "";
ftype: string = "";
constructor(
private infoBarService: InfoBarService
) {}
public ngAfterViewInit(): void {
this.loadSubscribers();
}
loadSubscribers() {
this.infoBarService.updateInfoBarFPath$().pipe(
takeUntil(this.unsubscribe)
).subscribe((fpath: string) => {
this.fpath = fpath;
let _path = fpath;
if (fpath?.length > 67) {
_path = "..." + fpath.slice(fpath.length - 67, fpath.length);
}
this.path = _path;
});
this.infoBarService.updateInfoBarCursorPos$().pipe(
takeUntil(this.unsubscribe)
).subscribe((cursorPos: any) => {
this.cursorPos = `${cursorPos.row + 1}:${cursorPos.column}`;
});
this.infoBarService.updateInfoBarEncodeing$().pipe(
takeUntil(this.unsubscribe)
).subscribe((encodeing: string) => {
this.encodeing = encodeing;
});
this.infoBarService.updateInfoBarFType$().pipe(
takeUntil(this.unsubscribe)
).subscribe((ftype: string) => {
let mode = ftype.split("/");
this.ftype = mode[ mode.length - 1 ];
});
}
}

View File

@ -1,7 +1,22 @@
.tab,
.title,
.close-button {
color: rgba(255, 255, 255, 0.64);
.tab {
display: flex;
overflow: auto;
float: left;
margin-right: 2em;
font-size: 0.2em;
border-top-style: solid;
border-top-color: #ffffff64;
border-top-width: 2px;
border-left-style: solid;
border-left-color: #ffffff64;
border-left-width: 2px;
border-right-style: solid;
border-right-color: #ffffff64;
border-right-width: 2px;
}
.tab:hover {

View File

@ -21,7 +21,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
templateUrl: './tabs.component.html',
styleUrl: './tabs.component.css',
host: {
'class': 'tabs scroller'
'class': 'row tabs scroller'
}
})
export class TabsComponent {

View File

@ -12,3 +12,8 @@
.ace_autocomplete {
background-color: #25282c !important;
}
.ace_sb-v,
.ace_sb-h {
width: 0.8em !important;
}

View File

@ -19,34 +19,19 @@ body {
/* CLASSES */
.info-bar {
font-size: 0.8em;
color: rgba(255, 255, 255, 0.84);
text-align: center;
}
.tabs {
display: flex;
overflow: auto;
margin-bottom: 0.5em;
padding-bottom: 0.4em;
padding-top: 0.4em;
}
.tab {
display: flex;
overflow: auto;
float: left;
margin-right: 2em;
font-size: 0.2em;
border-top-style: solid;
border-top-color: #ffffff64;
border-top-width: 2px;
border-left-style: solid;
border-left-color: #ffffff64;
border-left-width: 2px;
border-right-style: solid;
border-right-color: #ffffff64;
border-right-width: 2px;
color: rgba(255, 255, 255, 0.64);
}