mirror of
https://github.com/Eugeny/tabby.git
synced 2025-08-31 13:41:53 +00:00
Compare commits
49 Commits
v1.0.0-alp
...
v1.0.0-alp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1643ca2bd5 | ||
![]() |
b640abd85d | ||
![]() |
dcf9817075 | ||
![]() |
6f8f83d178 | ||
![]() |
475c4f91be | ||
![]() |
29a6fb60de | ||
![]() |
42007f4fef | ||
![]() |
92c0df7629 | ||
![]() |
e70cb25180 | ||
![]() |
980834df6f | ||
![]() |
50968508df | ||
![]() |
8ee93297be | ||
![]() |
dc9b2553ae | ||
![]() |
a6f7f7aa05 | ||
![]() |
c087a969d6 | ||
![]() |
f4eb03fee0 | ||
![]() |
deb4b963cd | ||
![]() |
9834b27b8d | ||
![]() |
fc060acd88 | ||
![]() |
709ffadc7c | ||
![]() |
536d9537ff | ||
![]() |
94217f0b01 | ||
![]() |
80762e92d6 | ||
![]() |
e6ef21fa9d | ||
![]() |
da89560d6b | ||
![]() |
c0c2373ed6 | ||
![]() |
f2a8eb92a1 | ||
![]() |
48e8ffd729 | ||
![]() |
7327a7008c | ||
![]() |
856c7e7e9e | ||
![]() |
353a4da083 | ||
![]() |
3068c27fd6 | ||
![]() |
7de0bd95b9 | ||
![]() |
904828c3e3 | ||
![]() |
63757f7726 | ||
![]() |
05f16f1719 | ||
![]() |
78e115b698 | ||
![]() |
55b53ed5b7 | ||
![]() |
1fa7b40913 | ||
![]() |
5b7ded9097 | ||
![]() |
06b60b86f2 | ||
![]() |
052c941275 | ||
![]() |
72899b0cf2 | ||
![]() |
342316f5a5 | ||
![]() |
c215faaeb8 | ||
![]() |
c4c342bd0a | ||
![]() |
4472a033a1 | ||
![]() |
093876a445 | ||
![]() |
359e0926cb |
108
.gitlab-ci.yml
108
.gitlab-ci.yml
@@ -1,108 +0,0 @@
|
||||
cache:
|
||||
untracked: true
|
||||
key: "$CI_BUILD_REF_NAME"
|
||||
paths:
|
||||
- app/node_modules
|
||||
- node_modules
|
||||
- typings
|
||||
|
||||
stages:
|
||||
- Build
|
||||
- Test
|
||||
- Package
|
||||
- Upload
|
||||
|
||||
Build:
|
||||
stage: Build
|
||||
script:
|
||||
- npm prune
|
||||
- npm install
|
||||
- cd app; npm prune && npm install; cd ..
|
||||
- ./node_modules/.bin/typings install
|
||||
tags:
|
||||
- Linux
|
||||
artifacts:
|
||||
paths:
|
||||
- node_modules
|
||||
- typings
|
||||
- app
|
||||
|
||||
Test:
|
||||
stage: Test
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- apt-get install -y xvfb libxtst6 libxss1 libgconf2-4 libnss3 libasound2
|
||||
- xvfb-run -a make coverage
|
||||
tags:
|
||||
- Linux
|
||||
|
||||
Windows package:
|
||||
stage: Package
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- call npm install
|
||||
- call npm install webpack # regenerate the .cmd launcher
|
||||
- cd app
|
||||
- call npm install
|
||||
- cd ..
|
||||
- call ./node_modules/.bin/webpack.cmd --progress
|
||||
- call make package-windows
|
||||
- call copy dist\Elements-Electron.exe Elements-Windows-%CI_BUILD_REF_NAME%.exe
|
||||
artifacts:
|
||||
name: Elements-Windows-%CI_BUILD_REF_NAME%
|
||||
paths:
|
||||
- Elements-Windows-%CI_BUILD_REF_NAME%.exe
|
||||
tags:
|
||||
- Windows
|
||||
|
||||
macOS package:
|
||||
stage: Package
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- npm install
|
||||
- rm -rf node_modules/electron-macos-sign || true
|
||||
- cp -r node_modules/electron-osx-sign node_modules/electron-macos-sign
|
||||
- cd app; npm install; cd ..
|
||||
- ./node_modules/.bin/webpack --progress
|
||||
- security unlock-keychain -p rjvg login.keychain
|
||||
- make package-mac
|
||||
- cp dist/Elements-Electron.pkg ./Elements-macOS-$CI_BUILD_REF_NAME.pkg
|
||||
artifacts:
|
||||
name: Elements-macOS-$CI_BUILD_REF_NAME
|
||||
paths:
|
||||
- Elements-macOS-$CI_BUILD_REF_NAME.pkg
|
||||
tags:
|
||||
- macOS
|
||||
|
||||
Linux package:
|
||||
stage: Package
|
||||
dependencies:
|
||||
- Build
|
||||
script:
|
||||
- npm install
|
||||
- cd app; npm install; cd ..
|
||||
- ./node_modules/.bin/webpack --progress
|
||||
- make build-linux
|
||||
- cp dist/ELEMENTS*.AppImage ./Elements-Linux-$CI_BUILD_REF_NAME.AppImage
|
||||
artifacts:
|
||||
name: Elements-Linux-$CI_BUILD_REF_NAME
|
||||
paths:
|
||||
- Elements-Linux-$CI_BUILD_REF_NAME.AppImage
|
||||
tags:
|
||||
- Linux
|
||||
|
||||
Upload packages:
|
||||
stage: Upload
|
||||
dependencies:
|
||||
- Windows package
|
||||
- macOS package
|
||||
- Linux package
|
||||
script:
|
||||
- scp Elements-Windows-$CI_BUILD_REF_NAME.exe root@cloud.elements.tv:/mnt/elements/www/clients/
|
||||
- scp Elements-macOS-$CI_BUILD_REF_NAME.pkg root@cloud.elements.tv:/mnt/elements/www/clients/
|
||||
- scp Elements-Linux-$CI_BUILD_REF_NAME.AppImage root@cloud.elements.tv:/mnt/elements/www/clients/
|
||||
tags:
|
||||
- Local
|
@@ -10,12 +10,14 @@ First, install the dependencies:
|
||||
|
||||
```
|
||||
# macOS/Linux:
|
||||
npm i
|
||||
sudo npm -g install yarn node-gyp
|
||||
yarn install
|
||||
./scripts/install-deps.js
|
||||
./scripts/build-native.js
|
||||
|
||||
# Windows:
|
||||
npm i
|
||||
npm -g install yarn node-gyp windows-build-tools
|
||||
yarn install
|
||||
node scripts\install-deps.js
|
||||
node scripts\build-native.js
|
||||
```
|
||||
|
@@ -13,6 +13,7 @@
|
||||
* Theming and color schemes
|
||||
* Configurable hotkey schemes
|
||||
* **GNU Screen** style hotkeys available by default
|
||||
* Default Linux style hotkeys for Copy(`Ctrl`+`Shift`+`C`), and Paste(`Ctrl`+`Shift`+`V`)
|
||||
* Full Unicode support including double-width characters
|
||||
* Doesn't choke on fast-flowing outputs
|
||||
* Tab persistence on macOS and Linux
|
||||
|
86
app/main.js
86
app/main.js
@@ -8,8 +8,8 @@ if (process.argv.indexOf('--debug') !== -1) {
|
||||
|
||||
let app = electron.app
|
||||
|
||||
let secondInstance = app.makeSingleInstance((argv) => {
|
||||
app.window.webContents.send('host:second-instance')
|
||||
let secondInstance = app.makeSingleInstance((argv, cwd) => {
|
||||
app.window.webContents.send('host:second-instance', argv, cwd)
|
||||
})
|
||||
|
||||
if (secondInstance) {
|
||||
@@ -108,25 +108,79 @@ setupWindowManagement = () => {
|
||||
|
||||
|
||||
setupMenu = () => {
|
||||
var template = [{
|
||||
let template = [{
|
||||
label: "Application",
|
||||
submenu: [
|
||||
{ type: "separator" },
|
||||
{ label: "Quit", accelerator: "CmdOrCtrl+Q", click: () => {
|
||||
app.window.webContents.send('host:quit-request')
|
||||
}}
|
||||
{ role: 'about', label: 'About Terminus' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Preferences',
|
||||
accelerator: 'Cmd+,',
|
||||
click () {
|
||||
app.window.webContents.send('host:preferences-menu')
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ role: 'services', submenu: [] },
|
||||
{ type: 'separator' },
|
||||
{ role: 'hide' },
|
||||
{ role: 'hideothers' },
|
||||
{ role: 'unhide' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Quit',
|
||||
accelerator: 'Cmd+Q',
|
||||
click () {
|
||||
app.window.webContents.send('host:quit-request')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
label: "Edit",
|
||||
submenu: [
|
||||
{ label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
|
||||
{ label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
|
||||
{ type: "separator" },
|
||||
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
|
||||
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
|
||||
{ label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
|
||||
{ label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
|
||||
{role: 'undo'},
|
||||
{role: 'redo'},
|
||||
{type: 'separator'},
|
||||
{role: 'cut'},
|
||||
{role: 'copy'},
|
||||
{role: 'paste'},
|
||||
{role: 'pasteandmatchstyle'},
|
||||
{role: 'delete'},
|
||||
{role: 'selectall'}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{role: 'reload'},
|
||||
{role: 'forcereload'},
|
||||
{role: 'toggledevtools'},
|
||||
{type: 'separator'},
|
||||
{role: 'resetzoom'},
|
||||
{role: 'zoomin'},
|
||||
{role: 'zoomout'},
|
||||
{type: 'separator'},
|
||||
{role: 'togglefullscreen'}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{role: 'close'},
|
||||
{role: 'minimize'},
|
||||
{role: 'zoom'},
|
||||
{type: 'separator'},
|
||||
{role: 'front'}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Website',
|
||||
click () { electron.shell.openExternal('https://eugeny.github.io/terminus') }
|
||||
}
|
||||
]
|
||||
}]
|
||||
|
||||
|
@@ -12,6 +12,10 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
|
||||
import { getRootModule } from './app.module'
|
||||
import { findPlugins, loadPlugins } from './plugins'
|
||||
|
||||
if (process.platform == 'win32') {
|
||||
process.env.HOME = process.env.HOMEDRIVE + process.env.HOMEPATH
|
||||
}
|
||||
|
||||
if (require('electron-is-dev')) {
|
||||
console.warn('Running in debug mode')
|
||||
} else {
|
||||
|
@@ -44,6 +44,7 @@ export interface IPluginInfo {
|
||||
packageName: string
|
||||
isBuiltin: boolean
|
||||
version: string
|
||||
author: string
|
||||
homepage?: string
|
||||
path?: string
|
||||
info?: any
|
||||
@@ -116,12 +117,15 @@ export async function findPlugins (): Promise<IPluginInfo[]> {
|
||||
if (!info.keywords || info.keywords.indexOf('terminus-plugin') === -1) {
|
||||
continue
|
||||
}
|
||||
let author = info.author
|
||||
author = author.name || author
|
||||
foundPlugins.push({
|
||||
name: pluginName.substring('terminus-'.length),
|
||||
packageName: pluginName,
|
||||
isBuiltin: pluginDir === builtinPluginsPath,
|
||||
version: info.version,
|
||||
description: info.description,
|
||||
author,
|
||||
path: pluginPath,
|
||||
info,
|
||||
})
|
||||
|
255
app/yarn.lock
Normal file
255
app/yarn.lock
Normal file
@@ -0,0 +1,255 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@angular/animations@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.0.1.tgz#154420c8ee5c22fbaf1434b6d156150cf5218da6"
|
||||
|
||||
"@angular/common@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.0.1.tgz#df488eada842b2d841ded750712292b18387b5b0"
|
||||
|
||||
"@angular/compiler@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.0.1.tgz#15721edb148167a2d83b6f9324817e658eac8280"
|
||||
|
||||
"@angular/core@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.0.1.tgz#0b110a001012076ea696460ccd922707bcdf51ba"
|
||||
|
||||
"@angular/forms@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.0.1.tgz#b9ebdbbb8ace0f9a3bf9e53c299eafdfab1d5041"
|
||||
|
||||
"@angular/platform-browser-dynamic@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.0.1.tgz#fd5debb2d3f6474350965e71c2674e2170d7cfcb"
|
||||
|
||||
"@angular/platform-browser@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.0.1.tgz#4b9efbeb2fbb900de188743b988802d3aa2b33ff"
|
||||
|
||||
"@ng-bootstrap/ng-bootstrap@1.0.0-alpha.22":
|
||||
version "1.0.0-alpha.22"
|
||||
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0-alpha.22.tgz#aaad058cc39293ea6184e4b9b849f298c0b11a86"
|
||||
|
||||
"@types/mz@0.0.31":
|
||||
version "0.0.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-0.0.31.tgz#a4d80c082fefe71e40a7c0f07d1e6555bbbc7b52"
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "8.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.7.tgz#fb0ad04b5b6f6eabe0372a32a8f1fbba5c130cae"
|
||||
|
||||
accessibility-developer-tools@^2.11.0:
|
||||
version "2.12.0"
|
||||
resolved "https://registry.yarnpkg.com/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz#3da0cce9d6ec6373964b84f35db7cfc3df7ab514"
|
||||
|
||||
any-promise@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
|
||||
|
||||
argparse@^1.0.7:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
conf@^0.11.1:
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/conf/-/conf-0.11.2.tgz#879f479267600483e502583462ca4063fc9779b2"
|
||||
dependencies:
|
||||
dot-prop "^3.0.0"
|
||||
env-paths "^0.3.0"
|
||||
mkdirp "^0.5.1"
|
||||
pkg-up "^1.0.0"
|
||||
|
||||
debug@^2.2.0, debug@^2.6.8:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
devtron@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/devtron/-/devtron-1.4.0.tgz#b5e748bd6e95bbe70bfcc68aae6fe696119441e1"
|
||||
dependencies:
|
||||
accessibility-developer-tools "^2.11.0"
|
||||
highlight.js "^9.3.0"
|
||||
humanize-plus "^1.8.1"
|
||||
|
||||
dot-prop@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
|
||||
dependencies:
|
||||
is-obj "^1.0.0"
|
||||
|
||||
electron-config@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/electron-config/-/electron-config-0.2.1.tgz#7e12c26412d06bf3ed3896d0479df162986b95ba"
|
||||
dependencies:
|
||||
conf "^0.11.1"
|
||||
|
||||
electron-debug@^1.0.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-debug/-/electron-debug-1.2.0.tgz#22e51a73e1bf095d0bb51a6c3d97a203364c4222"
|
||||
dependencies:
|
||||
electron-is-dev "^0.1.0"
|
||||
electron-localshortcut "^2.0.0"
|
||||
|
||||
electron-is-accelerator@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
|
||||
|
||||
electron-is-dev@0.1.2, electron-is-dev@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.1.2.tgz#8a1043e32b3a1da1c3f553dce28ce764246167e3"
|
||||
|
||||
electron-localshortcut@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-localshortcut/-/electron-localshortcut-2.0.2.tgz#6a1adcd6514c957328ec7912f5ccb5e1c10706db"
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
electron-is-accelerator "^0.1.0"
|
||||
|
||||
electron-squirrel-startup@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz#19b4e55933fa0ef8f556784b9c660f772546a0b8"
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
|
||||
env-paths@^0.3.0:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-0.3.1.tgz#c30ccfcbc30c890943dc08a85582517ef00da463"
|
||||
|
||||
esprima@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
|
||||
|
||||
find-up@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
|
||||
dependencies:
|
||||
path-exists "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
highlight.js@^9.3.0:
|
||||
version "9.12.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
|
||||
|
||||
humanize-plus@^1.8.1:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030"
|
||||
|
||||
inherits@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
||||
|
||||
is-obj@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
||||
|
||||
js-yaml@3.8.2:
|
||||
version "3.8.2"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721"
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
esprima "^3.1.1"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
||||
mz@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mz/-/mz-2.6.0.tgz#c8b8521d958df0a4f2768025db69c719ee4ef1ce"
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
path-exists@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
|
||||
dependencies:
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
path@0.12.7:
|
||||
version "0.12.7"
|
||||
resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f"
|
||||
dependencies:
|
||||
process "^0.11.1"
|
||||
util "^0.10.3"
|
||||
|
||||
pinkie-promise@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
|
||||
dependencies:
|
||||
pinkie "^2.0.0"
|
||||
|
||||
pinkie@^2.0.0:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||
|
||||
pkg-up@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26"
|
||||
dependencies:
|
||||
find-up "^1.0.0"
|
||||
|
||||
process@^0.11.1:
|
||||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
|
||||
rxjs@5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.3.0.tgz#d88ccbdd46af290cbdb97d5d8055e52453fabe2d"
|
||||
dependencies:
|
||||
symbol-observable "^1.0.1"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
|
||||
symbol-observable@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
|
||||
|
||||
thenify-all@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
|
||||
dependencies:
|
||||
thenify ">= 3.1.0 < 4"
|
||||
|
||||
"thenify@>= 3.1.0 < 4":
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
|
||||
util@^0.10.3:
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
|
||||
dependencies:
|
||||
inherits "2.0.1"
|
||||
|
||||
zone.js@0.8.4:
|
||||
version "0.8.4"
|
||||
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.8.4.tgz#cc40ae5a1c879601c5ebba2096b5c80f0c4c3602"
|
19
package.json
19
package.json
@@ -9,7 +9,7 @@
|
||||
"core-js": "2.4.1",
|
||||
"cross-env": "4.0.0",
|
||||
"css-loader": "0.28.0",
|
||||
"electron": "1.7.2",
|
||||
"electron": "1.6.11",
|
||||
"electron-builder": "17.1.1",
|
||||
"electron-builder-squirrel-windows": "17.0.1",
|
||||
"electron-rebuild": "1.5.11",
|
||||
@@ -20,7 +20,7 @@
|
||||
"less": "2.7.1",
|
||||
"less-loader": "2.2.3",
|
||||
"node-abi": "2.0.3",
|
||||
"node-gyp": "3.4.0",
|
||||
"node-gyp": "^3.6.2",
|
||||
"node-sass": "^4.5.3",
|
||||
"npmlog": "4.1.0",
|
||||
"pug": "2.0.0-beta11",
|
||||
@@ -67,16 +67,27 @@
|
||||
"icon": "./build/icons"
|
||||
},
|
||||
"deb": {
|
||||
"depends": ["screen", "gconf2", "gconf-service", "libnotify4", "libappindicator1", "libxtst6", "libnss3"]
|
||||
"depends": [
|
||||
"screen",
|
||||
"gconf2",
|
||||
"gconf-service",
|
||||
"libnotify4",
|
||||
"libappindicator1",
|
||||
"libxtst6",
|
||||
"libnss3"
|
||||
]
|
||||
},
|
||||
"rpm": {
|
||||
"depends": ["screen"]
|
||||
"depends": [
|
||||
"screen"
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --color --config app/webpack.config.js && webpack --color --config terminus-core/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-terminal/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-plugin-manager/webpack.config.js && webpack --color --config terminus-community-color-schemes/webpack.config.js",
|
||||
"watch": "webpack --progress --color --watch",
|
||||
"start": "cross-env DEV=1 electron --js-flags='--ignition' app --debug",
|
||||
"prod": "cross-env DEV=1 electron --js-flags='--ignition' app",
|
||||
"lint": "tslint -c tslint.json -t stylish terminus-*/src/**/*.ts terminus-*/src/*.ts app/src/*.ts",
|
||||
"postinstall": "install-app-deps"
|
||||
},
|
||||
|
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"name": "terminus-community-color-schemes",
|
||||
"version": "1.0.0-alpha.14",
|
||||
"version": "1.0.0-alpha.16-8-gfc060ac",
|
||||
"description": "Community color schemes for Terminus",
|
||||
"keywords": ["terminus-plugin"],
|
||||
"keywords": [
|
||||
"terminus-plugin"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
|
44
terminus-community-color-schemes/schemes/Base16 Default Dark
Normal file
44
terminus-community-color-schemes/schemes/Base16 Default Dark
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xreources.py
|
||||
!
|
||||
*.foreground: #d8d8d8
|
||||
*.background: #181818
|
||||
*.cursorColor: #d8d8d8
|
||||
!
|
||||
! Black
|
||||
*.color0: #181818
|
||||
*.color8: #585858
|
||||
!
|
||||
! Red
|
||||
*.color1: #ab4642
|
||||
*.color9: #ab4642
|
||||
!
|
||||
! Green
|
||||
*.color2: #a1b56c
|
||||
*.color10: #a1b56c
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #f7ca88
|
||||
*.color11: #f7ca88
|
||||
!
|
||||
! Blue
|
||||
*.color4: #7cafc2
|
||||
*.color12: #7cafc2
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #ba8baf
|
||||
*.color13: #ba8baf
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #86c1b9
|
||||
*.color14: #86c1b9
|
||||
!
|
||||
! White
|
||||
*.color7: #d8d8d8
|
||||
*.color15: #f8f8f8
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #d8d8d8
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
44
terminus-community-color-schemes/schemes/base2tone-cave-dark
Normal file
44
terminus-community-color-schemes/schemes/base2tone-cave-dark
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #9f999b
|
||||
*.background: #222021
|
||||
*.cursorColor: #996e00
|
||||
!
|
||||
! Black
|
||||
*.color0: #222021
|
||||
*.color8: #635f60
|
||||
!
|
||||
! Red
|
||||
*.color1: #936c7a
|
||||
*.color9: #ddaf3c
|
||||
!
|
||||
! Green
|
||||
*.color2: #cca133
|
||||
*.color10: #2f2d2e
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #ffcc4d
|
||||
*.color11: #565254
|
||||
!
|
||||
! Blue
|
||||
*.color4: #9c818b
|
||||
*.color12: #706b6d
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #cca133
|
||||
*.color13: #f0a8c1
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #d27998
|
||||
*.color14: #c39622
|
||||
!
|
||||
! White
|
||||
*.color7: #9f999b
|
||||
*.color15: #ffebf2
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #9f999b
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #ada594
|
||||
*.background: #292724
|
||||
*.cursorColor: #bc672f
|
||||
!
|
||||
! Black
|
||||
*.color0: #292724
|
||||
*.color8: #7e7767
|
||||
!
|
||||
! Red
|
||||
*.color1: #816f4b
|
||||
*.color9: #f29d63
|
||||
!
|
||||
! Green
|
||||
*.color2: #ec9255
|
||||
*.color10: #3d3a34
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #ffb380
|
||||
*.color11: #615c51
|
||||
!
|
||||
! Blue
|
||||
*.color4: #957e50
|
||||
*.color12: #908774
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #ec9255
|
||||
*.color13: #ddcba6
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #ac8e53
|
||||
*.color14: #e58748
|
||||
!
|
||||
! White
|
||||
*.color7: #ada594
|
||||
*.color15: #f2ead9
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #ada594
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #9094a7
|
||||
*.background: #1b1f32
|
||||
*.cursorColor: #289dbd
|
||||
!
|
||||
! Black
|
||||
*.color0: #1b1f32
|
||||
*.color8: #51587b
|
||||
!
|
||||
! Red
|
||||
*.color1: #627af4
|
||||
*.color9: #75d5f0
|
||||
!
|
||||
! Green
|
||||
*.color2: #67c9e4
|
||||
*.color10: #252a41
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #99e9ff
|
||||
*.color11: #444b6f
|
||||
!
|
||||
! Blue
|
||||
*.color4: #7289fd
|
||||
*.color12: #5e6587
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #67c9e4
|
||||
*.color13: #c3cdfe
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #8b9efd
|
||||
*.color14: #5cbcd6
|
||||
!
|
||||
! White
|
||||
*.color7: #9094a7
|
||||
*.color15: #e1e6ff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #9094a7
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #a4a1b5
|
||||
*.background: #2a2734
|
||||
*.cursorColor: #b37537
|
||||
!
|
||||
! Black
|
||||
*.color0: #2a2734
|
||||
*.color8: #6c6783
|
||||
!
|
||||
! Red
|
||||
*.color1: #8a75f5
|
||||
*.color9: #ffb870
|
||||
!
|
||||
! Green
|
||||
*.color2: #ffad5c
|
||||
*.color10: #363342
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #ffcc99
|
||||
*.color11: #545167
|
||||
!
|
||||
! Blue
|
||||
*.color4: #9a86fd
|
||||
*.color12: #787391
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #ffad5c
|
||||
*.color13: #d9d2fe
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #afa0fe
|
||||
*.color14: #ffa142
|
||||
!
|
||||
! White
|
||||
*.color7: #a4a1b5
|
||||
*.color15: #eeebff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #a4a1b5
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #a1b5a1
|
||||
*.background: #2a2d2a
|
||||
*.cursorColor: #656b47
|
||||
!
|
||||
! Black
|
||||
*.color0: #2a2d2a
|
||||
*.color8: #535f53
|
||||
!
|
||||
! Red
|
||||
*.color1: #5c705c
|
||||
*.color9: #cbe25a
|
||||
!
|
||||
! Green
|
||||
*.color2: #bfd454
|
||||
*.color10: #353b35
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #e5fb79
|
||||
*.color11: #485148
|
||||
!
|
||||
! Blue
|
||||
*.color4: #687d68
|
||||
*.color12: #5e6e5e
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #bfd454
|
||||
*.color13: #c8e4c8
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #8fae8f
|
||||
*.color14: #b1c44f
|
||||
!
|
||||
! White
|
||||
*.color7: #a1b5a1
|
||||
*.color15: #f0fff0
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #a1b5a1
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #9e999f
|
||||
*.background: #222022
|
||||
*.cursorColor: #995900
|
||||
!
|
||||
! Black
|
||||
*.color0: #222022
|
||||
*.color8: #635f63
|
||||
!
|
||||
! Red
|
||||
*.color1: #8f6c93
|
||||
*.color9: #d9b98c
|
||||
!
|
||||
! Green
|
||||
*.color2: #cc8c33
|
||||
*.color10: #2f2d2f
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #ffd599
|
||||
*.color11: #575158
|
||||
!
|
||||
! Blue
|
||||
*.color4: #9a819c
|
||||
*.color12: #6f6b70
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #cc8c33
|
||||
*.color13: #eaa8f0
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #cb79d2
|
||||
*.color14: #c38022
|
||||
!
|
||||
! White
|
||||
*.color7: #9e999f
|
||||
*.color15: #fdebff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #9e999f
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #575158
|
||||
*.background: #fbfaf9
|
||||
*.cursorColor: #eaa8f0
|
||||
!
|
||||
! Black
|
||||
*.color0: #222022
|
||||
*.color8: #635f63
|
||||
!
|
||||
! Red
|
||||
*.color1: #8f6c93
|
||||
*.color9: #d9b98c
|
||||
!
|
||||
! Green
|
||||
*.color2: #cc8c33
|
||||
*.color10: #2f2d2f
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #ffd599
|
||||
*.color11: #575158
|
||||
!
|
||||
! Blue
|
||||
*.color4: #9a819c
|
||||
*.color12: #6f6b70
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #b87414
|
||||
*.color13: #eaa8f0
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #cb79d2
|
||||
*.color14: #c38022
|
||||
!
|
||||
! White
|
||||
*.color7: #9e999f
|
||||
*.color15: #fbfaf9
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #575158
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
44
terminus-community-color-schemes/schemes/base2tone-lake-dark
Normal file
44
terminus-community-color-schemes/schemes/base2tone-lake-dark
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #7ba8b7
|
||||
*.background: #192d34
|
||||
*.cursorColor: #84740b
|
||||
!
|
||||
! Black
|
||||
*.color0: #192d34
|
||||
*.color8: #3d6876
|
||||
!
|
||||
! Red
|
||||
*.color1: #3e91ac
|
||||
*.color9: #d6c65c
|
||||
!
|
||||
! Green
|
||||
*.color2: #cbbb4d
|
||||
*.color10: #223c44
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #ffeb66
|
||||
*.color11: #335966
|
||||
!
|
||||
! Blue
|
||||
*.color4: #499fbc
|
||||
*.color12: #467686
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #cbbb4d
|
||||
*.color13: #a5d8e9
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #62b1cb
|
||||
*.color14: #c4b031
|
||||
!
|
||||
! White
|
||||
*.color7: #7ba8b7
|
||||
*.color15: #e1f7ff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #7ba8b7
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #7b9eb7
|
||||
*.background: #192834
|
||||
*.cursorColor: #4d8217
|
||||
!
|
||||
! Black
|
||||
*.color0: #192834
|
||||
*.color8: #3d5e76
|
||||
!
|
||||
! Red
|
||||
*.color1: #277fbe
|
||||
*.color9: #8cdd3c
|
||||
!
|
||||
! Green
|
||||
*.color2: #80bf40
|
||||
*.color10: #223644
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #a6f655
|
||||
*.color11: #335166
|
||||
!
|
||||
! Blue
|
||||
*.color4: #4299d7
|
||||
*.color12: #466b86
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #80bf40
|
||||
*.color13: #afddfe
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #47adf5
|
||||
*.color14: #73b234
|
||||
!
|
||||
! White
|
||||
*.color7: #7b9eb7
|
||||
*.color15: #d1ecff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #7b9eb7
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #4f5664
|
||||
*.background: #faf8f5
|
||||
*.cursorColor: #b7c9eb
|
||||
!
|
||||
! Black
|
||||
*.color0: #232834
|
||||
*.color8: #656e81
|
||||
!
|
||||
! Red
|
||||
*.color1: #1659df
|
||||
*.color9: #c6b28b
|
||||
!
|
||||
! Green
|
||||
*.color2: #b29762
|
||||
*.color10: #31363f
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #e5ddcd
|
||||
*.color11: #4f5664
|
||||
!
|
||||
! Blue
|
||||
*.color4: #3d75e6
|
||||
*.color12: #707a8f
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #896724
|
||||
*.color13: #b7c9eb
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #728fcb
|
||||
*.color14: #9a7c42
|
||||
!
|
||||
! White
|
||||
*.color7: #8d95a5
|
||||
*.color15: #faf8f5
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #4f5664
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
44
terminus-community-color-schemes/schemes/base2tone-pool-dark
Normal file
44
terminus-community-color-schemes/schemes/base2tone-pool-dark
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #9a90a7
|
||||
*.background: #2a2433
|
||||
*.cursorColor: #cf504a
|
||||
!
|
||||
! Black
|
||||
*.color0: #2a2433
|
||||
*.color8: #635775
|
||||
!
|
||||
! Red
|
||||
*.color1: #aa75f5
|
||||
*.color9: #fc8983
|
||||
!
|
||||
! Green
|
||||
*.color2: #f87972
|
||||
*.color10: #372f42
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #ffb6b3
|
||||
*.color11: #574b68
|
||||
!
|
||||
! Blue
|
||||
*.color4: #b886fd
|
||||
*.color12: #706383
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #f87972
|
||||
*.color13: #e4d2fe
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #c7a0fe
|
||||
*.color14: #f36f68
|
||||
!
|
||||
! White
|
||||
*.color7: #9a90a7
|
||||
*.color15: #f3ebff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #9a90a7
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
44
terminus-community-color-schemes/schemes/base2tone-sea-dark
Normal file
44
terminus-community-color-schemes/schemes/base2tone-sea-dark
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #a1aab5
|
||||
*.background: #1d262f
|
||||
*.cursorColor: #067953
|
||||
!
|
||||
! Black
|
||||
*.color0: #1d262f
|
||||
*.color8: #4a5f78
|
||||
!
|
||||
! Red
|
||||
*.color1: #34659d
|
||||
*.color9: #14e19d
|
||||
!
|
||||
! Green
|
||||
*.color2: #0fc78a
|
||||
*.color10: #27323f
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #47ebb4
|
||||
*.color11: #405368
|
||||
!
|
||||
! Blue
|
||||
*.color4: #57718e
|
||||
*.color12: #738191
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #0fc78a
|
||||
*.color13: #afd4fe
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #6e9bcf
|
||||
*.color14: #0db57d
|
||||
!
|
||||
! White
|
||||
*.color7: #a1aab5
|
||||
*.color15: #ebf4ff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #a1aab5
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! Generated with :
|
||||
! XRDB2Xrecources.py
|
||||
!
|
||||
*.foreground: #a1a1b5
|
||||
*.background: #24242e
|
||||
*.cursorColor: #b25424
|
||||
!
|
||||
! Black
|
||||
*.color0: #24242e
|
||||
*.color8: #5b5b76
|
||||
!
|
||||
! Red
|
||||
*.color1: #7676f4
|
||||
*.color9: #f37b3f
|
||||
!
|
||||
! Green
|
||||
*.color2: #ec7336
|
||||
*.color10: #333342
|
||||
!
|
||||
! Yellow
|
||||
*.color3: #fe8c52
|
||||
*.color11: #515167
|
||||
!
|
||||
! Blue
|
||||
*.color4: #767693
|
||||
*.color12: #737391
|
||||
!
|
||||
! Magenta
|
||||
*.color5: #ec7336
|
||||
*.color13: #cecee3
|
||||
!
|
||||
! Cyan
|
||||
*.color6: #8a8aad
|
||||
*.color14: #e66e33
|
||||
!
|
||||
! White
|
||||
*.color7: #a1a1b5
|
||||
*.color15: #ebebff
|
||||
!
|
||||
! Bold, Italic, Underline
|
||||
*.colorBD: #a1a1b5
|
||||
!*.colorIT:
|
||||
!*.colorUL:
|
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"name": "terminus-core",
|
||||
"version": "1.0.0-alpha.14",
|
||||
"version": "1.0.0-alpha.16-8-gfc060ac",
|
||||
"description": "Terminus core",
|
||||
"keywords": ["terminus-plugin"],
|
||||
"keywords": [
|
||||
"terminus-plugin"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
|
@@ -50,8 +50,8 @@ export class AppRootComponent {
|
||||
private docking: DockingService,
|
||||
private electron: ElectronService,
|
||||
private tabRecovery: TabRecoveryService,
|
||||
private hotkeys: HotkeysService,
|
||||
public hostApp: HostAppService,
|
||||
public hotkeys: HotkeysService,
|
||||
public config: ConfigService,
|
||||
public app: AppService,
|
||||
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
|
||||
@@ -93,7 +93,7 @@ export class AppRootComponent {
|
||||
this.docking.dock()
|
||||
})
|
||||
|
||||
this.hostApp.secondInstance.subscribe(() => {
|
||||
this.hostApp.secondInstance$.subscribe(() => {
|
||||
this.onGlobalHotkey()
|
||||
})
|
||||
this.hotkeys.globalHotkey.subscribe(() => {
|
||||
|
@@ -25,6 +25,9 @@ div
|
||||
span {{button.title}}
|
||||
|
||||
footer
|
||||
.pull-right
|
||||
.form-control-static Version: {{version}}
|
||||
|
||||
.btn-group
|
||||
button.btn.btn-secondary((click)='openGitHub()')
|
||||
i.fa.fa-github
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import * as os from 'os'
|
||||
import { Component, Inject } from '@angular/core'
|
||||
import { ElectronService } from '../services/electron.service'
|
||||
import { IToolbarButton, ToolbarButtonProvider } from '../api'
|
||||
@@ -8,10 +9,14 @@ import { IToolbarButton, ToolbarButtonProvider } from '../api'
|
||||
styles: [require('./startPage.component.scss')],
|
||||
})
|
||||
export class StartPageComponent {
|
||||
version: string
|
||||
|
||||
constructor (
|
||||
private electron: ElectronService,
|
||||
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
|
||||
) { }
|
||||
) {
|
||||
this.version = electron.app.getVersion()
|
||||
}
|
||||
|
||||
getButtons (): IToolbarButton[] {
|
||||
return this.toolbarButtonProviders
|
||||
@@ -25,6 +30,13 @@ export class StartPageComponent {
|
||||
}
|
||||
|
||||
reportBug () {
|
||||
this.electron.shell.openExternal('https://github.com/eugeny/terminus/issues/new')
|
||||
let body = `Version: ${this.version}\n`
|
||||
body += `Platform: ${os.platform()} ${os.release()}\n\n`
|
||||
let label = {
|
||||
darwin: 'macOS',
|
||||
windows: 'Windows',
|
||||
linux: 'Linux',
|
||||
}[os.platform()]
|
||||
this.electron.shell.openExternal(`https://github.com/eugeny/terminus/issues/new?body=${encodeURIComponent(body)}&labels=${label}`)
|
||||
}
|
||||
}
|
||||
|
@@ -54,6 +54,10 @@ $tabs-height: 36px;
|
||||
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover button {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Component, Input, Output, EventEmitter, HostBinding } from '@angular/core'
|
||||
import { Component, Input, Output, EventEmitter, HostBinding, HostListener } from '@angular/core'
|
||||
import { BaseTabComponent } from '../components/baseTab.component'
|
||||
|
||||
@Component({
|
||||
@@ -12,4 +12,10 @@ export class TabHeaderComponent {
|
||||
@Input() @HostBinding('class.has-activity') hasActivity: boolean
|
||||
@Input() tab: BaseTabComponent
|
||||
@Output() closeClicked = new EventEmitter()
|
||||
|
||||
@HostListener('auxclick', ['$event']) onClick ($event: MouseEvent): void {
|
||||
if ($event.which == 2) {
|
||||
this.closeClicked.emit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -67,7 +67,7 @@ export class ConfigService {
|
||||
this.defaults = configProviders.map(provider => {
|
||||
let defaults = {}
|
||||
if (provider.platformDefaults) {
|
||||
defaults = configMerge(defaults, provider.platformDefaults[hostApp.platform])
|
||||
defaults = configMerge(defaults, provider.platformDefaults[hostApp.platform] || {})
|
||||
}
|
||||
if (provider.defaults) {
|
||||
defaults = configMerge(defaults, provider.defaults)
|
||||
|
@@ -9,12 +9,12 @@ export class ElectronService {
|
||||
clipboard: any
|
||||
globalShortcut: any
|
||||
screen: any
|
||||
remote: any
|
||||
private electron: any
|
||||
private remoteElectron: any
|
||||
|
||||
constructor () {
|
||||
this.electron = require('electron')
|
||||
this.remoteElectron = this.remoteRequire('electron')
|
||||
this.remote = this.electron.remote
|
||||
this.app = this.electron.remote.app
|
||||
this.screen = this.electron.remote.screen
|
||||
this.dialog = this.electron.remote.dialog
|
||||
@@ -25,6 +25,6 @@ export class ElectronService {
|
||||
}
|
||||
|
||||
remoteRequire (name: string): any {
|
||||
return this.electron.remote.require(name)
|
||||
return this.remote.require(name)
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Subject } from 'rxjs'
|
||||
import { Injectable, NgZone, EventEmitter } from '@angular/core'
|
||||
import { ElectronService } from '../services/electron.service'
|
||||
import { Logger, LogService } from '../services/log.service'
|
||||
@@ -18,9 +19,10 @@ export class HostAppService {
|
||||
platform: Platform
|
||||
nodePlatform: string
|
||||
quitRequested = new EventEmitter<any>()
|
||||
preferencesMenu$ = new Subject<void>()
|
||||
ready = new EventEmitter<any>()
|
||||
shown = new EventEmitter<any>()
|
||||
secondInstance = new EventEmitter<any>()
|
||||
secondInstance$ = new Subject<{ argv: string[], cwd: string }>()
|
||||
|
||||
private logger: Logger
|
||||
|
||||
@@ -38,17 +40,18 @@ export class HostAppService {
|
||||
}[this.nodePlatform]
|
||||
|
||||
electron.ipcRenderer.on('host:quit-request', () => this.zone.run(() => this.quitRequested.emit()))
|
||||
electron.ipcRenderer.on('host:preferences-menu', () => this.zone.run(() => this.preferencesMenu$.next()))
|
||||
|
||||
electron.ipcRenderer.on('uncaughtException', (err) => {
|
||||
electron.ipcRenderer.on('uncaughtException', ($event, err) => {
|
||||
this.logger.error('Unhandled exception:', err)
|
||||
})
|
||||
|
||||
electron.ipcRenderer.on('host:window-shown', () => {
|
||||
this.shown.emit()
|
||||
this.zone.run(() => this.shown.emit())
|
||||
})
|
||||
|
||||
electron.ipcRenderer.on('host:second-instance', () => {
|
||||
this.secondInstance.emit()
|
||||
electron.ipcRenderer.on('host:second-instance', ($event, argv: string[], cwd: string) => {
|
||||
this.zone.run(() => this.secondInstance$.next({ argv, cwd }))
|
||||
})
|
||||
|
||||
this.ready.subscribe(() => {
|
||||
|
@@ -178,10 +178,6 @@ export class AppHotkeyProvider extends HotkeyProvider {
|
||||
id: 'toggle-window',
|
||||
name: 'Toggle terminal window',
|
||||
},
|
||||
{
|
||||
id: 'new-tab',
|
||||
name: 'New tab',
|
||||
},
|
||||
{
|
||||
id: 'close-tab',
|
||||
name: 'Close tab',
|
||||
|
@@ -45,7 +45,9 @@ export function stringifyKeySequence (events: NativeKeyEvent[]): string[] {
|
||||
// TODO make this optional?
|
||||
continue
|
||||
}
|
||||
if (event.key.length === 1) {
|
||||
if (event.key === ' ') {
|
||||
itemKeys.push('Space')
|
||||
} else if (event.key.length === 1) {
|
||||
itemKeys.push(event.key.toUpperCase())
|
||||
} else {
|
||||
itemKeys.push(event.key)
|
||||
|
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"name": "terminus-plugin-manager",
|
||||
"version": "1.0.0-alpha.14",
|
||||
"version": "1.0.0-alpha.16-8-gfc060ac",
|
||||
"description": "Terminus' plugin manager",
|
||||
"keywords": ["terminus-plugin"],
|
||||
"keywords": [
|
||||
"terminus-plugin"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
@@ -34,7 +36,8 @@
|
||||
"rxjs": "5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.16.2"
|
||||
"axios": "^0.16.2",
|
||||
"mz": "^2.6.0"
|
||||
},
|
||||
"false": {}
|
||||
}
|
||||
|
@@ -15,7 +15,9 @@ h3 Installed
|
||||
.mr-auto.d-flex.flex-column
|
||||
strong {{plugin.name}}
|
||||
small.text-muted.mb-0 {{plugin.description}}
|
||||
p.mb-0.mr-3 {{plugin.version}}
|
||||
.d-flex.flex-column.align-items-end.mr-3
|
||||
div {{plugin.version}}
|
||||
small.text-muted {{plugin.author}}
|
||||
button.btn.btn-outline-primary(
|
||||
*ngIf='npmInstalled',
|
||||
(click)='upgradePlugin(plugin)',
|
||||
@@ -31,7 +33,10 @@ h3 Installed
|
||||
.mr-auto.d-flex.flex-column
|
||||
strong {{plugin.name}}
|
||||
small.text-muted.mb-0 {{plugin.description}}
|
||||
p.mb-0.mr-3 {{plugin.version}}
|
||||
.d-flex.flex-column.align-items-end.mr-3
|
||||
div {{plugin.version}}
|
||||
small.text-muted {{plugin.author}}
|
||||
i.fa.fa-check.text-success.ml-1(*ngIf='plugin.isOfficial', title='Official')
|
||||
button.btn.btn-outline-danger(
|
||||
(click)='uninstallPlugin(plugin)',
|
||||
*ngIf='!plugin.isBuiltin && npmInstalled',
|
||||
@@ -41,12 +46,12 @@ h3 Installed
|
||||
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Uninstalling')
|
||||
|
||||
.text-center.mt-5(*ngIf='npmMissing')
|
||||
h4 NPM not installed
|
||||
p.mb-2 The Node Package Manager is required to install Terminus plugins.
|
||||
h4 npm not installed
|
||||
p.mb-2 npm is required to install Terminus plugins.
|
||||
.btn-group
|
||||
button.btn.btn-outline-primary((click)='downloadNPM()')
|
||||
i.fa.fa-download
|
||||
span Download NPM
|
||||
span Get npm
|
||||
button.btn.btn-outline-info((click)='checkNPM()')
|
||||
i.fa.fa-refresh
|
||||
span Try again
|
||||
@@ -73,7 +78,10 @@ div(*ngIf='npmInstalled')
|
||||
.mr-auto.d-flex.flex-column
|
||||
strong {{plugin.name}}
|
||||
small.text-muted.mb-0 {{plugin.description}}
|
||||
p.mb-0.mr-3 {{plugin.version}}
|
||||
.d-flex.flex-column.align-items-end.mr-3
|
||||
div {{plugin.version}}
|
||||
small.text-muted {{plugin.author}}
|
||||
i.fa.fa-check.text-success.ml-1(*ngIf='plugin.isOfficial', title='Official')
|
||||
button.btn.btn-outline-primary(
|
||||
(click)='installPlugin(plugin)',
|
||||
[disabled]='busy[plugin.name] != undefined'
|
||||
|
7
terminus-plugin-manager/src/config.ts
Normal file
7
terminus-plugin-manager/src/config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { ConfigProvider } from 'terminus-core'
|
||||
|
||||
export class PluginsConfigProvider extends ConfigProvider {
|
||||
defaults = {
|
||||
npm: 'npm',
|
||||
}
|
||||
}
|
@@ -4,10 +4,12 @@ import { FormsModule } from '@angular/forms'
|
||||
import { NgPipesModule } from 'ngx-pipes'
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
import { ConfigProvider } from 'terminus-core'
|
||||
import { SettingsTabProvider } from 'terminus-settings'
|
||||
|
||||
import { PluginsSettingsTabComponent } from './components/pluginsSettingsTab.component'
|
||||
import { PluginManagerService } from './services/pluginManager.service'
|
||||
import { PluginsConfigProvider } from './config'
|
||||
import { PluginsSettingsTabProvider } from './settings'
|
||||
|
||||
@NgModule({
|
||||
@@ -19,6 +21,7 @@ import { PluginsSettingsTabProvider } from './settings'
|
||||
],
|
||||
providers: [
|
||||
{ provide: SettingsTabProvider, useClass: PluginsSettingsTabProvider, multi: true },
|
||||
{ provide: ConfigProvider, useClass: PluginsConfigProvider, multi: true },
|
||||
PluginManagerService,
|
||||
],
|
||||
entryComponents: [
|
||||
|
@@ -1,19 +1,24 @@
|
||||
import { Observable } from 'rxjs'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { Logger, LogService } from 'terminus-core'
|
||||
import * as path from 'path'
|
||||
import * as fs from 'mz/fs'
|
||||
import { exec } from 'mz/child_process'
|
||||
import axios from 'axios'
|
||||
import { Observable } from 'rxjs'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { Logger, LogService, ConfigService, HostAppService, Platform } from 'terminus-core'
|
||||
|
||||
const NAME_PREFIX = 'terminus-'
|
||||
const KEYWORD = 'terminus-plugin'
|
||||
const OFFICIAL_NPM_ACCOUNT = 'eugenepankov'
|
||||
|
||||
export interface IPluginInfo {
|
||||
name: string
|
||||
description: string
|
||||
packageName: string
|
||||
isBuiltin: boolean
|
||||
isOfficial: boolean
|
||||
version: string
|
||||
homepage?: string
|
||||
author: string
|
||||
path?: string
|
||||
}
|
||||
|
||||
@@ -23,17 +28,38 @@ export class PluginManagerService {
|
||||
builtinPluginsPath: string = (window as any).builtinPluginsPath
|
||||
userPluginsPath: string = (window as any).userPluginsPath
|
||||
installedPlugins: IPluginInfo[] = (window as any).installedPlugins
|
||||
npmBinary = 'npm'
|
||||
npmPath: string
|
||||
|
||||
constructor (
|
||||
log: LogService,
|
||||
private config: ConfigService,
|
||||
private hostApp: HostAppService,
|
||||
) {
|
||||
this.logger = log.create('pluginManager')
|
||||
this.detectPath()
|
||||
}
|
||||
|
||||
async detectPath () {
|
||||
this.npmPath = this.config.store.npm
|
||||
if (await fs.exists(this.npmPath)) {
|
||||
return
|
||||
}
|
||||
if (this.hostApp.platform !== Platform.Windows) {
|
||||
let searchPaths = (await exec('bash -c -l "echo $PATH"'))[0].toString().trim().split(':')
|
||||
for (let searchPath of searchPaths) {
|
||||
if (await fs.exists(path.join(searchPath, 'npm'))) {
|
||||
this.logger.debug('Found npm in', searchPath)
|
||||
this.npmPath = path.join(searchPath, 'npm')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async isNPMInstalled (): Promise<boolean> {
|
||||
await this.detectPath()
|
||||
try {
|
||||
await exec(`${this.npmBinary} -v`)
|
||||
await exec(`${this.npmPath} -v`)
|
||||
return true
|
||||
} catch (_) {
|
||||
return false
|
||||
@@ -45,25 +71,28 @@ export class PluginManagerService {
|
||||
.fromPromise(
|
||||
axios.get(`https://www.npmjs.com/-/search?text=keywords:${KEYWORD}+${encodeURIComponent(query || '')}&from=0&size=1000`)
|
||||
)
|
||||
.do(response => console.log(response.data.objects))
|
||||
.map(response => response.data.objects.map(item => ({
|
||||
name: item.package.name.substring(NAME_PREFIX.length),
|
||||
packageName: item.package.name,
|
||||
description: item.package.description,
|
||||
version: item.package.version,
|
||||
homepage: item.package.links.homepage,
|
||||
author: (item.package.author || {}).name,
|
||||
isOfficial: item.package.publisher.username === OFFICIAL_NPM_ACCOUNT,
|
||||
})))
|
||||
.map(plugins => plugins.filter(x => x.packageName.startsWith(NAME_PREFIX)))
|
||||
}
|
||||
|
||||
async installPlugin (plugin: IPluginInfo) {
|
||||
let result = await exec(`${this.npmBinary} --prefix "${this.userPluginsPath}" install ${plugin.packageName}@${plugin.version}`)
|
||||
let result = await exec(`${this.npmPath} --prefix "${this.userPluginsPath}" install ${plugin.packageName}@${plugin.version}`)
|
||||
console.log(result)
|
||||
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
|
||||
this.installedPlugins.push(plugin)
|
||||
}
|
||||
|
||||
async uninstallPlugin (plugin: IPluginInfo) {
|
||||
await exec(`${this.npmBinary} --prefix "${this.userPluginsPath}" remove ${plugin.packageName}`)
|
||||
await exec(`${this.npmPath} --prefix "${this.userPluginsPath}" remove ${plugin.packageName}`)
|
||||
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
|
||||
}
|
||||
}
|
||||
|
@@ -37,10 +37,10 @@ module.exports = {
|
||||
},
|
||||
externals: [
|
||||
'fs',
|
||||
'fs-promise',
|
||||
'font-manager',
|
||||
'path',
|
||||
'node-pty',
|
||||
'mz/fs',
|
||||
'mz/child_process',
|
||||
'winreg',
|
||||
/^rxjs/,
|
||||
|
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"name": "terminus-settings",
|
||||
"version": "1.0.0-alpha.14",
|
||||
"version": "1.0.0-alpha.16-8-gfc060ac",
|
||||
"description": "Terminus terminal settings page",
|
||||
"keywords": ["terminus-plugin"],
|
||||
"keywords": [
|
||||
"terminus-plugin"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
|
@@ -1,14 +1,16 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ToolbarButtonProvider, IToolbarButton, AppService } from 'terminus-core'
|
||||
import { ToolbarButtonProvider, IToolbarButton, AppService, HostAppService } from 'terminus-core'
|
||||
|
||||
import { SettingsTabComponent } from './components/settingsTab.component'
|
||||
|
||||
@Injectable()
|
||||
export class ButtonProvider extends ToolbarButtonProvider {
|
||||
constructor (
|
||||
hostApp: HostAppService,
|
||||
private app: AppService,
|
||||
) {
|
||||
super()
|
||||
hostApp.preferencesMenu$.subscribe(() => this.open())
|
||||
}
|
||||
|
||||
provide (): IToolbarButton[] {
|
||||
@@ -16,14 +18,16 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
||||
icon: 'sliders',
|
||||
title: 'Settings',
|
||||
weight: 10,
|
||||
click: () => {
|
||||
let settingsTab = this.app.tabs.find((tab) => tab instanceof SettingsTabComponent)
|
||||
if (settingsTab) {
|
||||
this.app.selectTab(settingsTab)
|
||||
} else {
|
||||
this.app.openNewTab(SettingsTabComponent)
|
||||
}
|
||||
}
|
||||
click: () => this.open(),
|
||||
}]
|
||||
}
|
||||
|
||||
open (): void {
|
||||
let settingsTab = this.app.tabs.find((tab) => tab instanceof SettingsTabComponent)
|
||||
if (settingsTab) {
|
||||
this.app.selectTab(settingsTab)
|
||||
} else {
|
||||
this.app.openNewTab(SettingsTabComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -73,6 +73,7 @@ export class HotkeyInputModalComponent {
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
this.hotkeys.clearCurrentKeystrokes()
|
||||
this.hotkeys.enable()
|
||||
clearInterval(this.keyTimeoutInterval)
|
||||
}
|
||||
|
@@ -38,10 +38,8 @@ module.exports = {
|
||||
},
|
||||
externals: [
|
||||
'fs',
|
||||
'fs-promise',
|
||||
'path',
|
||||
'node-pty',
|
||||
'fs-promise',
|
||||
/^rxjs/,
|
||||
/^@angular/,
|
||||
/^@ng-bootstrap/,
|
||||
|
@@ -1,8 +1,10 @@
|
||||
{
|
||||
"name": "terminus-terminal",
|
||||
"version": "1.0.0-alpha.14",
|
||||
"version": "1.0.0-alpha.16-8-gfc060ac",
|
||||
"description": "Terminus' terminal emulation core",
|
||||
"keywords": ["terminus-plugin"],
|
||||
"keywords": [
|
||||
"terminus-plugin"
|
||||
],
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
@@ -35,10 +37,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"font-manager": "0.2.2",
|
||||
"fs-promise": "2.0.2",
|
||||
"hterm-umdjs": "1.1.3",
|
||||
"hterm-umdjs": "1.2.0",
|
||||
"mz": "^2.6.0",
|
||||
"node-pty": "0.6.2",
|
||||
"node-pty": "0.6.8",
|
||||
"winreg": "^1.2.3"
|
||||
},
|
||||
"false": {}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import * as path from 'path'
|
||||
import { exec } from 'mz/child_process'
|
||||
import * as fs from 'mz/fs'
|
||||
import * as path from 'path'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HotkeysService, ToolbarButtonProvider, IToolbarButton, AppService, ConfigService, ElectronService, HostAppService, Platform } from 'terminus-core'
|
||||
import { HotkeysService, ToolbarButtonProvider, IToolbarButton, AppService, ConfigService, HostAppService, Platform, ElectronService } from 'terminus-core'
|
||||
|
||||
import { SessionsService } from './services/sessions.service'
|
||||
import { ShellsService } from './services/shells.service'
|
||||
import { TerminalTabComponent } from './components/terminalTab.component'
|
||||
|
||||
@Injectable()
|
||||
@@ -13,8 +13,9 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
||||
private app: AppService,
|
||||
private sessions: SessionsService,
|
||||
private config: ConfigService,
|
||||
private electron: ElectronService,
|
||||
private shells: ShellsService,
|
||||
private hostApp: HostAppService,
|
||||
electron: ElectronService,
|
||||
hotkeys: HotkeysService,
|
||||
) {
|
||||
super()
|
||||
@@ -23,46 +24,50 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
||||
this.openNewTab()
|
||||
}
|
||||
})
|
||||
hostApp.secondInstance$.subscribe(async ({argv, cwd}) => {
|
||||
if (argv.length === 2) {
|
||||
let arg = path.resolve(cwd, argv[1])
|
||||
if (await fs.exists(arg)) {
|
||||
this.openNewTab(arg)
|
||||
}
|
||||
}
|
||||
})
|
||||
if (!electron.remote.process.env.DEV) {
|
||||
setImmediate(async () => {
|
||||
let argv: string[] = electron.remote.process.argv
|
||||
for (let arg of argv.slice(1)) {
|
||||
if (await fs.exists(arg)) {
|
||||
if ((await fs.stat(arg)).isDirectory()) {
|
||||
this.openNewTab(arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async openNewTab (): Promise<void> {
|
||||
let cwd = null
|
||||
if (this.app.activeTab instanceof TerminalTabComponent) {
|
||||
async openNewTab (cwd?: string): Promise<void> {
|
||||
if (!cwd && this.app.activeTab instanceof TerminalTabComponent) {
|
||||
cwd = await this.app.activeTab.session.getWorkingDirectory()
|
||||
}
|
||||
let command = this.config.store.terminal.shell
|
||||
let args = []
|
||||
// TODO move this?
|
||||
let env: any = {}
|
||||
let args: string[] = []
|
||||
if (command === '~clink~') {
|
||||
command = 'cmd.exe'
|
||||
args = [
|
||||
'/k',
|
||||
path.join(
|
||||
path.dirname(this.electron.app.getPath('exe')),
|
||||
(process.platform === 'darwin') ? '../Resources' : 'resources',
|
||||
'clink',
|
||||
`clink_${process.arch}.exe`,
|
||||
),
|
||||
'inject',
|
||||
]
|
||||
({ command, args } = this.shells.getClinkOptions())
|
||||
}
|
||||
if (command === '~default-shell~') {
|
||||
if (this.hostApp.platform === Platform.Linux) {
|
||||
let line = (await fs.readFile('/etc/passwd', { encoding: 'utf-8' }))
|
||||
.split('\n').find(x => x.startsWith(process.env.LOGNAME + ':'))
|
||||
if (!line) {
|
||||
console.warn('Could not detect user shell')
|
||||
command = '/bin/sh'
|
||||
} else {
|
||||
command = line.split(':')[6]
|
||||
}
|
||||
}
|
||||
if (this.hostApp.platform === Platform.macOS) {
|
||||
let shellEntry = (await exec(`dscl . -read /Users/${process.env.LOGNAME} UserShell`))[0].toString()
|
||||
command = shellEntry.split(':')[1].trim()
|
||||
}
|
||||
command = await this.shells.getDefaultShell()
|
||||
}
|
||||
let sessionOptions = await this.sessions.prepareNewSession({ command, args, cwd })
|
||||
if (this.hostApp.platform === Platform.Windows) {
|
||||
env.TERM = 'cygwin'
|
||||
}
|
||||
let sessionOptions = await this.sessions.prepareNewSession({
|
||||
command,
|
||||
args,
|
||||
cwd,
|
||||
env,
|
||||
})
|
||||
this.app.openNewTab(
|
||||
TerminalTabComponent,
|
||||
{ sessionOptions }
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import * as fs from 'fs-promise'
|
||||
import * as fs from 'mz/fs'
|
||||
import * as path from 'path'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { TerminalColorSchemeProvider, ITerminalColorScheme } from './api'
|
||||
@@ -6,7 +6,7 @@ import { TerminalColorSchemeProvider, ITerminalColorScheme } from './api'
|
||||
@Injectable()
|
||||
export class HyperColorSchemes extends TerminalColorSchemeProvider {
|
||||
async getSchemes (): Promise<ITerminalColorScheme[]> {
|
||||
let pluginsPath = path.join(process.env.HOME || (process.env.HOMEDRIVE + process.env.HOMEPATH), '.hyper_plugins', 'node_modules')
|
||||
let pluginsPath = path.join(process.env.HOME, '.hyper_plugins', 'node_modules')
|
||||
if (!(await fs.exists(pluginsPath))) return []
|
||||
let plugins = await fs.readdir(pluginsPath)
|
||||
|
||||
|
@@ -68,11 +68,10 @@ export class TerminalSettingsTabComponent {
|
||||
|
||||
// Detect Cygwin
|
||||
let cygwinPath = await new Promise<string>(resolve => {
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup' })
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup', arch: 'x64' })
|
||||
reg.get('rootdir', (err, item) => {
|
||||
if (err) {
|
||||
resolve(null)
|
||||
return
|
||||
return resolve(null)
|
||||
}
|
||||
resolve(item.value)
|
||||
})
|
||||
@@ -81,6 +80,20 @@ export class TerminalSettingsTabComponent {
|
||||
this.shells.push({ name: 'Cygwin', command: path.join(cygwinPath, 'bin', 'bash.exe') })
|
||||
}
|
||||
|
||||
// Detect 32-bit Cygwin
|
||||
let cygwin32Path = await new Promise<string>(resolve => {
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup', arch: 'x86' })
|
||||
reg.get('rootdir', (err, item) => {
|
||||
if (err) {
|
||||
return resolve(null)
|
||||
}
|
||||
resolve(item.value)
|
||||
})
|
||||
})
|
||||
if (cygwin32Path) {
|
||||
this.shells.push({ name: 'Cygwin (32 bit)', command: path.join(cygwin32Path, 'bin', 'bash.exe') })
|
||||
}
|
||||
|
||||
// Detect Git-Bash
|
||||
let gitBashPath = await new Promise<string>(resolve => {
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\GitForWindows' })
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { BehaviorSubject, ReplaySubject, Subject, Subscription } from 'rxjs'
|
||||
const dataurl = require('dataurl')
|
||||
import { BehaviorSubject, Subject, Subscription } from 'rxjs'
|
||||
import 'rxjs/add/operator/bufferTime'
|
||||
import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core'
|
||||
import { AppService, ConfigService, BaseTabComponent, ThemesService, HostAppService, Platform } from 'terminus-core'
|
||||
import { AppService, ConfigService, BaseTabComponent, ThemesService, HostAppService, HotkeysService, Platform } from 'terminus-core'
|
||||
|
||||
import { Session, SessionsService } from '../services/sessions.service'
|
||||
|
||||
@@ -16,13 +17,15 @@ import { hterm, preferenceManager } from '../hterm'
|
||||
export class TerminalTabComponent extends BaseTabComponent {
|
||||
session: Session
|
||||
@Input() sessionOptions: SessionOptions
|
||||
@Input() zoom = 0
|
||||
@ViewChild('content') content
|
||||
@HostBinding('style.background-color') backgroundColor: string
|
||||
hterm: any
|
||||
configSubscription: Subscription
|
||||
sessionCloseSubscription: Subscription
|
||||
hotkeysSubscription: Subscription
|
||||
bell$ = new Subject()
|
||||
size$ = new ReplaySubject<ResizeEvent>(1)
|
||||
size: ResizeEvent
|
||||
resize$ = new Subject<ResizeEvent>()
|
||||
input$ = new Subject<string>()
|
||||
output$ = new Subject<string>()
|
||||
@@ -37,6 +40,7 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
private app: AppService,
|
||||
private themes: ThemesService,
|
||||
private hostApp: HostAppService,
|
||||
private hotkeys: HotkeysService,
|
||||
private sessions: SessionsService,
|
||||
public config: ConfigService,
|
||||
@Optional() @Inject(TerminalDecorator) private decorators: TerminalDecorator[],
|
||||
@@ -64,6 +68,26 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
})
|
||||
this.session.releaseInitialDataBuffer()
|
||||
})
|
||||
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
|
||||
if (!this.hasFocus) {
|
||||
return
|
||||
}
|
||||
if (hotkey === 'copy') {
|
||||
this.hterm.copySelectionToClipboard()
|
||||
}
|
||||
if (hotkey === 'clear') {
|
||||
this.clear()
|
||||
}
|
||||
if (hotkey === 'zoom-in') {
|
||||
this.zoomIn()
|
||||
}
|
||||
if (hotkey === 'zoom-out') {
|
||||
this.zoomOut()
|
||||
}
|
||||
if (hotkey === 'reset-zoom') {
|
||||
this.resetZoom()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getRecoveryToken (): any {
|
||||
@@ -150,10 +174,18 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
const _onMouse = hterm.onMouse_.bind(hterm)
|
||||
hterm.onMouse_ = (event) => {
|
||||
this.mouseEvent$.next(event)
|
||||
if ((event.ctrlKey || event.metaKey) && event.type === 'mousewheel') {
|
||||
event.preventDefault()
|
||||
let delta = Math.round(event.wheelDeltaY / 50)
|
||||
this.sendInput(((delta > 0) ? '\u001bOA' : '\u001bOB').repeat(Math.abs(delta)))
|
||||
if (event.type === 'mousewheel') {
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (event.wheelDeltaY < 0) {
|
||||
this.zoomIn()
|
||||
} else {
|
||||
this.zoomOut()
|
||||
}
|
||||
} else if (event.altKey) {
|
||||
event.preventDefault()
|
||||
let delta = Math.round(event.wheelDeltaY / 50)
|
||||
this.sendInput(((delta > 0) ? '\u001bOA' : '\u001bOB').repeat(Math.abs(delta)))
|
||||
}
|
||||
}
|
||||
_onMouse(event)
|
||||
}
|
||||
@@ -188,11 +220,11 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
io.onTerminalResize = (columns, rows) => {
|
||||
// console.log(`Resizing to ${columns}x${rows}`)
|
||||
this.zone.run(() => {
|
||||
this.size$.next({ width: columns, height: rows })
|
||||
this.resize$.next({ width: columns, height: rows })
|
||||
this.size = { width: columns, height: rows }
|
||||
if (this.session) {
|
||||
this.session.resize(columns, rows)
|
||||
}
|
||||
this.resize$.next(this.size)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -205,10 +237,15 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
this.io.writeUTF8(data)
|
||||
}
|
||||
|
||||
clear () {
|
||||
this.hterm.wipeContents()
|
||||
this.hterm.onVTKeystroke('\f')
|
||||
}
|
||||
|
||||
async configure (): Promise<void> {
|
||||
let config = this.config.store
|
||||
preferenceManager.set('font-family', config.terminal.font)
|
||||
preferenceManager.set('font-size', config.terminal.fontSize)
|
||||
this.setFontSize()
|
||||
preferenceManager.set('enable-bold', true)
|
||||
preferenceManager.set('audible-bell-sound', '')
|
||||
preferenceManager.set('desktop-notification-bell', config.terminal.bell === 'notification')
|
||||
@@ -239,16 +276,55 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
preferenceManager.set('cursor-color', config.terminal.colorScheme.cursor)
|
||||
}
|
||||
|
||||
let css = require('../hterm.userCSS.scss')
|
||||
if (!config.terminal.ligatures) {
|
||||
css += `
|
||||
* {
|
||||
font-feature-settings: "liga" 0;
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
`
|
||||
} else {
|
||||
css += `
|
||||
* {
|
||||
font-feature-settings: "liga" 1;
|
||||
font-variant-ligatures: initial;
|
||||
}
|
||||
`
|
||||
}
|
||||
preferenceManager.set('user-css', dataurl.convert({
|
||||
data: css,
|
||||
mimetype: 'text/css',
|
||||
charset: 'utf8',
|
||||
}))
|
||||
|
||||
this.hterm.setBracketedPaste(config.terminal.bracketedPaste)
|
||||
}
|
||||
|
||||
zoomIn () {
|
||||
this.zoom++
|
||||
this.setFontSize()
|
||||
}
|
||||
|
||||
zoomOut () {
|
||||
this.zoom--
|
||||
this.setFontSize()
|
||||
}
|
||||
|
||||
resetZoom () {
|
||||
this.zoom = 0
|
||||
this.setFontSize()
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
this.decorators.forEach((decorator) => {
|
||||
this.decorators.forEach(decorator => {
|
||||
decorator.detach(this)
|
||||
})
|
||||
this.configSubscription.unsubscribe()
|
||||
this.sessionCloseSubscription.unsubscribe()
|
||||
this.size$.complete()
|
||||
this.hotkeysSubscription.unsubscribe()
|
||||
if (this.sessionCloseSubscription) {
|
||||
this.sessionCloseSubscription.unsubscribe()
|
||||
}
|
||||
this.resize$.complete()
|
||||
this.input$.complete()
|
||||
this.output$.complete()
|
||||
@@ -260,6 +336,12 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
|
||||
async destroy () {
|
||||
super.destroy()
|
||||
await this.session.destroy()
|
||||
if (this.session && this.session.open) {
|
||||
await this.session.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
private setFontSize () {
|
||||
preferenceManager.set('font-size', this.config.store.terminal.fontSize * Math.pow(1.1, this.zoom))
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
bell: 'off',
|
||||
bracketedPaste: false,
|
||||
background: 'theme',
|
||||
ligatures: false,
|
||||
colorScheme: {
|
||||
__nonStructural: true,
|
||||
name: 'Material',
|
||||
@@ -43,6 +44,23 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
shell: '~default-shell~',
|
||||
},
|
||||
hotkeys: {
|
||||
'copy': [
|
||||
'⌘-C',
|
||||
],
|
||||
'clear': [
|
||||
'⌘-K',
|
||||
],
|
||||
'zoom-in': [
|
||||
'⌘-=',
|
||||
'⌘-Shift-+',
|
||||
],
|
||||
'zoom-out': [
|
||||
'⌘--',
|
||||
'⌘-Shift-_',
|
||||
],
|
||||
'reset-zoom': [
|
||||
'⌘-0',
|
||||
],
|
||||
'new-tab': [
|
||||
['Ctrl-A', 'C'],
|
||||
['Ctrl-A', 'Ctrl-C'],
|
||||
@@ -57,6 +75,23 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
shell: '~clink~',
|
||||
},
|
||||
hotkeys: {
|
||||
'copy': [
|
||||
'Ctrl-Shift-C',
|
||||
],
|
||||
'clear': [
|
||||
'Ctrl-L',
|
||||
],
|
||||
'zoom-in': [
|
||||
'Ctrl-=',
|
||||
'Ctrl-Shift-+',
|
||||
],
|
||||
'zoom-out': [
|
||||
'Ctrl--',
|
||||
'Ctrl-Shift-_',
|
||||
],
|
||||
'reset-zoom': [
|
||||
'Ctrl-0',
|
||||
],
|
||||
'new-tab': [
|
||||
['Ctrl-A', 'C'],
|
||||
['Ctrl-A', 'Ctrl-C'],
|
||||
@@ -70,6 +105,23 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
shell: '~default-shell~',
|
||||
},
|
||||
hotkeys: {
|
||||
'copy': [
|
||||
'Ctrl-Shift-C',
|
||||
],
|
||||
'clear': [
|
||||
'Ctrl-L',
|
||||
],
|
||||
'zoom-in': [
|
||||
'Ctrl-=',
|
||||
'Ctrl-Shift-+',
|
||||
],
|
||||
'zoom-out': [
|
||||
'Ctrl--',
|
||||
'Ctrl-Shift-_',
|
||||
],
|
||||
'reset-zoom': [
|
||||
'Ctrl-0',
|
||||
],
|
||||
'new-tab': [
|
||||
['Ctrl-A', 'C'],
|
||||
['Ctrl-A', 'Ctrl-C'],
|
||||
|
32
terminus-terminal/src/hotkeys.ts
Normal file
32
terminus-terminal/src/hotkeys.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { IHotkeyDescription, HotkeyProvider } from 'terminus-core'
|
||||
|
||||
@Injectable()
|
||||
export class TerminalHotkeyProvider extends HotkeyProvider {
|
||||
hotkeys: IHotkeyDescription[] = [
|
||||
{
|
||||
id: 'copy',
|
||||
name: 'Copy to clipboard',
|
||||
},
|
||||
{
|
||||
id: 'clear',
|
||||
name: 'Clear terminal',
|
||||
},
|
||||
{
|
||||
id: 'zoom-in',
|
||||
name: 'Zoom in',
|
||||
},
|
||||
{
|
||||
id: 'zoom-out',
|
||||
name: 'Zoom out',
|
||||
},
|
||||
{
|
||||
id: 'reset-zoom',
|
||||
name: 'Reset zoom',
|
||||
},
|
||||
{
|
||||
id: 'new-tab',
|
||||
name: 'New tab',
|
||||
},
|
||||
]
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
const dataurl = require('dataurl')
|
||||
export const hterm = require('hterm-umdjs')
|
||||
hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory()
|
||||
export const preferenceManager = new hterm.hterm.PreferenceManager('default')
|
||||
@@ -16,14 +15,18 @@ hterm.hterm.VT.ESC['k'] = function (parseState) {
|
||||
parseState.func = parseOSC
|
||||
}
|
||||
|
||||
preferenceManager.set('user-css', dataurl.convert({
|
||||
data: require('./hterm.userCSS.scss'),
|
||||
mimetype: 'text/css',
|
||||
charset: 'utf8',
|
||||
}))
|
||||
preferenceManager.set('background-color', '#1D272D')
|
||||
preferenceManager.set('color-palette-overrides', {
|
||||
0: '#1D272D',
|
||||
})
|
||||
|
||||
hterm.hterm.Terminal.prototype.showOverlay = () => null
|
||||
|
||||
const oldCharWidthDisregardAmbiguous = hterm.lib.wc.charWidthDisregardAmbiguous
|
||||
hterm.lib.wc.charWidthDisregardAmbiguous = codepoint => {
|
||||
if ((codepoint >= 0x1f300 && codepoint <= 0x1f64f) ||
|
||||
(codepoint >= 0x1f680 && codepoint <= 0x1f6ff)) {
|
||||
return 2
|
||||
}
|
||||
return oldCharWidthDisregardAmbiguous(codepoint)
|
||||
}
|
||||
|
@@ -6,11 +6,6 @@ a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
* {
|
||||
font-feature-settings: "liga" 0; // disable ligatures (they break monospacing)
|
||||
}
|
||||
|
||||
x-screen {
|
||||
transition: 0.125s ease background;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ import { BrowserModule } from '@angular/platform-browser'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
import { HostAppService, Platform, ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService } from 'terminus-core'
|
||||
import { HostAppService, Platform, ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider } from 'terminus-core'
|
||||
import { SettingsTabProvider } from 'terminus-settings'
|
||||
|
||||
import { TerminalTabComponent } from './components/terminalTab.component'
|
||||
@@ -11,6 +11,7 @@ import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.c
|
||||
import { ColorPickerComponent } from './components/colorPicker.component'
|
||||
|
||||
import { SessionsService } from './services/sessions.service'
|
||||
import { ShellsService } from './services/shells.service'
|
||||
|
||||
import { ScreenPersistenceProvider } from './persistenceProviders'
|
||||
import { ButtonProvider } from './buttonProvider'
|
||||
@@ -19,6 +20,7 @@ import { SessionPersistenceProvider, TerminalColorSchemeProvider, TerminalDecora
|
||||
import { TerminalSettingsTabProvider } from './settings'
|
||||
import { PathDropDecorator } from './pathDrop'
|
||||
import { TerminalConfigProvider } from './config'
|
||||
import { TerminalHotkeyProvider } from './hotkeys'
|
||||
import { HyperColorSchemes } from './colorSchemes'
|
||||
import { hterm } from './hterm'
|
||||
|
||||
@@ -30,6 +32,7 @@ import { hterm } from './hterm'
|
||||
],
|
||||
providers: [
|
||||
SessionsService,
|
||||
ShellsService,
|
||||
ScreenPersistenceProvider,
|
||||
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
|
||||
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true },
|
||||
@@ -46,6 +49,7 @@ import { hterm } from './hterm'
|
||||
},
|
||||
{ provide: SettingsTabProvider, useClass: TerminalSettingsTabProvider, multi: true },
|
||||
{ provide: ConfigProvider, useClass: TerminalConfigProvider, multi: true },
|
||||
{ provide: HotkeyProvider, useClass: TerminalHotkeyProvider, multi: true },
|
||||
{ provide: TerminalColorSchemeProvider, useClass: HyperColorSchemes, multi: true },
|
||||
{ provide: TerminalDecorator, useClass: PathDropDecorator, multi: true },
|
||||
],
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import * as fs from 'fs-promise'
|
||||
import * as fs from 'mz/fs'
|
||||
import { exec, spawn } from 'mz/child_process'
|
||||
import { exec as execCallback } from 'child_process'
|
||||
|
||||
@@ -88,7 +88,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
|
||||
await fs.writeFile(configPath, `
|
||||
escape ^^^
|
||||
vbell on
|
||||
deflogin off
|
||||
deflogin on
|
||||
term xterm-color
|
||||
bindkey "^[OH" beginning-of-line
|
||||
bindkey "^[OF" end-of-line
|
||||
@@ -98,6 +98,8 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
|
||||
defhstatus "^Et"
|
||||
hardstatus off
|
||||
altscreen on
|
||||
defutf8 on
|
||||
defencoding utf8
|
||||
`, 'utf-8')
|
||||
let recoveryId = `term-tab-${Date.now()}`
|
||||
let args = ['-d', '-m', '-c', configPath, '-U', '-S', recoveryId, '-T', 'xterm-256color', '--', '-' + options.command].concat(options.args || [])
|
||||
@@ -110,6 +112,10 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
|
||||
}
|
||||
|
||||
async terminateSession (recoveryId: string): Promise<void> {
|
||||
await exec(`screen -S ${recoveryId} -X quit`)
|
||||
try {
|
||||
await exec(`screen -S ${recoveryId} -X quit`)
|
||||
} catch (_) {
|
||||
// screen has already quit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import * as nodePTY from 'node-pty'
|
||||
import * as fs from 'fs-promise'
|
||||
import * as fs from 'mz/fs'
|
||||
import { Subject } from 'rxjs'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { Logger, LogService } from 'terminus-core'
|
||||
@@ -25,8 +25,20 @@ export class Session {
|
||||
|
||||
let env = {
|
||||
...process.env,
|
||||
...options.env,
|
||||
TERM: 'xterm-256color',
|
||||
...options.env,
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin' && !process.env.LC_ALL) {
|
||||
let locale = process.env.LC_CTYPE || 'en_US.UTF-8'
|
||||
Object.assign(env, {
|
||||
LANG: locale,
|
||||
LC_ALL: locale,
|
||||
LC_MESSAGES: locale,
|
||||
LC_NUMERIC: locale,
|
||||
LC_COLLATE: locale,
|
||||
LC_MONETARY: locale,
|
||||
})
|
||||
}
|
||||
this.pty = nodePTY.spawn(options.command, options.args || [], {
|
||||
name: 'xterm-256color',
|
||||
@@ -54,6 +66,12 @@ export class Session {
|
||||
}
|
||||
})
|
||||
|
||||
this.pty.on('exit', () => {
|
||||
if (this.open) {
|
||||
this.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
this.pty.on('close', () => {
|
||||
if (this.open) {
|
||||
this.destroy()
|
||||
@@ -68,11 +86,15 @@ export class Session {
|
||||
}
|
||||
|
||||
resize (columns, rows) {
|
||||
this.pty.resize(columns, rows)
|
||||
if (this.pty.writable) {
|
||||
this.pty.resize(columns, rows)
|
||||
}
|
||||
}
|
||||
|
||||
write (data) {
|
||||
this.pty.write(data)
|
||||
if (this.pty.writable) {
|
||||
this.pty.write(Buffer.from(data, 'utf-8'))
|
||||
}
|
||||
}
|
||||
|
||||
kill (signal?: string) {
|
||||
@@ -114,7 +136,11 @@ export class Session {
|
||||
async getWorkingDirectory (): Promise<string> {
|
||||
if (process.platform === 'darwin') {
|
||||
let lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n')
|
||||
return lines[2].substring(1)
|
||||
if (lines[1] === 'fcwd') {
|
||||
return lines[2].substring(1)
|
||||
} else {
|
||||
return lines[1].substring(1)
|
||||
}
|
||||
}
|
||||
if (process.platform === 'linux') {
|
||||
return await fs.readlink(`/proc/${this.truePID}/cwd`)
|
||||
|
58
terminus-terminal/src/services/shells.service.ts
Normal file
58
terminus-terminal/src/services/shells.service.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import * as path from 'path'
|
||||
import { exec } from 'mz/child_process'
|
||||
import * as fs from 'mz/fs'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ElectronService, HostAppService, Platform, Logger, LogService } from 'terminus-core'
|
||||
|
||||
@Injectable()
|
||||
export class ShellsService {
|
||||
private logger: Logger
|
||||
|
||||
constructor (
|
||||
log: LogService,
|
||||
private electron: ElectronService,
|
||||
private hostApp: HostAppService,
|
||||
) {
|
||||
this.logger = log.create('shells')
|
||||
}
|
||||
|
||||
getClinkOptions (): { command, args } {
|
||||
return {
|
||||
command: 'cmd.exe',
|
||||
args: [
|
||||
'/k',
|
||||
path.join(
|
||||
path.dirname(this.electron.app.getPath('exe')),
|
||||
'resources',
|
||||
'clink',
|
||||
`clink_${process.arch}.exe`,
|
||||
),
|
||||
'inject',
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
async getDefaultShell (): Promise<string> {
|
||||
if (this.hostApp.platform === Platform.macOS) {
|
||||
return this.getDefaultMacOSShell()
|
||||
} else {
|
||||
return this.getDefaultLinuxShell()
|
||||
}
|
||||
}
|
||||
|
||||
async getDefaultMacOSShell (): Promise<string> {
|
||||
let shellEntry = (await exec(`dscl . -read /Users/${process.env.LOGNAME} UserShell`))[0].toString()
|
||||
return shellEntry.split(' ')[1].trim()
|
||||
}
|
||||
|
||||
async getDefaultLinuxShell (): Promise<string> {
|
||||
let line = (await fs.readFile('/etc/passwd', { encoding: 'utf-8' }))
|
||||
.split('\n').find(x => x.startsWith(process.env.LOGNAME + ':'))
|
||||
if (!line) {
|
||||
this.logger.warn('Could not detect user shell')
|
||||
return '/bin/sh'
|
||||
} else {
|
||||
return line.split(':')[6]
|
||||
}
|
||||
}
|
||||
}
|
@@ -38,10 +38,10 @@ module.exports = {
|
||||
},
|
||||
externals: [
|
||||
'fs',
|
||||
'fs-promise',
|
||||
'font-manager',
|
||||
'path',
|
||||
'node-pty',
|
||||
'mz/fs',
|
||||
'mz/child_process',
|
||||
'winreg',
|
||||
/^rxjs/,
|
||||
|
Reference in New Issue
Block a user