diff --git a/app/lib/cli.ts b/app/lib/cli.ts index c5f36643..6e7294c0 100644 --- a/app/lib/cli.ts +++ b/app/lib/cli.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs' import { app } from 'electron' export function parseArgs (argv, cwd) { @@ -13,11 +14,27 @@ export function parseArgs (argv, cwd) { .command('run [command...]', 'run a command in the terminal', { command: { type: 'string' }, }) - .version('v', 'Show version and exit', app.getVersion()) - .alias('d', 'debug') - .describe('d', 'Show DevTools on start') - .alias('h', 'help') - .help('h') + .command('paste [text]', 'paste stdin into the active tab', yargs => { + return yargs.option('escape', { + alias: 'e', + type: 'boolean', + 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() .parse(argv.slice(1)) } diff --git a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeDirectory b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeDirectory index 11741774..96e83191 100644 Binary files a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeDirectory and b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeDirectory differ diff --git a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeRequirements-1 b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeRequirements-1 index ecfbb68b..c700c2e3 100644 Binary files a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeRequirements-1 and b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeRequirements-1 differ diff --git a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeResources b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeResources index 1bed7a73..539527c3 100644 --- a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeResources +++ b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeResources @@ -21,7 +21,7 @@ cdhash - x6j3FhtlZlqVwCjiTDDdZxRQkDk= + DwLo2M9xZ+aZGtMzRCGHhHB/wMY= requirement 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 diff --git a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeSignature b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeSignature index 9a3b9467..0350c333 100644 Binary files a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeSignature and b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/_CodeSignature/CodeSignature differ diff --git a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/document.wflow b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/document.wflow index 7d35eafe..3ad088c6 100644 --- a/extras/automator-workflows/Paste path into Terminus.workflow/Contents/document.wflow +++ b/extras/automator-workflows/Paste path into Terminus.workflow/Contents/document.wflow @@ -59,7 +59,7 @@ ActionParameters COMMAND_STRING - echo -n $1 | /Applications/Terminus.app/Contents/MacOS/terminus paste --escape + /Applications/Terminus.app/Contents/MacOS/terminus paste --escape "$1" CheckedForUserDefaultShell inputMethod diff --git a/terminus-core/package.json b/terminus-core/package.json index 5020c5df..06a6c2ab 100644 --- a/terminus-core/package.json +++ b/terminus-core/package.json @@ -27,6 +27,7 @@ "electron-updater": "^2.8.9", "ng2-dnd": "^5.0.2", "ngx-perfect-scrollbar": "^6.0.0", + "shell-escape": "^0.2.0", "universal-analytics": "^0.4.17" }, "peerDependencies": { diff --git a/terminus-core/src/services/app.service.ts b/terminus-core/src/services/app.service.ts index d275b85b..6784a785 100644 --- a/terminus-core/src/services/app.service.ts +++ b/terminus-core/src/services/app.service.ts @@ -74,8 +74,8 @@ export class AppService { this.activeTabChange.next(tab) if (this.activeTab) { this.activeTab.emitFocused() + this.hostApp.setTitle(this.activeTab.title) } - this.hostApp.setTitle(this.activeTab.title) } toggleLastTab () { diff --git a/terminus-core/src/services/hostApp.service.ts b/terminus-core/src/services/hostApp.service.ts index 495c5d6c..9a3a6cfa 100644 --- a/terminus-core/src/services/hostApp.service.ts +++ b/terminus-core/src/services/hostApp.service.ts @@ -1,4 +1,5 @@ import * as path from 'path' +import shellEscape = require('shell-escape') import { Observable, Subject } from 'rxjs' import { Injectable, NgZone, EventEmitter } from '@angular/core' import { ElectronService } from './electron.service' @@ -25,6 +26,7 @@ export class HostAppService { private secondInstance = new Subject() private cliOpenDirectory = new Subject() private cliRunCommand = new Subject() + private cliPaste = new Subject() private configChangeBroadcast = new Subject() private logger: Logger private windowId: number @@ -33,6 +35,7 @@ export class HostAppService { get secondInstance$ (): Observable { return this.secondInstance } get cliOpenDirectory$ (): Observable { return this.cliOpenDirectory } get cliRunCommand$ (): Observable { return this.cliRunCommand } + get cliPaste$ (): Observable { return this.cliPaste } get configChangeBroadcast$ (): Observable { return this.configChangeBroadcast } constructor ( @@ -76,6 +79,12 @@ export class HostAppService { this.cliOpenDirectory.next(path.resolve(cwd, argv.directory)) } else if (op === 'run') { this.cliRunCommand.next(argv.command) + } else if (op === 'paste') { + let text = argv.text + if (argv.escape) { + text = shellEscape([text]) + } + this.cliPaste.next(text) } })) diff --git a/terminus-core/yarn.lock b/terminus-core/yarn.lock index c3dcb948..a9678215 100644 --- a/terminus-core/yarn.lock +++ b/terminus-core/yarn.lock @@ -460,6 +460,10 @@ semver@^5.4.1: version "5.4.1" 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: version "2.1.0" resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" diff --git a/terminus-terminal/src/buttonProvider.ts b/terminus-terminal/src/buttonProvider.ts index 8de05816..b37b39bb 100644 --- a/terminus-terminal/src/buttonProvider.ts +++ b/terminus-terminal/src/buttonProvider.ts @@ -15,30 +15,6 @@ export class ButtonProvider extends ToolbarButtonProvider { hotkeys: HotkeysService, ) { 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) { setImmediate(async () => { let argv: string[] = electron.remote.process.argv diff --git a/terminus-terminal/src/index.ts b/terminus-terminal/src/index.ts index 7bde6ecc..a71c815d 100644 --- a/terminus-terminal/src/index.ts +++ b/terminus-terminal/src/index.ts @@ -1,9 +1,12 @@ +import * as fs from 'mz/fs' + import { NgModule } from '@angular/core' import { BrowserModule } from '@angular/platform-browser' import { FormsModule } from '@angular/forms' import { NgbModule } from '@ng-bootstrap/ng-bootstrap' import { ToastrModule } from 'ngx-toastr' import TerminusCorePlugin from 'terminus-core' +import { HostAppService } from 'terminus-core' import { ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider, AppService, ConfigService } from 'terminus-core' import { SettingsTabProvider } from 'terminus-settings' @@ -100,6 +103,7 @@ export default class TerminalModule { config: ConfigService, hotkeys: HotkeysService, terminal: TerminalService, + hostApp: HostAppService, ) { let events = [ { @@ -130,6 +134,36 @@ export default class TerminalModule { 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) + } + }) } }