Initial commit

This commit is contained in:
Jomar Milan 2023-09-05 21:30:26 -07:00
commit 392461d253
No known key found for this signature in database
GPG Key ID: 56F5037BF30EA749
10 changed files with 1311 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
dist/
node_modules/

21
LICENSE Normal file
View File

@ -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.

19
README.md Normal file
View File

@ -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\\"
```

36
package.json Normal file
View File

@ -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"
}
}

11
src/index.ts Normal file
View File

@ -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 {
}

View File

@ -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);
}
}

View File

@ -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();
}
}

27
tsconfig.json Normal file
View File

@ -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"
]
}

39
webpack.config.js Normal file
View File

@ -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-/ ]
};

1074
yarn.lock Normal file

File diff suppressed because it is too large Load Diff