mirror of
https://github.com/Eugeny/tabby.git
synced 2025-09-07 17:11:50 +00:00
Compare commits
24 Commits
v1.0.0-alp
...
v1.0.0-alp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fa2650cd1f | ||
![]() |
33514cb073 | ||
![]() |
4d2be9ec89 | ||
![]() |
1b2236eb90 | ||
![]() |
f84fd07857 | ||
![]() |
24c59b88ca | ||
![]() |
e45090cc89 | ||
![]() |
f53b96eba8 | ||
![]() |
80699ee13f | ||
![]() |
7e7d537868 | ||
![]() |
1afb1e718b | ||
![]() |
f71f518058 | ||
![]() |
7a005132cc | ||
![]() |
34ef809aee | ||
![]() |
6352f22c48 | ||
![]() |
d0f378764f | ||
![]() |
7885badbfd | ||
![]() |
5999d169bc | ||
![]() |
40b0f8cb69 | ||
![]() |
f428be5ae7 | ||
![]() |
39183b1205 | ||
![]() |
36f82545ae | ||
![]() |
1ef8343ea9 | ||
![]() |
c9e24819ae |
@@ -10,6 +10,7 @@
|
||||
</div>
|
||||
|
||||
[](https://travis-ci.org/Eugeny/terminus) [](https://ci.appveyor.com/project/Eugeny/terminus) [](https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE) [](https://github.com/Eugeny/terminus/releases/latest)
|
||||
[](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.
|
||||
|
||||
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) for a very brief plugin development tutorial!
|
||||
|
||||
|
||||
## License
|
||||
[](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus?ref=badge_large)
|
@@ -19,7 +19,7 @@
|
||||
"@angular/forms": "4.3.0",
|
||||
"@angular/platform-browser": "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",
|
||||
"electron-config": "0.2.1",
|
||||
"electron-debug": "^1.0.1",
|
||||
|
@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'
|
||||
import { BrowserModule } from '@angular/platform-browser'
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
export async function getRootModule (plugins: any[]): Promise<any> {
|
||||
export function getRootModule (plugins: any[]) {
|
||||
let imports = [
|
||||
BrowserModule,
|
||||
...(plugins.map(x => x.default.forRoot ? x.default.forRoot() : x.default)),
|
||||
|
@@ -6,11 +6,11 @@ import 'rxjs'
|
||||
// Always land on the start view
|
||||
location.hash = ''
|
||||
|
||||
import { enableProdMode } from '@angular/core'
|
||||
import { enableProdMode, NgModuleRef } from '@angular/core'
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
|
||||
|
||||
import { getRootModule } from './app.module'
|
||||
import { findPlugins, loadPlugins } from './plugins'
|
||||
import { findPlugins, loadPlugins, IPluginInfo } from './plugins'
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
process.env.HOME = process.env.HOMEDRIVE + process.env.HOMEPATH
|
||||
@@ -22,10 +22,29 @@ if (require('electron-is-dev')) {
|
||||
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) => {
|
||||
(document.querySelector('.progress .bar') as HTMLElement).style.width = 100 * current / total + '%'
|
||||
})
|
||||
let module = await getRootModule(pluginsModules)
|
||||
platformBrowserDynamic().bootstrapModule(module)
|
||||
let module = getRootModule(pluginsModules)
|
||||
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)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@@ -20,7 +20,7 @@ if (process.env.DEV) {
|
||||
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(
|
||||
require('electron').remote.app.getPath('appData'),
|
||||
|
@@ -44,9 +44,9 @@
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@ng-bootstrap/ng-bootstrap@^1.0.0-alpha.28":
|
||||
version "1.0.0-alpha.28"
|
||||
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0-alpha.28.tgz#30a6503bf7f94f9d3187591fb3267b59cc0cdaad"
|
||||
"@ng-bootstrap/ng-bootstrap@^1.0.0-beta.2":
|
||||
version "1.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0-beta.2.tgz#3d4b567b0334a9ee631b73c72156cd3a9d3cd29f"
|
||||
|
||||
"@types/mz@0.0.31":
|
||||
version "0.0.31"
|
||||
|
@@ -33,5 +33,4 @@ deploy:
|
||||
prerelease: false
|
||||
force_update: true
|
||||
on:
|
||||
branch: master
|
||||
appveyor_repo_tag: true
|
||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 361 KiB After Width: | Height: | Size: 361 KiB |
@@ -74,7 +74,8 @@
|
||||
"libnotify4",
|
||||
"libappindicator1",
|
||||
"libxtst6",
|
||||
"libnss3"
|
||||
"libnss3",
|
||||
"tmux"
|
||||
]
|
||||
},
|
||||
"rpm": {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { Component, Inject, Input, HostListener } from '@angular/core'
|
||||
import { trigger, style, animate, transition, state } from '@angular/animations'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
import { ElectronService } from '../services/electron.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 { ThemesService } from '../services/themes.service'
|
||||
|
||||
import { SafeModeModalComponent } from './safeModeModal.component'
|
||||
import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
|
||||
|
||||
@Component({
|
||||
@@ -62,6 +64,7 @@ export class AppRootComponent {
|
||||
public app: AppService,
|
||||
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
|
||||
log: LogService,
|
||||
ngbModal: NgbModal,
|
||||
_themes: ThemesService,
|
||||
) {
|
||||
this.logger = log.create('main')
|
||||
@@ -104,6 +107,10 @@ export class AppRootComponent {
|
||||
this.hotkeys.globalHotkey.subscribe(() => {
|
||||
this.onGlobalHotkey()
|
||||
})
|
||||
|
||||
if (window['safeModeReason']) {
|
||||
ngbModal.open(SafeModeModalComponent)
|
||||
}
|
||||
}
|
||||
|
||||
onGlobalHotkey () {
|
||||
|
7
terminus-core/src/components/safeModeModal.component.pug
Normal file
7
terminus-core/src/components/safeModeModal.component.pug
Normal 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
|
19
terminus-core/src/components/safeModeModal.component.ts
Normal file
19
terminus-core/src/components/safeModeModal.component.ts
Normal 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()
|
||||
}
|
||||
}
|
@@ -17,6 +17,7 @@ import { ThemesService } from './services/themes.service'
|
||||
|
||||
import { AppRootComponent } from './components/appRoot.component'
|
||||
import { TabBodyComponent } from './components/tabBody.component'
|
||||
import { SafeModeModalComponent } from './components/safeModeModal.component'
|
||||
import { StartPageComponent } from './components/startPage.component'
|
||||
import { TabHeaderComponent } from './components/tabHeader.component'
|
||||
import { TitleBarComponent } from './components/titleBar.component'
|
||||
@@ -52,7 +53,7 @@ const PROVIDERS = [
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
FormsModule,
|
||||
NgbModule,
|
||||
NgbModule.forRoot(),
|
||||
PerfectScrollbarModule.forRoot({
|
||||
suppressScrollX: true,
|
||||
}),
|
||||
@@ -65,9 +66,11 @@ const PROVIDERS = [
|
||||
TitleBarComponent,
|
||||
WindowControlsComponent,
|
||||
RenameTabModalComponent,
|
||||
SafeModeModalComponent,
|
||||
],
|
||||
entryComponents: [
|
||||
RenameTabModalComponent,
|
||||
SafeModeModalComponent,
|
||||
]
|
||||
})
|
||||
export default class AppModule {
|
||||
|
@@ -38,7 +38,7 @@ export class ConfigProxy {
|
||||
{
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
get: () => real[key] || defaults[key],
|
||||
get: () => (real[key] !== undefined) ? real[key] : defaults[key],
|
||||
set: (value) => {
|
||||
real[key] = value
|
||||
}
|
||||
|
@@ -76,6 +76,13 @@ $list-group-border-color: rgba(255,255,255,.1);
|
||||
$list-group-hover-bg: rgba(255,255,255,.1);
|
||||
$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';
|
||||
|
||||
|
@@ -13,35 +13,39 @@ export class HyperColorSchemes extends TerminalColorSchemeProvider {
|
||||
let themes: ITerminalColorScheme[] = []
|
||||
|
||||
plugins.forEach(plugin => {
|
||||
let module = (global as any).require(path.join(pluginsPath, plugin))
|
||||
if (module.decorateConfig) {
|
||||
let config = module.decorateConfig({})
|
||||
if (config.colors) {
|
||||
themes.push({
|
||||
name: plugin,
|
||||
foreground: config.foregroundColor,
|
||||
background: config.backgroundColor,
|
||||
cursor: config.cursorColor,
|
||||
colors: config.colors.black ? [
|
||||
config.colors.black,
|
||||
config.colors.red,
|
||||
config.colors.green,
|
||||
config.colors.yellow,
|
||||
config.colors.blue,
|
||||
config.colors.magenta,
|
||||
config.colors.cyan,
|
||||
config.colors.white,
|
||||
config.colors.lightBlack,
|
||||
config.colors.lightRed,
|
||||
config.colors.lightGreen,
|
||||
config.colors.lightYellow,
|
||||
config.colors.lightBlue,
|
||||
config.colors.lightMagenta,
|
||||
config.colors.lightCyan,
|
||||
config.colors.lightWhite,
|
||||
] : config.colors,
|
||||
})
|
||||
try {
|
||||
let module = (global as any).require(path.join(pluginsPath, plugin))
|
||||
if (module.decorateConfig) {
|
||||
let config = module.decorateConfig({})
|
||||
if (config.colors) {
|
||||
themes.push({
|
||||
name: plugin,
|
||||
foreground: config.foregroundColor,
|
||||
background: config.backgroundColor,
|
||||
cursor: config.cursorColor,
|
||||
colors: config.colors.black ? [
|
||||
config.colors.black,
|
||||
config.colors.red,
|
||||
config.colors.green,
|
||||
config.colors.yellow,
|
||||
config.colors.blue,
|
||||
config.colors.magenta,
|
||||
config.colors.cyan,
|
||||
config.colors.white,
|
||||
config.colors.lightBlack,
|
||||
config.colors.lightRed,
|
||||
config.colors.lightGreen,
|
||||
config.colors.lightYellow,
|
||||
config.colors.lightBlue,
|
||||
config.colors.lightMagenta,
|
||||
config.colors.lightCyan,
|
||||
config.colors.lightWhite,
|
||||
] : config.colors,
|
||||
})
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.debug('Skipping Hyper plugin', plugin, err)
|
||||
}
|
||||
})
|
||||
|
||||
|
@@ -230,7 +230,7 @@
|
||||
)
|
||||
option(
|
||||
*ngFor='let shell of shells',
|
||||
[ngValue]='shell.command'
|
||||
[ngValue]='shell.id'
|
||||
) {{shell.name}}
|
||||
|
||||
.form-group
|
||||
|
@@ -182,7 +182,7 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
this.mouseEvent$.next(event)
|
||||
if (event.type === 'mousewheel') {
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (event.wheelDeltaY < 0) {
|
||||
if (event.wheelDeltaY > 0) {
|
||||
this.zoomIn()
|
||||
} else {
|
||||
this.zoomOut()
|
||||
@@ -214,6 +214,13 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
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) {
|
||||
@@ -261,6 +268,8 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
preferenceManager.set('ctrl-plus-minus-zero-zoom', false)
|
||||
preferenceManager.set('scrollbar-visible', this.hostApp.platform === Platform.macOS)
|
||||
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) {
|
||||
preferenceManager.set('foreground-color', config.terminal.colorScheme.foreground)
|
||||
|
@@ -4,6 +4,7 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
defaults = {
|
||||
terminal: {
|
||||
fontSize: 14,
|
||||
linePadding: 0,
|
||||
bell: 'off',
|
||||
bracketedPaste: false,
|
||||
background: 'theme',
|
||||
@@ -42,7 +43,7 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
[Platform.macOS]: {
|
||||
terminal: {
|
||||
font: 'Menlo',
|
||||
shell: '~default-shell~',
|
||||
shell: 'default',
|
||||
persistence: 'screen',
|
||||
},
|
||||
hotkeys: {
|
||||
@@ -74,7 +75,7 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
[Platform.Windows]: {
|
||||
terminal: {
|
||||
font: 'Consolas',
|
||||
shell: '~clink~',
|
||||
shell: 'clink',
|
||||
persistence: null,
|
||||
},
|
||||
hotkeys: {
|
||||
@@ -105,8 +106,8 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
[Platform.Linux]: {
|
||||
terminal: {
|
||||
font: 'Liberation Mono',
|
||||
shell: '~default-shell~',
|
||||
persistence: 'screen',
|
||||
shell: 'default',
|
||||
persistence: 'tmux',
|
||||
},
|
||||
hotkeys: {
|
||||
'copy': [
|
||||
|
@@ -10,6 +10,11 @@ x-screen {
|
||||
transition: 0.125s ease background;
|
||||
}
|
||||
|
||||
x-row > span {
|
||||
display: inline-block;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "monospace-fallback";
|
||||
src: url(fonts/Meslo.otf) format("opentype");
|
||||
|
@@ -1,10 +1,11 @@
|
||||
import * as fs from 'mz/fs'
|
||||
import * as path from 'path'
|
||||
import { exec, spawn } from 'mz/child_process'
|
||||
import { exec as execAsync, execFileSync } from 'child_process'
|
||||
|
||||
import { AsyncSubject } from 'rxjs'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { Logger, LogService } from 'terminus-core'
|
||||
import { Logger, LogService, ElectronService } from 'terminus-core'
|
||||
import { SessionOptions, SessionPersistenceProvider } from '../api'
|
||||
|
||||
declare function delay (ms: number): Promise<void>
|
||||
@@ -35,6 +36,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
|
||||
|
||||
constructor (
|
||||
log: LogService,
|
||||
private electron: ElectronService,
|
||||
) {
|
||||
super()
|
||||
this.logger = log.create('main')
|
||||
@@ -115,7 +117,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
|
||||
}
|
||||
|
||||
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, `
|
||||
escape ^^^
|
||||
vbell off
|
||||
|
@@ -15,6 +15,7 @@ const TMUX_CONFIG = `
|
||||
set -g set-titles-string "#W"
|
||||
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-option -g prefix C-^
|
||||
set-option -g status-interval 1
|
||||
`
|
||||
|
||||
|
@@ -156,6 +156,9 @@ export class Session {
|
||||
}
|
||||
|
||||
async getWorkingDirectory (): Promise<string> {
|
||||
if (!this.truePID) {
|
||||
return null
|
||||
}
|
||||
if (process.platform === 'darwin') {
|
||||
let lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n')
|
||||
if (lines[1] === 'fcwd') {
|
||||
@@ -185,6 +188,7 @@ export class SessionsService {
|
||||
) {
|
||||
nodePTY = electron.remoteRequirePluginModule('terminus-terminal', 'node-pty', global as any)
|
||||
this.logger = log.create('sessions')
|
||||
this.persistenceProviders = this.persistenceProviders.filter(x => x.isAvailable())
|
||||
}
|
||||
|
||||
async prepareNewSession (options: SessionOptions): Promise<SessionOptions> {
|
||||
@@ -220,6 +224,9 @@ export class SessionsService {
|
||||
}
|
||||
|
||||
private getPersistence (): SessionPersistenceProvider {
|
||||
if (!this.config.store.terminal.persistence) {
|
||||
return null
|
||||
}
|
||||
return this.persistenceProviders.find(x => x.id === this.config.store.terminal.persistence) || null
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ export class Cygwin32ShellProvider extends ShellProvider {
|
||||
let cygwinPath = 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) {
|
||||
if (err || !item) {
|
||||
return resolve(null)
|
||||
}
|
||||
resolve(item.value)
|
||||
|
@@ -25,7 +25,7 @@ export class Cygwin64ShellProvider extends ShellProvider {
|
||||
let cygwinPath = await new Promise<string>(resolve => {
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup', arch: 'x64' })
|
||||
reg.get('rootdir', (err, item) => {
|
||||
if (err) {
|
||||
if (err || !item) {
|
||||
return resolve(null)
|
||||
}
|
||||
resolve(item.value)
|
||||
|
@@ -25,7 +25,7 @@ export class GitBashShellProvider extends ShellProvider {
|
||||
let gitBashPath = await new Promise<string>(resolve => {
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\GitForWindows' })
|
||||
reg.get('InstallPath', (err, item) => {
|
||||
if (err) {
|
||||
if (err || !item) {
|
||||
resolve(null)
|
||||
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) {
|
||||
return []
|
||||
}
|
||||
@@ -41,6 +54,7 @@ export class GitBashShellProvider extends ShellProvider {
|
||||
id: 'git-bash',
|
||||
name: 'Git-Bash',
|
||||
command: path.join(gitBashPath, 'bin', 'bash.exe'),
|
||||
args: [ '--login', '-i' ],
|
||||
env: {
|
||||
TERM: 'cygwin',
|
||||
}
|
||||
|
Reference in New Issue
Block a user