diff --git a/src/app/app.component.html b/src/app/app.component.html
index 0368c2b..5e8b57a 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,4 +1,5 @@
+
\ No newline at end of file
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 23b4924..69f54d8 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -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
],
diff --git a/src/app/common/services/editor/info-bar/info-bar.service.ts b/src/app/common/services/editor/info-bar/info-bar.service.ts
new file mode 100644
index 0000000..fed6037
--- /dev/null
+++ b/src/app/common/services/editor/info-bar/info-bar.service.ts
@@ -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 = new ReplaySubject(1);
+ private fpathSubject: ReplaySubject = new ReplaySubject(1);
+ private cursorPosSubject: ReplaySubject = new ReplaySubject(1);
+ private encodeingSubject: ReplaySubject = new ReplaySubject(1);
+ private ftypeSubject: ReplaySubject = new ReplaySubject(1);
+
+
+ constructor() {}
+
+
+ setData(data: ServiceMessage): void {
+ this.dataSubject.next(data);
+ }
+
+ getData$(): Observable {
+ return this.dataSubject.asObservable();
+ }
+
+ setInfoBarFPath(data: string): void {
+ this.fpathSubject.next(data);
+ }
+
+ updateInfoBarFPath$(): Observable {
+ return this.fpathSubject.asObservable();
+ }
+
+ setInfoBarCursorPos(data: any): void {
+ this.cursorPosSubject.next(data);
+ }
+
+ updateInfoBarCursorPos$(): Observable {
+ return this.cursorPosSubject.asObservable();
+ }
+
+ setInfoBarEncodeing(data: string): void {
+ this.encodeingSubject.next(data);
+ }
+
+ updateInfoBarEncodeing$(): Observable {
+ return this.encodeingSubject.asObservable();
+ }
+
+ setInfoBarFType(data: string): void {
+ this.ftypeSubject.next(data);
+ }
+
+ updateInfoBarFType$(): Observable {
+ return this.ftypeSubject.asObservable();
+ }
+
+}
\ No newline at end of file
diff --git a/src/app/editor/ace/ace-editor.base.ts b/src/app/editor/ace/ace-editor.base.ts
index 033ec9e..6c27a4e 100644
--- a/src/app/editor/ace/ace-editor.base.ts
+++ b/src/app/editor/ace/ace-editor.base.ts
@@ -33,7 +33,7 @@ export class AceEditorBase {
}
protected search() {
- console.log(this.editor.getSession()["$modeId"])
+ console.log(this.editor.session.getMode()["$id"]);
}
protected openFiles() {
diff --git a/src/app/editor/ace/ace-editor.component.ts b/src/app/editor/ace/ace-editor.component.ts
index ba24e1f..60fe7d8 100644
--- a/src/app/editor/ace/ace-editor.component.ts
+++ b/src/app/editor/ace/ace-editor.component.ts
@@ -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();
}
}
\ No newline at end of file
diff --git a/src/app/editor/editors.component.css b/src/app/editor/editors.component.css
index c00f657..693ae44 100644
--- a/src/app/editor/editors.component.css
+++ b/src/app/editor/editors.component.css
@@ -1,3 +1,3 @@
.dropzone {
- height: 95vh;
+ height: 92vh;
}
diff --git a/src/app/editor/info-bar/info-bar.component.css b/src/app/editor/info-bar/info-bar.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/editor/info-bar/info-bar.component.html b/src/app/editor/info-bar/info-bar.component.html
new file mode 100644
index 0000000..185fc24
--- /dev/null
+++ b/src/app/editor/info-bar/info-bar.component.html
@@ -0,0 +1,15 @@
+
+{{path || "..."}}
+
+
+
+{{cursorPos || "1:1"}}
+
+
+
+{{encodeing || "utf-8"}}
+
+
+
+{{ftype || "text"}}
+
\ No newline at end of file
diff --git a/src/app/editor/info-bar/info-bar.component.ts b/src/app/editor/info-bar/info-bar.component.ts
new file mode 100644
index 0000000..3fc6a31
--- /dev/null
+++ b/src/app/editor/info-bar/info-bar.component.ts
@@ -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();
+
+ 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 ];
+ });
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/app/editor/tabs/tabs.component.css b/src/app/editor/tabs/tabs.component.css
index 6ff7c3e..6622d33 100644
--- a/src/app/editor/tabs/tabs.component.css
+++ b/src/app/editor/tabs/tabs.component.css
@@ -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 {
diff --git a/src/app/editor/tabs/tabs.component.ts b/src/app/editor/tabs/tabs.component.ts
index 6fdd20d..7f59c7b 100644
--- a/src/app/editor/tabs/tabs.component.ts
+++ b/src/app/editor/tabs/tabs.component.ts
@@ -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 {
@@ -117,4 +117,4 @@ export class TabsComponent {
// moveItemInArray(this.tabs, event.previousIndex, event.currentIndex);
}
-}
+}
\ No newline at end of file
diff --git a/src/assets/css/ace-overrides.css b/src/assets/css/ace-overrides.css
index 0eaf590..7619370 100644
--- a/src/assets/css/ace-overrides.css
+++ b/src/assets/css/ace-overrides.css
@@ -12,3 +12,8 @@
.ace_autocomplete {
background-color: #25282c !important;
}
+
+.ace_sb-v,
+.ace_sb-h {
+ width: 0.8em !important;
+}
\ No newline at end of file
diff --git a/src/assets/css/styles.css b/src/assets/css/styles.css
index a3bce7d..206fd08 100644
--- a/src/assets/css/styles.css
+++ b/src/assets/css/styles.css
@@ -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);
}