diff --git a/terminus-core/@angular/animations.ts b/terminus-core/@angular/animations.ts new file mode 100644 index 00000000..7d60b27e --- /dev/null +++ b/terminus-core/@angular/animations.ts @@ -0,0 +1 @@ +export * from '@angular/animations' diff --git a/terminus-core/@angular/common.ts b/terminus-core/@angular/common.ts new file mode 100644 index 00000000..a632305e --- /dev/null +++ b/terminus-core/@angular/common.ts @@ -0,0 +1 @@ +export * from '@angular/common' diff --git a/terminus-core/@angular/compiler.ts b/terminus-core/@angular/compiler.ts new file mode 100644 index 00000000..eeea4358 --- /dev/null +++ b/terminus-core/@angular/compiler.ts @@ -0,0 +1 @@ +export * from '@angular/compiler' diff --git a/terminus-core/@angular/core.ts b/terminus-core/@angular/core.ts new file mode 100644 index 00000000..c84ba0c1 --- /dev/null +++ b/terminus-core/@angular/core.ts @@ -0,0 +1 @@ +export * from '@angular/core' diff --git a/terminus-core/@angular/forms.ts b/terminus-core/@angular/forms.ts new file mode 100644 index 00000000..e360776f --- /dev/null +++ b/terminus-core/@angular/forms.ts @@ -0,0 +1 @@ +export * from '@angular/forms' diff --git a/terminus-core/@angular/platform-browser-dynamic.ts b/terminus-core/@angular/platform-browser-dynamic.ts new file mode 100644 index 00000000..9ff6a3ea --- /dev/null +++ b/terminus-core/@angular/platform-browser-dynamic.ts @@ -0,0 +1 @@ +export * from '@angular/platform-browser-dynamic' diff --git a/terminus-core/@angular/platform-browser.ts b/terminus-core/@angular/platform-browser.ts new file mode 100644 index 00000000..97121280 --- /dev/null +++ b/terminus-core/@angular/platform-browser.ts @@ -0,0 +1 @@ +export * from '@angular/platform-browser' diff --git a/terminus-core/@ng-bootstrap/ng-bootstrap.ts b/terminus-core/@ng-bootstrap/ng-bootstrap.ts new file mode 100644 index 00000000..c7937101 --- /dev/null +++ b/terminus-core/@ng-bootstrap/ng-bootstrap.ts @@ -0,0 +1 @@ +export * from '@ng-bootstrap/ng-bootstrap' diff --git a/terminus-core/rxjs.ts b/terminus-core/rxjs.ts new file mode 100644 index 00000000..c276befc --- /dev/null +++ b/terminus-core/rxjs.ts @@ -0,0 +1 @@ +export * from 'rxjs' diff --git a/terminus-core/zone.js.ts b/terminus-core/zone.js.ts new file mode 100644 index 00000000..672bc266 --- /dev/null +++ b/terminus-core/zone.js.ts @@ -0,0 +1 @@ +export * from 'zone.js' diff --git a/terminus-terminal/src/components/colorPicker.ts b/terminus-terminal/src/components/colorPicker.ts index 4beb5f47..f1e82fd8 100644 --- a/terminus-terminal/src/components/colorPicker.ts +++ b/terminus-terminal/src/components/colorPicker.ts @@ -13,17 +13,22 @@ export class ColorPickerComponent { @Output() modelChange = new EventEmitter() @ViewChild('popover') popover: NgbPopover @ViewChild('input') input + isOpen: boolean open () { setImmediate(() => { this.popover.open() setImmediate(() => { this.input.nativeElement.focus() + this.isOpen = true }) }) } @HostListener('document:click', ['$event']) onOutsideClick ($event) { + if (!this.isOpen) { + return + } let windowRef = (this.popover)._windowRef if (!windowRef) { return @@ -31,6 +36,7 @@ export class ColorPickerComponent { if ($event.target !== windowRef.location.nativeElement && !windowRef.location.nativeElement.contains($event.target)) { this.popover.close() + this.isOpen = false } } diff --git a/terminus-terminal/src/components/settings.pug b/terminus-terminal/src/components/settings.pug deleted file mode 100644 index c74bf8aa..00000000 --- a/terminus-terminal/src/components/settings.pug +++ /dev/null @@ -1,151 +0,0 @@ -.row - .col-lg-6 - .form-group - label Preview - .appearance-preview( - [style.font-family]='config.full().terminal.font', - [style.font-size]='config.full().terminal.fontSize + "px"', - [style.background-color]='(config.full().terminal.background == "theme") ? null : config.full().terminal.colorScheme.background', - [style.color]='config.full().terminal.colorScheme.foreground', - ) - div - span john@doe-pc - span([style.color]='config.full().terminal.colorScheme.colors[1]') $ - span webpack - div - span Asset Size - div - span([style.color]='config.full().terminal.colorScheme.colors[2]') main.js - span 234 kB - span([style.color]='config.full().terminal.colorScheme.colors[2]') [emitted] - div - span([style.color]='config.full().terminal.colorScheme.colors[3]') big.js - span([style.color]='config.full().terminal.colorScheme.colors[3]') 1.2 MB - span([style.color]='config.full().terminal.colorScheme.colors[2]') [emitted] - span([style.color]='config.full().terminal.colorScheme.colors[3]') [big] - div - span - div - span john@doe-pc - span([style.color]='config.full().terminal.colorScheme.colors[1]') $ - span ls -l - div - span drwxr-xr-x 1 root root - span([style.color]='config.full().terminal.colorScheme.colors[4]') directory - div - span -rw-r--r-- 1 root root file - div - span -rwxr-xr-x 1 root root - span([style.color]='config.full().terminal.colorScheme.colors[2]') executable - div - span -rwxr-xr-x 1 root root - span([style.color]='config.full().terminal.colorScheme.colors[6]') sym - span -> - span([style.color]='config.full().terminal.colorScheme.colors[1]') link - div - span - div - span john@doe-pc - span([style.color]='config.full().terminal.colorScheme.colors[1]') $ - span rm -rf / - span([style.background-color]='config.full().terminal.colorScheme.cursor')   - - - .col-lg-6 - .form-group - label Font - .row - .col-8 - input.form-control( - type='text', - [ngbTypeahead]='fontAutocomplete', - '[(ngModel)]'='config.store.terminal.font', - (ngModelChange)='config.save()', - ) - .col-4 - input.form-control( - type='number', - '[(ngModel)]'='config.store.terminal.fontSize', - (ngModelChange)='config.save()', - ) - small.form-text.text-muted Font to be used in the terminal - - .form-group - label Color scheme - select.form-control( - [compareWith]='equalComparator', - '[(ngModel)]'='config.store.terminal.colorScheme', - (ngModelChange)='config.save()', - ) - option(*ngFor='let scheme of colorSchemes', [ngValue]='scheme') {{scheme.name}} - - div(*ngIf='config.store.terminal.colorScheme.colors') - color-picker( - '[(model)]'='config.store.terminal.colorScheme.foreground', - (modelChange)='config.save()', - title='FG', - ) - color-picker( - '[(model)]'='config.store.terminal.colorScheme.background', - (modelChange)='config.save()', - title='BG', - ) - color-picker( - '[(model)]'='config.store.terminal.colorScheme.cursor', - (modelChange)='config.save()', - title='CU', - ) - color-picker( - *ngFor='let _ of config.store.terminal.colorScheme.colors; let idx = index', - '[(model)]'='config.store.terminal.colorScheme.colors[idx]', - (modelChange)='config.save()', - [title]='idx', - ) - - .form-group - label Terminal background - br - div( - '[(ngModel)]'='config.store.terminal.background', - (ngModelChange)='config.save()', - ngbRadioGroup - ) - label.btn.btn-secondary - input( - type='radio', - [value]='"theme"' - ) - | From the app theme - label.btn.btn-secondary - input( - type='radio', - [value]='"colorScheme"' - ) - | From the terminal colors - - .form-group - label Terminal bell - br - div( - '[(ngModel)]'='config.store.terminal.bell', - (ngModelChange)='config.save()', - ngbRadioGroup - ) - label.btn.btn-secondary - input( - type='radio', - [value]='"off"' - ) - | Off - label.btn.btn-secondary - input( - type='radio', - [value]='"visual"' - ) - | Visual - label.btn.btn-secondary - input( - type='radio', - [value]='"audible"' - ) - | Audible diff --git a/terminus-terminal/src/components/terminalSettingsTab.pug b/terminus-terminal/src/components/terminalSettingsTab.pug new file mode 100644 index 00000000..8474c974 --- /dev/null +++ b/terminus-terminal/src/components/terminalSettingsTab.pug @@ -0,0 +1,223 @@ +.row + .col-md-6 + .form-group + label Preview + .appearance-preview( + [style.font-family]='config.full().terminal.font', + [style.font-size]='config.full().terminal.fontSize + "px"', + [style.background-color]='(config.full().terminal.background == "theme") ? null : config.full().terminal.colorScheme.background', + [style.color]='config.full().terminal.colorScheme.foreground', + ) + div + span([style.background-color]='config.full().terminal.colorScheme.colors[0]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[1]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[2]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[3]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[4]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[5]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[6]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[7]')   + span    + span([style.color]='config.full().terminal.colorScheme.colors[0]') B + span   + span([style.color]='config.full().terminal.colorScheme.colors[1]') R + span   + span([style.color]='config.full().terminal.colorScheme.colors[2]') G + span   + span([style.color]='config.full().terminal.colorScheme.colors[3]') Y + span   + span([style.color]='config.full().terminal.colorScheme.colors[4]') B + span   + span([style.color]='config.full().terminal.colorScheme.colors[5]') M + span   + span([style.color]='config.full().terminal.colorScheme.colors[6]') T + span   + span([style.color]='config.full().terminal.colorScheme.colors[7]') W + div + span([style.background-color]='config.full().terminal.colorScheme.colors[8]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[9]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[10]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[11]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[12]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[13]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[14]')   + span([style.background-color]='config.full().terminal.colorScheme.colors[15]')   + span    + span([style.color]='config.full().terminal.colorScheme.colors[8]') B + span   + span([style.color]='config.full().terminal.colorScheme.colors[9]') R + span   + span([style.color]='config.full().terminal.colorScheme.colors[10]') G + span   + span([style.color]='config.full().terminal.colorScheme.colors[11]') Y + span   + span([style.color]='config.full().terminal.colorScheme.colors[12]') B + span   + span([style.color]='config.full().terminal.colorScheme.colors[13]') M + span   + span([style.color]='config.full().terminal.colorScheme.colors[14]') T + span   + span([style.color]='config.full().terminal.colorScheme.colors[15]') W + div + span + div + span john@doe-pc + span([style.color]='config.full().terminal.colorScheme.colors[1]') $ + span webpack + div + span Asset Size + div + span([style.color]='config.full().terminal.colorScheme.colors[2]') main.js + span 234 kB + span([style.color]='config.full().terminal.colorScheme.colors[2]') [emitted] + div + span([style.color]='config.full().terminal.colorScheme.colors[3]') big.js + span([style.color]='config.full().terminal.colorScheme.colors[3]') 1.2 MB + span([style.color]='config.full().terminal.colorScheme.colors[2]') [emitted] + span([style.color]='config.full().terminal.colorScheme.colors[3]') [big] + div + span + div + span john@doe-pc + span([style.color]='config.full().terminal.colorScheme.colors[1]') $ + span ls -l + div + span drwxr-xr-x 1 root + span([style.color]='config.full().terminal.colorScheme.colors[4]') directory + div + span -rw-r--r-- 1 root file + div + span -rwxr-xr-x 1 root + span([style.color]='config.full().terminal.colorScheme.colors[2]') executable + div + span -rwxr-xr-x 1 root + span([style.color]='config.full().terminal.colorScheme.colors[6]') sym + span -> + span([style.color]='config.full().terminal.colorScheme.colors[1]') link + div + span + div + span john@doe-pc + span([style.color]='config.full().terminal.colorScheme.colors[1]') $ + span rm -rf / + span([style.background-color]='config.full().terminal.colorScheme.cursor')   + + + .col-md-6 + .form-group + label Font + .row + .col-8 + input.form-control( + type='text', + [ngbTypeahead]='fontAutocomplete', + '[(ngModel)]'='config.store.terminal.font', + (ngModelChange)='config.save()', + ) + .col-4 + input.form-control( + type='number', + '[(ngModel)]'='config.store.terminal.fontSize', + (ngModelChange)='config.save()', + ) + small.form-text.text-muted Font to be used in the terminal + + .form-group(*ngIf='!editingColorScheme') + label Color scheme + .input-group + select.form-control( + [compareWith]='equalComparator', + '[(ngModel)]'='config.store.terminal.colorScheme', + (ngModelChange)='config.save()', + ) + option(*ngFor='let scheme of config.full().terminal.customColorSchemes', [ngValue]='scheme') Custom: {{scheme.name}} + option(*ngFor='let scheme of colorSchemes', [ngValue]='scheme') {{scheme.name}} + .input-group-btn + button.btn.btn-secondary((click)='editScheme(config.store.terminal.colorScheme)') Edit + .input-group-btn + button.btn.btn-outline-danger( + (click)='deleteScheme(config.store.terminal.colorScheme)', + *ngIf='isCustomScheme(config.store.terminal.colorScheme)' + ) + i.fa.fa-trash-o + + .form-group(*ngIf='editingColorScheme') + label Editing + .input-group + input.form-control(type='text', '[(ngModel)]'='editingColorScheme.name') + .input-group-btn + button.btn.btn-secondary((click)='saveScheme()') Save + .input-group-btn + button.btn.btn-secondary((click)='cancelEditing()') Cancel + + + .form-group(*ngIf='editingColorScheme') + color-picker( + '[(model)]'='editingColorScheme.foreground', + (modelChange)='config.save(); schemeChanged = true', + title='FG', + ) + color-picker( + '[(model)]'='editingColorScheme.background', + (modelChange)='config.save(); schemeChanged = true', + title='BG', + ) + color-picker( + '[(model)]'='editingColorScheme.cursor', + (modelChange)='config.save(); schemeChanged = true', + title='CU', + ) + color-picker( + *ngFor='let _ of editingColorScheme.colors; let idx = index; trackBy: colorsTrackBy', + '[(model)]'='editingColorScheme.colors[idx]', + (modelChange)='config.save(); schemeChanged = true', + [title]='idx', + ) + + .form-group + label Terminal background + br + div( + '[(ngModel)]'='config.store.terminal.background', + (ngModelChange)='config.save()', + ngbRadioGroup + ) + label.btn.btn-secondary + input( + type='radio', + [value]='"theme"' + ) + | From the app theme + label.btn.btn-secondary + input( + type='radio', + [value]='"colorScheme"' + ) + | From the terminal colors + + .form-group + label Terminal bell + br + div( + '[(ngModel)]'='config.store.terminal.bell', + (ngModelChange)='config.save()', + ngbRadioGroup + ) + label.btn.btn-secondary + input( + type='radio', + [value]='"off"' + ) + | Off + label.btn.btn-secondary + input( + type='radio', + [value]='"visual"' + ) + | Visual + label.btn.btn-secondary + input( + type='radio', + [value]='"audible"' + ) + | Audible diff --git a/terminus-terminal/src/components/settings.scss b/terminus-terminal/src/components/terminalSettingsTab.scss similarity index 83% rename from terminus-terminal/src/components/settings.scss rename to terminus-terminal/src/components/terminalSettingsTab.scss index 8af3f5f5..ef003293 100644 --- a/terminus-terminal/src/components/settings.scss +++ b/terminus-terminal/src/components/terminalSettingsTab.scss @@ -1,6 +1,7 @@ .appearance-preview { padding: 10px 20px; margin: 0 0 10px; + overflow: hidden; span { white-space: pre; } diff --git a/terminus-terminal/src/components/settings.ts b/terminus-terminal/src/components/terminalSettingsTab.ts similarity index 58% rename from terminus-terminal/src/components/settings.ts rename to terminus-terminal/src/components/terminalSettingsTab.ts index 13113aa9..9f964802 100644 --- a/terminus-terminal/src/components/settings.ts +++ b/terminus-terminal/src/components/terminalSettingsTab.ts @@ -2,24 +2,25 @@ import { Observable } from 'rxjs/Observable' import 'rxjs/add/operator/map' import 'rxjs/add/operator/debounceTime' import 'rxjs/add/operator/distinctUntilChanged' -const equal = require('deep-equal') const fontManager = require('font-manager') +const equal = require('deep-equal') import { Component, Inject } from '@angular/core' import { ConfigService, HostAppService, Platform } from 'terminus-core' -const { exec } = require('child-process-promise') - import { TerminalColorSchemeProvider, ITerminalColorScheme } from '../api' +const { exec } = require('child-process-promise') @Component({ - template: require('./settings.pug'), - styles: [require('./settings.scss')], + template: require('./terminalSettingsTab.pug'), + styles: [require('./terminalSettingsTab.scss')], }) -export class SettingsComponent { +export class TerminalSettingsTabComponent { fonts: string[] = [] colorSchemes: ITerminalColorScheme[] = [] equalComparator = equal + editingColorScheme: ITerminalColorScheme + schemeChanged = false constructor( public config: ConfigService, @@ -54,5 +55,38 @@ export class SettingsComponent { .map(list => Array.from(new Set(list))) } + editScheme (scheme: ITerminalColorScheme) { + this.editingColorScheme = scheme + this.schemeChanged = false + } + saveScheme () { + let schemes = this.config.full().terminal.customColorSchemes + schemes = schemes.filter(x => x !== this.editingColorScheme && x.name !== this.editingColorScheme.name) + schemes.push(this.editingColorScheme) + this.config.store.terminal.customColorSchemes = schemes + this.config.save() + this.cancelEditing() + } + + cancelEditing () { + this.editingColorScheme = null + } + + deleteScheme (scheme: ITerminalColorScheme) { + if (confirm(`Delete "${scheme.name}"?`)) { + let schemes = this.config.full().terminal.customColorSchemes + schemes = schemes.filter(x => x !== scheme) + this.config.store.terminal.customColorSchemes = schemes + this.config.save() + } + } + + isCustomScheme (scheme: ITerminalColorScheme) { + return this.config.full().terminal.customColorSchemes.some(x => equal(x, scheme)) + } + + colorsTrackBy (index) { + return index + } } diff --git a/terminus-terminal/src/components/terminalTab.ts b/terminus-terminal/src/components/terminalTab.ts index 0467d29f..4171452a 100644 --- a/terminus-terminal/src/components/terminalTab.ts +++ b/terminus-terminal/src/components/terminalTab.ts @@ -181,6 +181,7 @@ export class TerminalTabComponent extends BaseTabComponent { let config = this.config.full() preferenceManager.set('font-family', config.terminal.font) preferenceManager.set('font-size', config.terminal.fontSize) + preferenceManager.set('enable-bold', true) preferenceManager.set('audible-bell-sound', '') preferenceManager.set('desktop-notification-bell', config.terminal.bell == 'notification') preferenceManager.set('enable-clipboard-notice', false) diff --git a/terminus-terminal/src/config.ts b/terminus-terminal/src/config.ts index 11691f9f..8476d009 100644 --- a/terminus-terminal/src/config.ts +++ b/terminus-terminal/src/config.ts @@ -15,6 +15,7 @@ export class TerminalConfigProvider extends ConfigProvider { cursor: null, colors: [], }, + customColorSchemes: [] }, hotkeys: { 'new-tab': [ diff --git a/terminus-terminal/src/index.ts b/terminus-terminal/src/index.ts index e40f9947..8ff34e57 100644 --- a/terminus-terminal/src/index.ts +++ b/terminus-terminal/src/index.ts @@ -7,14 +7,14 @@ import { HostAppService, Platform, ToolbarButtonProvider, TabRecoveryProvider, C import { SettingsTabProvider } from 'terminus-settings' import { TerminalTabComponent } from './components/terminalTab' -import { SettingsComponent } from './components/settings' +import { TerminalSettingsTabComponent } from './components/terminalSettingsTab' import { ColorPickerComponent } from './components/colorPicker' import { SessionsService } from './services/sessions' import { ScreenPersistenceProvider } from './persistenceProviders' import { ButtonProvider } from './buttonProvider' import { RecoveryProvider } from './recoveryProvider' import { SessionPersistenceProvider, TerminalColorSchemeProvider } from './api' -import { TerminalSettingsProvider } from './settings' +import { TerminalSettingsTabProvider } from './settings' import { TerminalConfigProvider } from './config' import { HyperColorSchemes } from './colorSchemes' import { hterm } from './hterm' @@ -42,18 +42,18 @@ import { hterm } from './hterm' }, deps: [HostAppService, ScreenPersistenceProvider], }, - { provide: SettingsTabProvider, useClass: TerminalSettingsProvider, multi: true }, + { provide: SettingsTabProvider, useClass: TerminalSettingsTabProvider, multi: true }, { provide: ConfigProvider, useClass: TerminalConfigProvider, multi: true }, { provide: TerminalColorSchemeProvider, useClass: HyperColorSchemes, multi: true }, ], entryComponents: [ TerminalTabComponent, - SettingsComponent, + TerminalSettingsTabComponent, ], declarations: [ ColorPickerComponent, TerminalTabComponent, - SettingsComponent, + TerminalSettingsTabComponent, ], }) export default class TerminalModule { diff --git a/terminus-terminal/src/persistenceProviders.ts b/terminus-terminal/src/persistenceProviders.ts index ab59ecf8..a3ef30c7 100644 --- a/terminus-terminal/src/persistenceProviders.ts +++ b/terminus-terminal/src/persistenceProviders.ts @@ -47,7 +47,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider { altscreen on `, 'utf-8') let recoveryId = `term-tab-${Date.now()}` - let args = ['-d', '-m', '-c', configPath, '-U', '-S', recoveryId, '--', options.command].concat(options.args || []) + let args = ['-d', '-m', '-c', configPath, '-U', '-S', recoveryId, '-T', 'xterm-256color', '--', options.command].concat(options.args || []) await spawn('screen', args, { cwd: options.cwd, env: options.env || process.env, diff --git a/terminus-terminal/src/settings.ts b/terminus-terminal/src/settings.ts index 65cdd277..8bfd6b57 100644 --- a/terminus-terminal/src/settings.ts +++ b/terminus-terminal/src/settings.ts @@ -1,14 +1,14 @@ import { Injectable } from '@angular/core' import { SettingsTabProvider, ComponentType } from 'terminus-settings' -import { SettingsComponent } from './components/settings' +import { TerminalSettingsTabComponent } from './components/terminalSettingsTab' @Injectable() -export class TerminalSettingsProvider extends SettingsTabProvider { +export class TerminalSettingsTabProvider extends SettingsTabProvider { title = 'Terminal' getComponentType (): ComponentType { - return SettingsComponent + return TerminalSettingsTabComponent } }