added CLI option to paste text into terminal

This commit is contained in:
Eugene Pankov
2018-09-23 16:33:57 +02:00
parent 0545471f3c
commit e71d404c2b
12 changed files with 73 additions and 32 deletions

View File

@@ -1,3 +1,4 @@
import * as fs from 'fs'
import { app } from 'electron' import { app } from 'electron'
export function parseArgs (argv, cwd) { export function parseArgs (argv, cwd) {
@@ -13,11 +14,27 @@ export function parseArgs (argv, cwd) {
.command('run [command...]', 'run a command in the terminal', { .command('run [command...]', 'run a command in the terminal', {
command: { type: 'string' }, command: { type: 'string' },
}) })
.version('v', 'Show version and exit', app.getVersion()) .command('paste [text]', 'paste stdin into the active tab', yargs => {
.alias('d', 'debug') return yargs.option('escape', {
.describe('d', 'Show DevTools on start') alias: 'e',
.alias('h', 'help') type: 'boolean',
.help('h') describe: 'Perform shell escaping'
}).positional('text', {
type: 'string'
})
})
.version('version', '', app.getVersion())
.option('debug', {
alias: 'd',
describe: 'Show DevTools on start',
type: 'boolean'
})
.option('version', {
alias: 'v',
describe: 'Show version and exit',
type: 'boolean'
})
.help('help')
.strict() .strict()
.parse(argv.slice(1)) .parse(argv.slice(1))
} }

View File

@@ -21,7 +21,7 @@
<dict> <dict>
<key>cdhash</key> <key>cdhash</key>
<data> <data>
x6j3FhtlZlqVwCjiTDDdZxRQkDk= DwLo2M9xZ+aZGtMzRCGHhHB/wMY=
</data> </data>
<key>requirement</key> <key>requirement</key>
<string>identifier document and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = V4JSMC46SY</string> <string>identifier document and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = V4JSMC46SY</string>

View File

@@ -59,7 +59,7 @@
<key>ActionParameters</key> <key>ActionParameters</key>
<dict> <dict>
<key>COMMAND_STRING</key> <key>COMMAND_STRING</key>
<string>echo -n $1 | /Applications/Terminus.app/Contents/MacOS/terminus paste --escape</string> <string>/Applications/Terminus.app/Contents/MacOS/terminus paste --escape "$1"</string>
<key>CheckedForUserDefaultShell</key> <key>CheckedForUserDefaultShell</key>
<true/> <true/>
<key>inputMethod</key> <key>inputMethod</key>

View File

@@ -27,6 +27,7 @@
"electron-updater": "^2.8.9", "electron-updater": "^2.8.9",
"ng2-dnd": "^5.0.2", "ng2-dnd": "^5.0.2",
"ngx-perfect-scrollbar": "^6.0.0", "ngx-perfect-scrollbar": "^6.0.0",
"shell-escape": "^0.2.0",
"universal-analytics": "^0.4.17" "universal-analytics": "^0.4.17"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -74,8 +74,8 @@ export class AppService {
this.activeTabChange.next(tab) this.activeTabChange.next(tab)
if (this.activeTab) { if (this.activeTab) {
this.activeTab.emitFocused() this.activeTab.emitFocused()
this.hostApp.setTitle(this.activeTab.title)
} }
this.hostApp.setTitle(this.activeTab.title)
} }
toggleLastTab () { toggleLastTab () {

View File

@@ -1,4 +1,5 @@
import * as path from 'path' import * as path from 'path'
import shellEscape = require('shell-escape')
import { Observable, Subject } from 'rxjs' import { Observable, Subject } from 'rxjs'
import { Injectable, NgZone, EventEmitter } from '@angular/core' import { Injectable, NgZone, EventEmitter } from '@angular/core'
import { ElectronService } from './electron.service' import { ElectronService } from './electron.service'
@@ -25,6 +26,7 @@ export class HostAppService {
private secondInstance = new Subject<void>() private secondInstance = new Subject<void>()
private cliOpenDirectory = new Subject<string>() private cliOpenDirectory = new Subject<string>()
private cliRunCommand = new Subject<string[]>() private cliRunCommand = new Subject<string[]>()
private cliPaste = new Subject<string>()
private configChangeBroadcast = new Subject<void>() private configChangeBroadcast = new Subject<void>()
private logger: Logger private logger: Logger
private windowId: number private windowId: number
@@ -33,6 +35,7 @@ export class HostAppService {
get secondInstance$ (): Observable<void> { return this.secondInstance } get secondInstance$ (): Observable<void> { return this.secondInstance }
get cliOpenDirectory$ (): Observable<string> { return this.cliOpenDirectory } get cliOpenDirectory$ (): Observable<string> { return this.cliOpenDirectory }
get cliRunCommand$ (): Observable<string[]> { return this.cliRunCommand } get cliRunCommand$ (): Observable<string[]> { return this.cliRunCommand }
get cliPaste$ (): Observable<string> { return this.cliPaste }
get configChangeBroadcast$ (): Observable<void> { return this.configChangeBroadcast } get configChangeBroadcast$ (): Observable<void> { return this.configChangeBroadcast }
constructor ( constructor (
@@ -76,6 +79,12 @@ export class HostAppService {
this.cliOpenDirectory.next(path.resolve(cwd, argv.directory)) this.cliOpenDirectory.next(path.resolve(cwd, argv.directory))
} else if (op === 'run') { } else if (op === 'run') {
this.cliRunCommand.next(argv.command) this.cliRunCommand.next(argv.command)
} else if (op === 'paste') {
let text = argv.text
if (argv.escape) {
text = shellEscape([text])
}
this.cliPaste.next(text)
} }
})) }))

View File

@@ -460,6 +460,10 @@ semver@^5.4.1:
version "5.4.1" version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
shell-escape@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/shell-escape/-/shell-escape-0.2.0.tgz#68fd025eb0490b4f567a027f0bf22480b5f84133"
sntp@2.x.x: sntp@2.x.x:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"

View File

@@ -15,30 +15,6 @@ export class ButtonProvider extends ToolbarButtonProvider {
hotkeys: HotkeysService, hotkeys: HotkeysService,
) { ) {
super() super()
hotkeys.matchedHotkey.subscribe(async (hotkey) => {
if (hotkey === 'new-tab') {
terminal.openTab()
}
})
hotkeys.matchedHotkey.subscribe(async (hotkey) => {
if (hotkey === 'new-window') {
hostApp.newWindow()
}
})
hostApp.cliOpenDirectory$.subscribe(async directory => {
if (await fs.exists(directory)) {
if ((await fs.stat(directory)).isDirectory()) {
this.terminal.openTab(null, directory)
}
}
})
hostApp.cliRunCommand$.subscribe(async command => {
this.terminal.openTab({
id: '',
command: command[0],
args: command.slice(1),
}, null, true)
})
if (!electron.remote.process.env.DEV) { if (!electron.remote.process.env.DEV) {
setImmediate(async () => { setImmediate(async () => {
let argv: string[] = electron.remote.process.argv let argv: string[] = electron.remote.process.argv

View File

@@ -1,9 +1,12 @@
import * as fs from 'mz/fs'
import { NgModule } from '@angular/core' import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser' import { BrowserModule } from '@angular/platform-browser'
import { FormsModule } from '@angular/forms' import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap' import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { ToastrModule } from 'ngx-toastr' import { ToastrModule } from 'ngx-toastr'
import TerminusCorePlugin from 'terminus-core' import TerminusCorePlugin from 'terminus-core'
import { HostAppService } from 'terminus-core'
import { ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider, AppService, ConfigService } from 'terminus-core' import { ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider, AppService, ConfigService } from 'terminus-core'
import { SettingsTabProvider } from 'terminus-settings' import { SettingsTabProvider } from 'terminus-settings'
@@ -100,6 +103,7 @@ export default class TerminalModule {
config: ConfigService, config: ConfigService,
hotkeys: HotkeysService, hotkeys: HotkeysService,
terminal: TerminalService, terminal: TerminalService,
hostApp: HostAppService,
) { ) {
let events = [ let events = [
{ {
@@ -130,6 +134,36 @@ export default class TerminalModule {
terminal.openTab() terminal.openTab()
}) })
} }
hotkeys.matchedHotkey.subscribe(async (hotkey) => {
if (hotkey === 'new-tab') {
terminal.openTab()
}
})
hotkeys.matchedHotkey.subscribe(async (hotkey) => {
if (hotkey === 'new-window') {
hostApp.newWindow()
}
})
hostApp.cliOpenDirectory$.subscribe(async directory => {
if (await fs.exists(directory)) {
if ((await fs.stat(directory)).isDirectory()) {
terminal.openTab(null, directory)
}
}
})
hostApp.cliRunCommand$.subscribe(async command => {
terminal.openTab({
id: '',
command: command[0],
args: command.slice(1),
}, null, true)
})
hostApp.cliPaste$.subscribe(text => {
if (app.activeTab instanceof TerminalTabComponent && app.activeTab.session) {
(app.activeTab as TerminalTabComponent).sendInput(text)
}
})
} }
} }