diff --git a/package.json b/package.json index 96235602..b41cd999 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "ts-loader": "^9.2.3", "tslib": "^2.3.0", "typedoc": "^0.21.4", + "shell-quote": "^1.7.2", "typescript": "^4.3.5", "url-loader": "^4.1.1", "val-loader": "4.0.0", diff --git a/tabby-local/package.json b/tabby-local/package.json index 9f1168ad..367978a5 100644 --- a/tabby-local/package.json +++ b/tabby-local/package.json @@ -22,13 +22,11 @@ }, "devDependencies": { "@types/deep-equal": "^1.0.0", - "@types/shell-escape": "^0.2.0", "ansi-colors": "^4.1.1", "dataurl": "0.1.0", "deep-equal": "2.0.5", "ps-node": "^0.1.6", "runes": "^0.4.2", - "shell-escape": "^0.2.0", "utils-decorators": "^1.8.3" }, "peerDependencies": { diff --git a/tabby-local/src/components/commandLineEditor.component.pug b/tabby-local/src/components/commandLineEditor.component.pug new file mode 100644 index 00000000..901743bc --- /dev/null +++ b/tabby-local/src/components/commandLineEditor.component.pug @@ -0,0 +1,41 @@ +ng-container(*ngIf='!argvMode') + .form-group + label Command line + .input-group + .input-group-prepend + button.btn.btn-secondary((click)='switchToArgv()', title='Switch to split arguments') + i.fas.fa-fw.fa-caret-right + input.form-control.text-monospace( + [(ngModel)]='command', + (ngModelChange)='parseCommand()' + ) + +ng-container(*ngIf='argvMode') + .form-group + label Program + .input-group + .input-group-prepend + button.btn.btn-secondary((click)='switchToCommand()', title='Switch to a single-line command') + i.fas.fa-fw.fa-caret-down + input.form-control.text-monospace( + type='text', + [(ngModel)]='_model.command', + ) + + .form-group + label Arguments + .input-group( + *ngFor='let arg of _model.args; index as i; trackBy: trackByIndex', + ) + input.form-control.text-monospace( + type='text', + [(ngModel)]='_model.args[i]', + ) + .input-group-append + button.btn.btn-secondary((click)='_model.args.splice(i, 1)') + i.fas.fa-fw.fa-trash + + .mt-2 + button.btn.btn-secondary((click)='_model.args.push("")') + i.fas.fa-plus.mr-2 + | Add diff --git a/tabby-local/src/components/commandLineEditor.component.ts b/tabby-local/src/components/commandLineEditor.component.ts new file mode 100644 index 00000000..f4a81f2e --- /dev/null +++ b/tabby-local/src/components/commandLineEditor.component.ts @@ -0,0 +1,50 @@ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import * as shellQuote from 'shell-quote' +import { Component, Input } from '@angular/core' +import { SessionOptions } from '../api' + +/** @hidden */ +@Component({ + selector: 'command-line-editor', + template: require('./commandLineEditor.component.pug'), +}) +export class CommandLineEditorComponent { + @Input() argvMode = false + @Input() _model: SessionOptions + command = '' + + @Input() get model (): SessionOptions { + return this._model + } + + set model (value: SessionOptions) { + this._model = value + this.updateCommand() + } + + switchToCommand () { + this.updateCommand() + this.argvMode = false + } + + switchToArgv () { + this.argvMode = true + } + + parseCommand () { + const args = shellQuote.parse(this.command) + this.model.command = args[0] ?? '' + this.model.args = args.slice(1) + } + + updateCommand () { + this.command = shellQuote.quote([ + this.model.command, + ...this.model.args ?? [], + ]) + } + + trackByIndex (index) { + return index + } +} diff --git a/tabby-local/src/components/environmentEditor.component.pug b/tabby-local/src/components/environmentEditor.component.pug index f82f2793..cd804c8a 100644 --- a/tabby-local/src/components/environmentEditor.component.pug +++ b/tabby-local/src/components/environmentEditor.component.pug @@ -1,12 +1,12 @@ .mb-2.d-flex.align-items-center(*ngFor='let pair of vars') .input-group - input.form-control.w-25([(ngModel)]='pair.key', (blur)='emitUpdate()', placeholder='Variable name') + input.form-control.w-25.text-monospace([(ngModel)]='pair.key', (blur)='emitUpdate()', placeholder='Variable name') .input-group-append .input-group-text = - input.form-control.w-50([(ngModel)]='pair.value', (blur)='emitUpdate()', placeholder='Value') + input.form-control.w-50.text-monospace([(ngModel)]='pair.value', (blur)='emitUpdate()', placeholder='Value') .input-group-append button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)') - i.fas.fa-trash + i.fas.fa-fw.fa-trash button.btn.btn-secondary((click)='addEnvironmentVar()') i.fas.fa-plus.mr-2 diff --git a/tabby-local/src/components/localProfileSettings.component.pug b/tabby-local/src/components/localProfileSettings.component.pug index 11cd89a6..9002eca5 100644 --- a/tabby-local/src/components/localProfileSettings.component.pug +++ b/tabby-local/src/components/localProfileSettings.component.pug @@ -1,27 +1,4 @@ -.form-group - label Command - input.form-control( - type='text', - [(ngModel)]='profile.options.command', - ) - -.form-group - label Arguments - .input-group( - *ngFor='let arg of profile.options.args; index as i; trackBy: trackByIndex', - ) - input.form-control( - type='text', - [(ngModel)]='profile.options.args[i]', - ) - .input-group-append - button.btn.btn-secondary((click)='profile.options.args.splice(i, 1)') - i.fas.fa-trash - - .mt-2 - button.btn.btn-secondary((click)='profile.options.args.push("")') - i.fas.fa-plus.mr-2 - | Add +command-line-editor([model]='profile.options') .form-line(*ngIf='uac.isAvailable') .header diff --git a/tabby-local/src/components/localProfileSettings.component.ts b/tabby-local/src/components/localProfileSettings.component.ts index a8043f77..8542de22 100644 --- a/tabby-local/src/components/localProfileSettings.component.ts +++ b/tabby-local/src/components/localProfileSettings.component.ts @@ -40,8 +40,4 @@ export class LocalProfileSettingsComponent implements ProfileSettingsComponent