Compare commits

...

24 Commits

Author SHA1 Message Date
Eugene Pankov
fa2650cd1f appveyor fix 2017-09-06 17:07:14 +02:00
Eugene Pankov
33514cb073 bumped ng-bootstrap 2017-08-30 11:47:49 +02:00
Eugene Pankov
4d2be9ec89 handle Hyper plugin crashes (fixes #71) 2017-08-30 11:23:51 +02:00
Eugene Pankov
1b2236eb90 fixed #187, fixed #188 2017-08-30 11:12:04 +02:00
Eugene Pankov
f84fd07857 invert scroll-zoom (fixes #184) 2017-08-26 20:02:15 +02:00
Eugene Pankov
24c59b88ca Merge branch 'master' of https://github.com/Eugeny/terminus 2017-08-20 19:31:17 +02:00
Eugene Pankov
e45090cc89 handle compose key on Windows (fixes #17) 2017-08-20 19:31:15 +02:00
Eugene Pankov
f53b96eba8 detect git-bash when installed for current user only (closes #161) 2017-08-18 18:28:38 +03:00
Eugene Pankov
80699ee13f handle plugin loading errors 2017-08-13 15:13:04 +03:00
Eugene Pankov
7e7d537868 allow null values in config (fixes #165) 2017-08-11 19:47:52 +03:00
Eugene Pankov
1afb1e718b change default tmux hotkey (fixes #171) 2017-08-11 19:26:24 +03:00
Eugene Pankov
f71f518058 store Screen configuration in Terminus user directory (fixes #177) 2017-08-11 19:21:32 +03:00
Eugene Pankov
7a005132cc Merge branch 'master' of github.com:Eugeny/terminus 2017-08-11 19:17:54 +03:00
Eugene Pankov
34ef809aee handle null results from winreg (fixes #174) 2017-08-11 19:16:58 +03:00
Eugene Pankov
6352f22c48 Merge pull request #167 from koraktor/patch-1
Start an interactive logon shell for Git Bash
2017-08-07 13:52:54 +02:00
Sebastian Staudt
d0f378764f Start an interactive logon shell for Git Bash
Provide additional arguments to `bash.exe` to get an interactive login shell.
This ensures e.g. `.profile` and `.bash_profile` are sourced. As there’s no way
to have an existing session under Windows, `--login` is mandatory. Each bash
session must be started from scratch.

Fixes #105
2017-08-07 10:07:07 +02:00
Eugene Pankov
7885badbfd make line padding adjustable (fixes #141) 2017-08-05 16:57:00 +02:00
Eugene Pankov
5999d169bc mac & windows icons 2017-08-05 16:27:25 +02:00
Eugene Pankov
40b0f8cb69 added tmux dependency 2017-08-05 10:15:07 +02:00
Eugene Pankov
f428be5ae7 ignore unavaiable persistence providers in SessionsService (fixes #159) 2017-08-05 09:25:25 +02:00
Eugene Pankov
39183b1205 Merge branch 'master' of github.com:Eugeny/terminus 2017-08-04 14:42:06 +02:00
Eugene Pankov
36f82545ae fixed #155 2017-08-04 14:41:36 +02:00
Eugene Pankov
1ef8343ea9 default to tmux if available on Linux 2017-08-04 14:40:49 +02:00
fossabot
c9e24819ae Add license scan report and status 2017-08-04 13:39:41 +02:00
27 changed files with 164 additions and 54 deletions

View File

@@ -10,6 +10,7 @@
</div> </div>
[![Build Status](https://travis-ci.org/Eugeny/terminus.svg?branch=master)](https://travis-ci.org/Eugeny/terminus) [![Build status](https://ci.appveyor.com/api/projects/status/wnnq4hm5mbd9rgoy?svg=true)](https://ci.appveyor.com/project/Eugeny/terminus) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE) [![Downloads](https://img.shields.io/badge/downloads-latest_release-brightgreen.svg)](https://github.com/Eugeny/terminus/releases/latest) [![Build Status](https://travis-ci.org/Eugeny/terminus.svg?branch=master)](https://travis-ci.org/Eugeny/terminus) [![Build status](https://ci.appveyor.com/api/projects/status/wnnq4hm5mbd9rgoy?svg=true)](https://ci.appveyor.com/project/Eugeny/terminus) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE) [![Downloads](https://img.shields.io/badge/downloads-latest_release-brightgreen.svg)](https://github.com/Eugeny/terminus/releases/latest)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus?ref=badge_shield)
---- ----
@@ -45,3 +46,7 @@ Plugins can be installed directly from the Settings view inside Terminus.
Pull requests and plugins are welcome! Publish your plugin on NPM with a `terminus-plugin` keyword to make them appear in the Plugin Manager. Pull requests and plugins are welcome! Publish your plugin on NPM with a `terminus-plugin` keyword to make them appear in the Plugin Manager.
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) for a very brief plugin development tutorial! See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) for a very brief plugin development tutorial!
## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus?ref=badge_large)

View File

@@ -19,7 +19,7 @@
"@angular/forms": "4.3.0", "@angular/forms": "4.3.0",
"@angular/platform-browser": "4.3.0", "@angular/platform-browser": "4.3.0",
"@angular/platform-browser-dynamic": "4.3.0", "@angular/platform-browser-dynamic": "4.3.0",
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.28", "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.2",
"devtron": "1.4.0", "devtron": "1.4.0",
"electron-config": "0.2.1", "electron-config": "0.2.1",
"electron-debug": "^1.0.1", "electron-debug": "^1.0.1",

View File

@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser' import { BrowserModule } from '@angular/platform-browser'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap' import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
export async function getRootModule (plugins: any[]): Promise<any> { export function getRootModule (plugins: any[]) {
let imports = [ let imports = [
BrowserModule, BrowserModule,
...(plugins.map(x => x.default.forRoot ? x.default.forRoot() : x.default)), ...(plugins.map(x => x.default.forRoot ? x.default.forRoot() : x.default)),

View File

@@ -6,11 +6,11 @@ import 'rxjs'
// Always land on the start view // Always land on the start view
location.hash = '' location.hash = ''
import { enableProdMode } from '@angular/core' import { enableProdMode, NgModuleRef } from '@angular/core'
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
import { getRootModule } from './app.module' import { getRootModule } from './app.module'
import { findPlugins, loadPlugins } from './plugins' import { findPlugins, loadPlugins, IPluginInfo } from './plugins'
if (process.platform === 'win32') { if (process.platform === 'win32') {
process.env.HOME = process.env.HOMEDRIVE + process.env.HOMEPATH process.env.HOME = process.env.HOMEDRIVE + process.env.HOMEPATH
@@ -22,10 +22,29 @@ if (require('electron-is-dev')) {
enableProdMode() enableProdMode()
} }
findPlugins().then(async plugins => { async function bootstrap (plugins: IPluginInfo[], safeMode = false): Promise<NgModuleRef<any>> {
if (safeMode) {
plugins = plugins.filter(x => x.isBuiltin)
}
let pluginsModules = await loadPlugins(plugins, (current, total) => { let pluginsModules = await loadPlugins(plugins, (current, total) => {
(document.querySelector('.progress .bar') as HTMLElement).style.width = 100 * current / total + '%' (document.querySelector('.progress .bar') as HTMLElement).style.width = 100 * current / total + '%'
}) })
let module = await getRootModule(pluginsModules) let module = getRootModule(pluginsModules)
platformBrowserDynamic().bootstrapModule(module) return await platformBrowserDynamic().bootstrapModule(module)
}
findPlugins().then(async plugins => {
console.log('Starting with plugins:', plugins)
try {
await bootstrap(plugins)
} catch (error) {
console.error('Angular bootstrapping error:', error)
console.warn('Trying safe mode')
window['safeModeReason'] = error
try {
await bootstrap(plugins, true)
} catch (error) {
console.error('Bootstrap failed:', error)
}
}
}) })

View File

@@ -20,7 +20,7 @@ if (process.env.DEV) {
nodeModule.globalPaths.unshift(path.dirname(require('electron').remote.app.getAppPath())) nodeModule.globalPaths.unshift(path.dirname(require('electron').remote.app.getAppPath()))
} }
const builtinPluginsPath = path.join((process as any).resourcesPath, 'builtin-plugins') const builtinPluginsPath = process.env.DEV ? path.dirname(require('electron').remote.app.getAppPath()) : path.join((process as any).resourcesPath, 'builtin-plugins')
const userPluginsPath = path.join( const userPluginsPath = path.join(
require('electron').remote.app.getPath('appData'), require('electron').remote.app.getPath('appData'),

View File

@@ -44,9 +44,9 @@
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@ng-bootstrap/ng-bootstrap@^1.0.0-alpha.28": "@ng-bootstrap/ng-bootstrap@^1.0.0-beta.2":
version "1.0.0-alpha.28" version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0-alpha.28.tgz#30a6503bf7f94f9d3187591fb3267b59cc0cdaad" resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0-beta.2.tgz#3d4b567b0334a9ee631b73c72156cd3a9d3cd29f"
"@types/mz@0.0.31": "@types/mz@0.0.31":
version "0.0.31" version "0.0.31"

View File

@@ -33,5 +33,4 @@ deploy:
prerelease: false prerelease: false
force_update: true force_update: true
on: on:
branch: master
appveyor_repo_tag: true appveyor_repo_tag: true

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View File

@@ -74,7 +74,8 @@
"libnotify4", "libnotify4",
"libappindicator1", "libappindicator1",
"libxtst6", "libxtst6",
"libnss3" "libnss3",
"tmux"
] ]
}, },
"rpm": { "rpm": {

View File

@@ -1,5 +1,6 @@
import { Component, Inject, Input, HostListener } from '@angular/core' import { Component, Inject, Input, HostListener } from '@angular/core'
import { trigger, style, animate, transition, state } from '@angular/animations' import { trigger, style, animate, transition, state } from '@angular/animations'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { ElectronService } from '../services/electron.service' import { ElectronService } from '../services/electron.service'
import { HostAppService, Platform } from '../services/hostApp.service' import { HostAppService, Platform } from '../services/hostApp.service'
@@ -10,6 +11,7 @@ import { DockingService } from '../services/docking.service'
import { TabRecoveryService } from '../services/tabRecovery.service' import { TabRecoveryService } from '../services/tabRecovery.service'
import { ThemesService } from '../services/themes.service' import { ThemesService } from '../services/themes.service'
import { SafeModeModalComponent } from './safeModeModal.component'
import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api' import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
@Component({ @Component({
@@ -62,6 +64,7 @@ export class AppRootComponent {
public app: AppService, public app: AppService,
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[], @Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
log: LogService, log: LogService,
ngbModal: NgbModal,
_themes: ThemesService, _themes: ThemesService,
) { ) {
this.logger = log.create('main') this.logger = log.create('main')
@@ -104,6 +107,10 @@ export class AppRootComponent {
this.hotkeys.globalHotkey.subscribe(() => { this.hotkeys.globalHotkey.subscribe(() => {
this.onGlobalHotkey() this.onGlobalHotkey()
}) })
if (window['safeModeReason']) {
ngbModal.open(SafeModeModalComponent)
}
} }
onGlobalHotkey () { onGlobalHotkey () {

View File

@@ -0,0 +1,7 @@
.modal-body
.alert.alert-danger Terminus could not start with your plugins, so all third party plugins have been disabled in this session. The error was:
pre {{error}}
.modal-footer
button.btn.btn-outline-primary((click)='close()') Close

View File

@@ -0,0 +1,19 @@
import { Component, Input } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
@Component({
template: require('./safeModeModal.component.pug'),
})
export class SafeModeModalComponent {
@Input() error: Error
constructor (
public modalInstance: NgbActiveModal,
) {
this.error = window['safeModeReason']
}
close () {
this.modalInstance.dismiss()
}
}

View File

@@ -17,6 +17,7 @@ import { ThemesService } from './services/themes.service'
import { AppRootComponent } from './components/appRoot.component' import { AppRootComponent } from './components/appRoot.component'
import { TabBodyComponent } from './components/tabBody.component' import { TabBodyComponent } from './components/tabBody.component'
import { SafeModeModalComponent } from './components/safeModeModal.component'
import { StartPageComponent } from './components/startPage.component' import { StartPageComponent } from './components/startPage.component'
import { TabHeaderComponent } from './components/tabHeader.component' import { TabHeaderComponent } from './components/tabHeader.component'
import { TitleBarComponent } from './components/titleBar.component' import { TitleBarComponent } from './components/titleBar.component'
@@ -52,7 +53,7 @@ const PROVIDERS = [
BrowserModule, BrowserModule,
BrowserAnimationsModule, BrowserAnimationsModule,
FormsModule, FormsModule,
NgbModule, NgbModule.forRoot(),
PerfectScrollbarModule.forRoot({ PerfectScrollbarModule.forRoot({
suppressScrollX: true, suppressScrollX: true,
}), }),
@@ -65,9 +66,11 @@ const PROVIDERS = [
TitleBarComponent, TitleBarComponent,
WindowControlsComponent, WindowControlsComponent,
RenameTabModalComponent, RenameTabModalComponent,
SafeModeModalComponent,
], ],
entryComponents: [ entryComponents: [
RenameTabModalComponent, RenameTabModalComponent,
SafeModeModalComponent,
] ]
}) })
export default class AppModule { export default class AppModule {

View File

@@ -38,7 +38,7 @@ export class ConfigProxy {
{ {
enumerable: true, enumerable: true,
configurable: false, configurable: false,
get: () => real[key] || defaults[key], get: () => (real[key] !== undefined) ? real[key] : defaults[key],
set: (value) => { set: (value) => {
real[key] = value real[key] = value
} }

View File

@@ -76,6 +76,13 @@ $list-group-border-color: rgba(255,255,255,.1);
$list-group-hover-bg: rgba(255,255,255,.1); $list-group-hover-bg: rgba(255,255,255,.1);
$list-group-link-active-bg: rgba(255,255,255,.2); $list-group-link-active-bg: rgba(255,255,255,.2);
$pre-bg: $dropdown-bg;
$pre-color: $dropdown-link-color;
$alert-danger-bg: $body-bg2;
$alert-danger-text: $red;
$alert-danger-border: $red;
@import '~bootstrap/scss/bootstrap.scss'; @import '~bootstrap/scss/bootstrap.scss';

View File

@@ -13,35 +13,39 @@ export class HyperColorSchemes extends TerminalColorSchemeProvider {
let themes: ITerminalColorScheme[] = [] let themes: ITerminalColorScheme[] = []
plugins.forEach(plugin => { plugins.forEach(plugin => {
let module = (global as any).require(path.join(pluginsPath, plugin)) try {
if (module.decorateConfig) { let module = (global as any).require(path.join(pluginsPath, plugin))
let config = module.decorateConfig({}) if (module.decorateConfig) {
if (config.colors) { let config = module.decorateConfig({})
themes.push({ if (config.colors) {
name: plugin, themes.push({
foreground: config.foregroundColor, name: plugin,
background: config.backgroundColor, foreground: config.foregroundColor,
cursor: config.cursorColor, background: config.backgroundColor,
colors: config.colors.black ? [ cursor: config.cursorColor,
config.colors.black, colors: config.colors.black ? [
config.colors.red, config.colors.black,
config.colors.green, config.colors.red,
config.colors.yellow, config.colors.green,
config.colors.blue, config.colors.yellow,
config.colors.magenta, config.colors.blue,
config.colors.cyan, config.colors.magenta,
config.colors.white, config.colors.cyan,
config.colors.lightBlack, config.colors.white,
config.colors.lightRed, config.colors.lightBlack,
config.colors.lightGreen, config.colors.lightRed,
config.colors.lightYellow, config.colors.lightGreen,
config.colors.lightBlue, config.colors.lightYellow,
config.colors.lightMagenta, config.colors.lightBlue,
config.colors.lightCyan, config.colors.lightMagenta,
config.colors.lightWhite, config.colors.lightCyan,
] : config.colors, config.colors.lightWhite,
}) ] : config.colors,
})
}
} }
} catch (err) {
console.debug('Skipping Hyper plugin', plugin, err)
} }
}) })

View File

@@ -230,7 +230,7 @@
) )
option( option(
*ngFor='let shell of shells', *ngFor='let shell of shells',
[ngValue]='shell.command' [ngValue]='shell.id'
) {{shell.name}} ) {{shell.name}}
.form-group .form-group

View File

@@ -182,7 +182,7 @@ export class TerminalTabComponent extends BaseTabComponent {
this.mouseEvent$.next(event) this.mouseEvent$.next(event)
if (event.type === 'mousewheel') { if (event.type === 'mousewheel') {
if (event.ctrlKey || event.metaKey) { if (event.ctrlKey || event.metaKey) {
if (event.wheelDeltaY < 0) { if (event.wheelDeltaY > 0) {
this.zoomIn() this.zoomIn()
} else { } else {
this.zoomOut() this.zoomOut()
@@ -214,6 +214,13 @@ export class TerminalTabComponent extends BaseTabComponent {
return ret return ret
} }
} }
const _measureCharacterSize = hterm.scrollPort_.measureCharacterSize.bind(hterm.scrollPort_)
hterm.scrollPort_.measureCharacterSize = () => {
let size = _measureCharacterSize()
size.height += this.config.store.terminal.linePadding
return size
}
} }
attachIOHandlers (io: any) { attachIOHandlers (io: any) {
@@ -261,6 +268,8 @@ export class TerminalTabComponent extends BaseTabComponent {
preferenceManager.set('ctrl-plus-minus-zero-zoom', false) preferenceManager.set('ctrl-plus-minus-zero-zoom', false)
preferenceManager.set('scrollbar-visible', this.hostApp.platform === Platform.macOS) preferenceManager.set('scrollbar-visible', this.hostApp.platform === Platform.macOS)
preferenceManager.set('copy-on-select', false) preferenceManager.set('copy-on-select', false)
preferenceManager.set('alt-sends-what', 'browser-key')
preferenceManager.set('alt-gr-mode', 'ctrl-alt')
if (config.terminal.colorScheme.foreground) { if (config.terminal.colorScheme.foreground) {
preferenceManager.set('foreground-color', config.terminal.colorScheme.foreground) preferenceManager.set('foreground-color', config.terminal.colorScheme.foreground)

View File

@@ -4,6 +4,7 @@ export class TerminalConfigProvider extends ConfigProvider {
defaults = { defaults = {
terminal: { terminal: {
fontSize: 14, fontSize: 14,
linePadding: 0,
bell: 'off', bell: 'off',
bracketedPaste: false, bracketedPaste: false,
background: 'theme', background: 'theme',
@@ -42,7 +43,7 @@ export class TerminalConfigProvider extends ConfigProvider {
[Platform.macOS]: { [Platform.macOS]: {
terminal: { terminal: {
font: 'Menlo', font: 'Menlo',
shell: '~default-shell~', shell: 'default',
persistence: 'screen', persistence: 'screen',
}, },
hotkeys: { hotkeys: {
@@ -74,7 +75,7 @@ export class TerminalConfigProvider extends ConfigProvider {
[Platform.Windows]: { [Platform.Windows]: {
terminal: { terminal: {
font: 'Consolas', font: 'Consolas',
shell: '~clink~', shell: 'clink',
persistence: null, persistence: null,
}, },
hotkeys: { hotkeys: {
@@ -105,8 +106,8 @@ export class TerminalConfigProvider extends ConfigProvider {
[Platform.Linux]: { [Platform.Linux]: {
terminal: { terminal: {
font: 'Liberation Mono', font: 'Liberation Mono',
shell: '~default-shell~', shell: 'default',
persistence: 'screen', persistence: 'tmux',
}, },
hotkeys: { hotkeys: {
'copy': [ 'copy': [

View File

@@ -10,6 +10,11 @@ x-screen {
transition: 0.125s ease background; transition: 0.125s ease background;
} }
x-row > span {
display: inline-block;
height: inherit;
}
@font-face { @font-face {
font-family: "monospace-fallback"; font-family: "monospace-fallback";
src: url(fonts/Meslo.otf) format("opentype"); src: url(fonts/Meslo.otf) format("opentype");

View File

@@ -1,10 +1,11 @@
import * as fs from 'mz/fs' import * as fs from 'mz/fs'
import * as path from 'path'
import { exec, spawn } from 'mz/child_process' import { exec, spawn } from 'mz/child_process'
import { exec as execAsync, execFileSync } from 'child_process' import { exec as execAsync, execFileSync } from 'child_process'
import { AsyncSubject } from 'rxjs' import { AsyncSubject } from 'rxjs'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { Logger, LogService } from 'terminus-core' import { Logger, LogService, ElectronService } from 'terminus-core'
import { SessionOptions, SessionPersistenceProvider } from '../api' import { SessionOptions, SessionPersistenceProvider } from '../api'
declare function delay (ms: number): Promise<void> declare function delay (ms: number): Promise<void>
@@ -35,6 +36,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
constructor ( constructor (
log: LogService, log: LogService,
private electron: ElectronService,
) { ) {
super() super()
this.logger = log.create('main') this.logger = log.create('main')
@@ -115,7 +117,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
} }
private async prepareConfig (): Promise<string> { private async prepareConfig (): Promise<string> {
let configPath = '/tmp/.termScreenConfig' let configPath = path.join(this.electron.app.getPath('userData'), 'screen-config.tmp')
await fs.writeFile(configPath, ` await fs.writeFile(configPath, `
escape ^^^ escape ^^^
vbell off vbell off

View File

@@ -15,6 +15,7 @@ const TMUX_CONFIG = `
set -g set-titles-string "#W" set -g set-titles-string "#W"
set -g window-status-format '#I:#(pwd="#{pane_current_path}"; echo \${pwd####*/})#F' set -g window-status-format '#I:#(pwd="#{pane_current_path}"; echo \${pwd####*/})#F'
set -g window-status-current-format '#I:#(pwd="#{pane_current_path}"; echo \${pwd####*/})#F' set -g window-status-current-format '#I:#(pwd="#{pane_current_path}"; echo \${pwd####*/})#F'
set-option -g prefix C-^
set-option -g status-interval 1 set-option -g status-interval 1
` `

View File

@@ -156,6 +156,9 @@ export class Session {
} }
async getWorkingDirectory (): Promise<string> { async getWorkingDirectory (): Promise<string> {
if (!this.truePID) {
return null
}
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
let lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n') let lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n')
if (lines[1] === 'fcwd') { if (lines[1] === 'fcwd') {
@@ -185,6 +188,7 @@ export class SessionsService {
) { ) {
nodePTY = electron.remoteRequirePluginModule('terminus-terminal', 'node-pty', global as any) nodePTY = electron.remoteRequirePluginModule('terminus-terminal', 'node-pty', global as any)
this.logger = log.create('sessions') this.logger = log.create('sessions')
this.persistenceProviders = this.persistenceProviders.filter(x => x.isAvailable())
} }
async prepareNewSession (options: SessionOptions): Promise<SessionOptions> { async prepareNewSession (options: SessionOptions): Promise<SessionOptions> {
@@ -220,6 +224,9 @@ export class SessionsService {
} }
private getPersistence (): SessionPersistenceProvider { private getPersistence (): SessionPersistenceProvider {
if (!this.config.store.terminal.persistence) {
return null
}
return this.persistenceProviders.find(x => x.id === this.config.store.terminal.persistence) || null return this.persistenceProviders.find(x => x.id === this.config.store.terminal.persistence) || null
} }
} }

View File

@@ -25,7 +25,7 @@ export class Cygwin32ShellProvider extends ShellProvider {
let cygwinPath = await new Promise<string>(resolve => { let cygwinPath = await new Promise<string>(resolve => {
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup', arch: 'x86' }) let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup', arch: 'x86' })
reg.get('rootdir', (err, item) => { reg.get('rootdir', (err, item) => {
if (err) { if (err || !item) {
return resolve(null) return resolve(null)
} }
resolve(item.value) resolve(item.value)

View File

@@ -25,7 +25,7 @@ export class Cygwin64ShellProvider extends ShellProvider {
let cygwinPath = await new Promise<string>(resolve => { let cygwinPath = await new Promise<string>(resolve => {
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup', arch: 'x64' }) let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup', arch: 'x64' })
reg.get('rootdir', (err, item) => { reg.get('rootdir', (err, item) => {
if (err) { if (err || !item) {
return resolve(null) return resolve(null)
} }
resolve(item.value) resolve(item.value)

View File

@@ -25,7 +25,7 @@ export class GitBashShellProvider extends ShellProvider {
let gitBashPath = await new Promise<string>(resolve => { let gitBashPath = await new Promise<string>(resolve => {
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\GitForWindows' }) let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\GitForWindows' })
reg.get('InstallPath', (err, item) => { reg.get('InstallPath', (err, item) => {
if (err) { if (err || !item) {
resolve(null) resolve(null)
return return
} }
@@ -33,6 +33,19 @@ export class GitBashShellProvider extends ShellProvider {
}) })
}) })
if (!gitBashPath) {
gitBashPath = await new Promise<string>(resolve => {
let reg = new Registry({ hive: Registry.HKCU, key: '\\Software\\GitForWindows' })
reg.get('InstallPath', (err, item) => {
if (err || !item) {
resolve(null)
return
}
resolve(item.value)
})
})
}
if (!gitBashPath) { if (!gitBashPath) {
return [] return []
} }
@@ -41,6 +54,7 @@ export class GitBashShellProvider extends ShellProvider {
id: 'git-bash', id: 'git-bash',
name: 'Git-Bash', name: 'Git-Bash',
command: path.join(gitBashPath, 'bin', 'bash.exe'), command: path.join(gitBashPath, 'bin', 'bash.exe'),
args: [ '--login', '-i' ],
env: { env: {
TERM: 'cygwin', TERM: 'cygwin',
} }