mirror of
https://github.com/Eugeny/tabby.git
synced 2024-11-28 05:36:31 +03:00
Merge branch 'master' of github.com:Eugeny/terminus
This commit is contained in:
commit
57227ae6ce
@ -17,7 +17,7 @@
|
||||
* Doesn't choke on fast-flowing outputs
|
||||
* Tab persistence on macOS and Linux
|
||||
* Proper shell-like experience on Windows including tab completion (thanks, Clink!)
|
||||
* CMD, PowerShell and Bash on Windows support
|
||||
* CMD, PowerShell, Cygwin, Git-Bash and Bash on Windows support
|
||||
|
||||
---
|
||||
|
||||
|
@ -16,5 +16,4 @@ exports.builtinPlugins = [
|
||||
'terminus-plugin-manager',
|
||||
]
|
||||
exports.nativeModules = ['node-pty', 'font-manager']
|
||||
exports.version = appInfo.version
|
||||
exports.electronVersion = pkgInfo.devDependencies.electron
|
||||
|
@ -40,12 +40,12 @@ export class DockingService {
|
||||
newBounds.height = Math.round(fill * display.bounds.height)
|
||||
}
|
||||
if (dockSide === 'right') {
|
||||
newBounds.x = display.bounds.x + display.bounds.width * (1.0 - fill)
|
||||
newBounds.x = display.bounds.x + Math.round(display.bounds.width * (1.0 - fill))
|
||||
} else {
|
||||
newBounds.x = display.bounds.x
|
||||
}
|
||||
if (dockSide === 'bottom') {
|
||||
newBounds.y = display.bounds.y + display.bounds.height * (1.0 - fill)
|
||||
newBounds.y = display.bounds.y + Math.round(display.bounds.height * (1.0 - fill))
|
||||
} else {
|
||||
newBounds.y = display.bounds.y
|
||||
}
|
||||
|
@ -109,17 +109,17 @@ ngb-tabset.vertical(type='tabs')
|
||||
label Display on
|
||||
br
|
||||
div(
|
||||
'[(ngModel)]'='config.store.appearance.dockScreen'
|
||||
'(ngModelChange)'='config.save(); docking.dock()'
|
||||
[(ngModel)]='config.store.appearance.dockScreen',
|
||||
(ngModelChange)='config.save(); docking.dock()',
|
||||
ngbRadioGroup
|
||||
)
|
||||
label.btn.btn-secondary
|
||||
input(
|
||||
type='radio',
|
||||
[value]='"current"'
|
||||
value='current'
|
||||
)
|
||||
| Current
|
||||
label.btn.btn-secondary(*ngFor='let screen of docking.getScreens()')
|
||||
label.btn.btn-secondary(*ngFor='let screen of screens')
|
||||
input(
|
||||
type='radio',
|
||||
[value]='screen.id'
|
||||
|
@ -14,6 +14,7 @@ import { SettingsTabProvider } from '../api'
|
||||
export class SettingsTabComponent extends BaseTabComponent {
|
||||
hotkeyFilter = ''
|
||||
private hotkeyDescriptions: IHotkeyDescription[]
|
||||
private screens
|
||||
|
||||
constructor (
|
||||
public config: ConfigService,
|
||||
@ -28,6 +29,7 @@ export class SettingsTabComponent extends BaseTabComponent {
|
||||
this.hotkeyDescriptions = hotkeyProviders.map(x => x.hotkeys).reduce((a, b) => a.concat(b))
|
||||
this.title$.next('Settings')
|
||||
this.scrollable = true
|
||||
this.screens = this.docking.getScreens()
|
||||
}
|
||||
|
||||
getRecoveryToken (): any {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import * as path from 'path'
|
||||
import { exec } from 'mz/child_process'
|
||||
import * as fs from 'mz/fs'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HotkeysService, ToolbarButtonProvider, IToolbarButton, AppService, ConfigService, ElectronService } from 'terminus-core'
|
||||
import { HotkeysService, ToolbarButtonProvider, IToolbarButton, AppService, ConfigService, ElectronService, HostAppService, Platform } from 'terminus-core'
|
||||
|
||||
import { SessionsService } from './services/sessions.service'
|
||||
import { TerminalTabComponent } from './components/terminalTab.component'
|
||||
@ -12,6 +14,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
||||
private sessions: SessionsService,
|
||||
private config: ConfigService,
|
||||
private electron: ElectronService,
|
||||
private hostApp: HostAppService,
|
||||
hotkeys: HotkeysService,
|
||||
) {
|
||||
super()
|
||||
@ -43,6 +46,22 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
||||
'inject',
|
||||
]
|
||||
}
|
||||
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(':')[5]
|
||||
}
|
||||
}
|
||||
if (this.hostApp.platform === Platform.macOS) {
|
||||
let shellEntry = (await exec(`dscl . -read /Users/${process.env.LOGNAME} UserShell`))[0].toString()
|
||||
command = shellEntry.split(':')[1].trim()
|
||||
}
|
||||
}
|
||||
let sessionOptions = await this.sessions.prepareNewSession({ command, args, cwd })
|
||||
this.app.openNewTab(
|
||||
TerminalTabComponent,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Observable } from 'rxjs'
|
||||
import * as fs from 'fs-promise'
|
||||
import * as fs from 'mz/fs'
|
||||
import * as path from 'path'
|
||||
import { exec } from 'mz/child_process'
|
||||
const equal = require('deep-equal')
|
||||
@ -59,16 +59,20 @@ export class TerminalSettingsTabComponent {
|
||||
{ name: 'CMD (stock)', command: 'cmd.exe' },
|
||||
{ name: 'PowerShell', command: 'powershell.exe' },
|
||||
]
|
||||
|
||||
// Detect whether BoW is installed
|
||||
const wslPath = `${process.env.windir}\\system32\\bash.exe`
|
||||
if (await fs.exists(wslPath)) {
|
||||
this.shells.push({ name: 'Bash on Windows', command: wslPath })
|
||||
}
|
||||
|
||||
// Detect Cygwin
|
||||
let cygwinPath = await new Promise<string>(resolve => {
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\Cygwin\\setup' })
|
||||
reg.get('rootdir', (err, item) => {
|
||||
if (err) {
|
||||
resolve(null)
|
||||
return
|
||||
}
|
||||
resolve(item.value)
|
||||
})
|
||||
@ -76,13 +80,29 @@ export class TerminalSettingsTabComponent {
|
||||
if (cygwinPath) {
|
||||
this.shells.push({ name: 'Cygwin', command: path.join(cygwinPath, 'bin', 'bash.exe') })
|
||||
}
|
||||
|
||||
// Detect Git-Bash
|
||||
let gitBashPath = await new Promise<string>(resolve => {
|
||||
let reg = new Registry({ hive: Registry.HKLM, key: '\\Software\\GitForWindows' })
|
||||
reg.get('InstallPath', (err, item) => {
|
||||
if (err) {
|
||||
resolve(null)
|
||||
return
|
||||
}
|
||||
resolve(item.value)
|
||||
})
|
||||
})
|
||||
if (gitBashPath) {
|
||||
this.shells.push({ name: 'Git-Bash', command: path.join(gitBashPath, 'bin', 'bash.exe') })
|
||||
}
|
||||
}
|
||||
if (this.hostApp.platform === Platform.Linux || this.hostApp.platform === Platform.macOS) {
|
||||
this.shells = (await fs.readFile('/etc/shells', 'utf-8'))
|
||||
this.shells = [{ name: 'Default shell', command: '~default-shell~' }]
|
||||
this.shells = this.shells.concat((await fs.readFile('/etc/shells', { encoding: 'utf-8' }))
|
||||
.split('\n')
|
||||
.map(x => x.trim())
|
||||
.filter(x => x && !x.startsWith('#'))
|
||||
.map(x => ({ name: x, command: x }))
|
||||
.map(x => ({ name: x, command: x })))
|
||||
}
|
||||
this.colorSchemes = (await Promise.all(this.colorSchemeProviders.map(x => x.getSchemes()))).reduce((a, b) => a.concat(b))
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
[Platform.macOS]: {
|
||||
terminal: {
|
||||
font: 'Menlo',
|
||||
shell: '/bin/zsh',
|
||||
shell: '~default-shell~',
|
||||
},
|
||||
hotkeys: {
|
||||
'new-tab': [
|
||||
@ -67,7 +67,7 @@ export class TerminalConfigProvider extends ConfigProvider {
|
||||
[Platform.Linux]: {
|
||||
terminal: {
|
||||
font: 'Liberation Mono',
|
||||
shell: '/bin/bash',
|
||||
shell: '~default-shell~',
|
||||
},
|
||||
hotkeys: {
|
||||
'new-tab': [
|
||||
|
@ -100,7 +100,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, '-T', 'xterm-256color', '--', options.command].concat(options.args || [])
|
||||
let args = ['-d', '-m', '-c', configPath, '-U', '-S', recoveryId, '-T', 'xterm-256color', '--', '-' + options.command].concat(options.args || [])
|
||||
this.logger.debug('Spawning screen with', args.join(' '))
|
||||
await spawn('screen', args, {
|
||||
cwd: options.cwd,
|
||||
|
@ -28,10 +28,6 @@ export class Session {
|
||||
...options.env,
|
||||
TERM: 'xterm-256color',
|
||||
}
|
||||
if (options.command.includes(' ')) {
|
||||
options.args = ['-c', options.command]
|
||||
options.command = 'sh'
|
||||
}
|
||||
this.pty = nodePTY.spawn(options.command, options.args || [], {
|
||||
name: 'xterm-256color',
|
||||
cols: options.width || 80,
|
||||
|
Loading…
Reference in New Issue
Block a user