Initial commit
This commit is contained in:
commit
392461d253
|
@ -0,0 +1,2 @@
|
|||
dist/
|
||||
node_modules/
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Jomar Milan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,19 @@
|
|||
# osc-notify
|
||||
|
||||
This is a [Tabby](https://github.com/Eugeny/tabby) plugin. It creates a system
|
||||
notification when an OSC 9 escape code sequence is printed. OSC 9 is in this
|
||||
format:
|
||||
|
||||
```sh
|
||||
OSC 9 ; [message] ST
|
||||
```
|
||||
|
||||
### Example commands
|
||||
|
||||
```sh
|
||||
# creates a notification that says 'hello'
|
||||
printf "\033]9;hello\a"
|
||||
# for tmux, use the passthrough escape sequence. allow-passthrough should be
|
||||
# enabled
|
||||
printf "\033Ptmux;\033\x1b]9;hello\x07\033\\"
|
||||
```
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "osc-notify",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"watch": "webpack --watch"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": "https://tildegit.org/jomarm/osc-notify",
|
||||
"author": "jomarm",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"keywords": [
|
||||
"tabby-plugin"
|
||||
],
|
||||
"devDependencies": {
|
||||
"apply-loader": "^2.0.0",
|
||||
"css-loader": "^6.8.1",
|
||||
"pug-loader": "^2.4.0",
|
||||
"sass-loader": "^13.3.2",
|
||||
"style-loader": "^3.3.3",
|
||||
"ts-loader": "^9.4.4",
|
||||
"typescript": "^5.2.2",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/core": "^16.2.3",
|
||||
"rxjs": "^7.8.1",
|
||||
"tabby-terminal": "^1.0.197-nightly.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import OscNotifyDecorator from "./osc-notify-decorator";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { TerminalDecorator } from "tabby-terminal";
|
||||
|
||||
@NgModule({
|
||||
providers: [
|
||||
{ provide: TerminalDecorator, useClass: OscNotifyDecorator, multi: true }
|
||||
]
|
||||
})
|
||||
export default class OscNotifyModule {
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import OscNotifyMiddleware from "./osc-notify-middleware";
|
||||
import { Injectable } from "@angular/core";
|
||||
import { TerminalDecorator, BaseSession, BaseTerminalTabComponent } from "tabby-terminal";
|
||||
|
||||
@Injectable()
|
||||
export default class OscNotifyDecorator extends TerminalDecorator {
|
||||
attach(tab: BaseTerminalTabComponent<any>): void {
|
||||
// Subscribe to attach to future sessions in this tab
|
||||
tab.sessionChanged$.subscribe((session) => {
|
||||
if (session) {
|
||||
this.attachToSession(session, (<any>tab).title);
|
||||
}
|
||||
});
|
||||
|
||||
// Attach the current session for this tab
|
||||
if (tab.session) {
|
||||
this.attachToSession(tab.session, (<any>tab).title);
|
||||
}
|
||||
}
|
||||
|
||||
private attachToSession(session: BaseSession, tabTitle: string) {
|
||||
const middleware = new OscNotifyMiddleware(tabTitle);
|
||||
|
||||
session.middleware.push(middleware);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
import { SessionMiddleware } from "tabby-terminal";
|
||||
import { Observable, Subject } from "rxjs";
|
||||
|
||||
const oscPrefix = Buffer.from("\x1b]");
|
||||
const oscSuffix = Buffer.from("\x07");
|
||||
|
||||
export default class OscNotifyMiddleware extends SessionMiddleware {
|
||||
tabTitle: string;
|
||||
|
||||
constructor(tabTitle: string) {
|
||||
super();
|
||||
|
||||
this.tabTitle = tabTitle;
|
||||
}
|
||||
|
||||
get cwdReported$(): Observable<string> {
|
||||
return this.cwdReported;
|
||||
}
|
||||
get copyRequested$(): Observable<string> {
|
||||
return this.copyRequested;
|
||||
}
|
||||
|
||||
private cwdReported = new Subject<string>();
|
||||
private copyRequested = new Subject<string>();
|
||||
|
||||
feedFromSession(data: Buffer): void {
|
||||
let startIndex = 0;
|
||||
|
||||
while (data.includes(oscPrefix, startIndex) && data.includes(oscSuffix, startIndex)) {
|
||||
const params = data.subarray(data.indexOf(oscPrefix, startIndex) + oscPrefix.length);
|
||||
const oscString = params.subarray(0, params.indexOf(oscSuffix)).toString();
|
||||
|
||||
startIndex = data.indexOf(oscSuffix, startIndex) + oscSuffix.length;
|
||||
|
||||
const [ oscCodeString, ...oscParams ] = oscString.split(";");
|
||||
const oscCode = parseInt(oscCodeString);
|
||||
|
||||
if (oscCode === 9) {
|
||||
// TODO: onclick switch to tab
|
||||
new Notification(this.tabTitle, {
|
||||
body: oscParams[0]
|
||||
});
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
super.feedFromSession(data);
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.cwdReported.complete();
|
||||
this.copyRequested.complete();
|
||||
super.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"target": "es2016",
|
||||
"esModuleInterop": true,
|
||||
"noImplicitAny": false,
|
||||
"removeComments": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"sourceMap": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"declaration": true,
|
||||
"declarationDir": "dist",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2015",
|
||||
"es7"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
target: "node",
|
||||
entry: "src/index.ts",
|
||||
devtool: "source-map",
|
||||
context: __dirname,
|
||||
mode: "development",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
filename: "index.js",
|
||||
pathinfo: true,
|
||||
libraryTarget: "umd"
|
||||
},
|
||||
resolve: {
|
||||
modules: [".", "src", "node_modules"].map(x => path.join(__dirname, x)),
|
||||
extensions: [ ".js", ".ts" ]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loader: "ts-loader",
|
||||
options: {
|
||||
configFile: path.resolve(__dirname, "tsconfig.json")
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.scss/,
|
||||
use: [ "style-loader", "css-loader", "sass-lodaer" ]
|
||||
},
|
||||
{
|
||||
test: /\.pug$/,
|
||||
use: [ "apply-loader", "pug-loader" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
externals: [ "fs", "ngx-toastr", /^rxjs/, /^@angular/, /^@ng-bootstrap/, /^tabby-/ ]
|
||||
};
|
Loading…
Reference in New Issue