This commit is contained in:
Eugene Pankov
2020-03-01 16:10:45 +01:00
parent fda4d2dcef
commit 04a0a0cc64
81 changed files with 284 additions and 295 deletions

View File

@@ -174,7 +174,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
}
/** @hidden */
ngOnInit () {
ngOnInit (): void {
this.focused$.subscribe(() => {
this.configure()
this.frontend.focus()
@@ -259,7 +259,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
/**
* Feeds input into the active session
*/
sendInput (data: string|Buffer) {
sendInput (data: string|Buffer): void {
if (!(data instanceof Buffer)) {
data = Buffer.from(data, 'utf-8')
}
@@ -272,7 +272,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
/**
* Feeds input into the terminal frontend
*/
write (data: string) {
write (data: string): void {
const percentageMatch = /(^|[^\d])(\d+(\.\d+)?)%([^\d]|$)/.exec(data)
if (percentageMatch) {
const percentage = percentageMatch[3] ? parseFloat(percentageMatch[2]) : parseInt(percentageMatch[2])
@@ -286,7 +286,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.frontend.write(data)
}
paste () {
paste (): void {
let data = this.electron.clipboard.readText() as string
if (this.config.store.terminal.bracketedPaste) {
data = '\x1b[200~' + data + '\x1b[201~'
@@ -318,23 +318,23 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
}
}
zoomIn () {
zoomIn (): void {
this.zoom++
this.frontend.setZoom(this.zoom)
}
zoomOut () {
zoomOut (): void {
this.zoom--
this.frontend.setZoom(this.zoom)
}
resetZoom () {
resetZoom (): void {
this.zoom = 0
this.frontend.setZoom(this.zoom)
}
/** @hidden */
ngOnDestroy () {
ngOnDestroy (): void {
this.frontend.detach(this.content.nativeElement)
this.detachTermContainerHandlers()
this.config.enabledServices(this.decorators).forEach(decorator => {
@@ -351,21 +351,21 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.output.complete()
}
async destroy () {
async destroy (): Promise<void> {
super.destroy()
if (this.session && this.session.open) {
await this.session.destroy()
}
}
protected detachTermContainerHandlers () {
protected detachTermContainerHandlers (): void {
for (const subscription of this.termContainerSubscriptions) {
subscription.unsubscribe()
}
this.termContainerSubscriptions = []
}
protected attachTermContainerHandlers () {
protected attachTermContainerHandlers (): void {
this.detachTermContainerHandlers()
const maybeConfigure = () => {
@@ -437,7 +437,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
]
}
protected attachSessionHandlers () {
protected attachSessionHandlers (): void {
// this.session.output$.bufferTime(10).subscribe((datas) => {
this.session.output$.subscribe(data => {
if (this.enablePassthrough) {

View File

@@ -26,7 +26,7 @@ export abstract class TerminalDecorator {
/**
* Automatically cancel @subscription once detached from @terminal
*/
protected subscribeUntilDetached (terminal: BaseTerminalTabComponent, subscription: Subscription) {
protected subscribeUntilDetached (terminal: BaseTerminalTabComponent, subscription: Subscription): void {
if (!this.smartSubscriptions.has(terminal)) {
this.smartSubscriptions.set(terminal, [])
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import * as fs from 'mz/fs'
import { Injectable } from '@angular/core'
import { ToolbarButtonProvider, ToolbarButton, ElectronService } from 'terminus-core'

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Observable } from 'rxjs'
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
import { exec } from 'mz/child_process'

View File

@@ -15,7 +15,7 @@ export class ColorPickerComponent {
@ViewChild('input') input
isOpen: boolean
open () {
open (): void {
setImmediate(() => {
this.popover.open()
setImmediate(() => {
@@ -25,7 +25,7 @@ export class ColorPickerComponent {
})
}
@HostListener('document:click', ['$event']) onOutsideClick ($event) {
@HostListener('document:click', ['$event']) onOutsideClick ($event: MouseEvent): void {
if (!this.isOpen) {
return
}
@@ -40,7 +40,7 @@ export class ColorPickerComponent {
}
}
onChange () {
onChange (): void {
this.modelChange.emit(this.model)
}
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { UACService } from '../services/uac.service'

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component, Output, Input } from '@angular/core'
import { Subject } from 'rxjs'

View File

@@ -21,19 +21,19 @@ export class SearchPanelComponent {
private toastr: ToastrService,
) { }
onQueryChange () {
onQueryChange (): void {
this.notFound = false
this.findNext(true)
}
findNext (incremental = false) {
findNext (incremental = false): void {
if (!this.frontend.findNext(this.query, { ...this.options, incremental: incremental || undefined })) {
this.notFound = true
this.toastr.error('Not found')
}
}
findPrevious () {
findPrevious (): void {
if (!this.frontend.findPrevious(this.query, this.options)) {
this.notFound = true
this.toastr.error('Not found')

View File

@@ -37,19 +37,19 @@ export class ShellSettingsTabComponent {
this.isConPTYStable = isWindowsBuild(WIN_BUILD_CONPTY_STABLE)
}
async ngOnInit () {
async ngOnInit (): void {
this.shells = await this.terminalService.shells$.toPromise()
}
ngOnDestroy () {
ngOnDestroy (): void {
this.configSubscription.unsubscribe()
}
async reload () {
async reload (): void {
this.profiles = await this.terminalService.getProfiles(true)
}
pickWorkingDirectory () {
pickWorkingDirectory (): void {
const shell = this.shells.find(x => x.id === this.config.store.terminal.shell)
if (!shell) {
return
@@ -66,7 +66,7 @@ export class ShellSettingsTabComponent {
}
}
newProfile (shell: Shell) {
newProfile (shell: Shell): void {
const profile: Profile = {
name: shell.name || '',
sessionOptions: this.terminalService.optionsFromShell(shell),
@@ -76,7 +76,7 @@ export class ShellSettingsTabComponent {
this.reload()
}
editProfile (profile: Profile) {
editProfile (profile: Profile): void {
const modal = this.ngbModal.open(EditProfileModalComponent)
modal.componentInstance.profile = Object.assign({}, profile)
modal.result.then(result => {
@@ -85,7 +85,7 @@ export class ShellSettingsTabComponent {
})
}
deleteProfile (profile: Profile) {
deleteProfile (profile: Profile): void {
this.config.store.terminal.profiles = this.config.store.terminal.profiles.filter(x => x !== profile)
this.config.save()
this.reload()

View File

@@ -13,7 +13,7 @@ export class TerminalSettingsTabComponent {
private terminal: TerminalService,
) { }
openWSLVolumeMixer () {
openWSLVolumeMixer (): void {
this.electron.shell.openItem('sndvol.exe')
this.terminal.openTab({
name: '',

View File

@@ -24,7 +24,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
super(injector)
}
ngOnInit () {
ngOnInit (): void {
this.logger = this.log.create('terminalTab')
this.session = new Session(this.config)
@@ -51,7 +51,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
super.ngOnInit()
}
initializeSession (columns: number, rows: number) {
initializeSession (columns: number, rows: number): void {
this.sessions.addSession(
this.session,
Object.assign({}, this.sessionOptions, {
@@ -101,7 +101,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
)).response === 1
}
ngOnDestroy () {
ngOnDestroy (): void {
this.homeEndSubscription.unsubscribe()
super.ngOnDestroy()
this.session.destroy()

View File

@@ -61,7 +61,7 @@ export class DebugDecorator extends TerminalDecorator {
})
}
async loadFile (): Promise<string|null> {
private async loadFile (): Promise<string|null> {
const result = await this.electron.dialog.showOpenDialog(
this.hostApp.getWindow(),
{
@@ -75,7 +75,7 @@ export class DebugDecorator extends TerminalDecorator {
return null
}
async saveFile (content: string, name: string) {
private async saveFile (content: string, name: string) {
const result = await this.electron.dialog.showSaveDialog(
this.hostApp.getWindow(),
{
@@ -87,21 +87,21 @@ export class DebugDecorator extends TerminalDecorator {
}
}
doSaveState (terminal: TerminalTabComponent) {
private doSaveState (terminal: TerminalTabComponent) {
this.saveFile(terminal.frontend.saveState(), 'state.txt')
}
async doCopyState (terminal: TerminalTabComponent) {
private async doCopyState (terminal: TerminalTabComponent) {
const data = '```' + JSON.stringify(terminal.frontend.saveState()) + '```'
this.electron.clipboard.writeText(data)
}
async doLoadState (terminal: TerminalTabComponent) {
private async doLoadState (terminal: TerminalTabComponent) {
const data = await this.loadFile()
terminal.frontend.restoreState(data)
}
async doPasteState (terminal: TerminalTabComponent) {
private async doPasteState (terminal: TerminalTabComponent) {
let data = this.electron.clipboard.readText()
if (data) {
if (data.startsWith('`')) {
@@ -111,23 +111,23 @@ export class DebugDecorator extends TerminalDecorator {
}
}
doSaveOutput (buffer: string) {
private doSaveOutput (buffer: string) {
this.saveFile(buffer, 'output.txt')
}
async doCopyOutput (buffer: string) {
private async doCopyOutput (buffer: string) {
const data = '```' + JSON.stringify(buffer) + '```'
this.electron.clipboard.writeText(data)
}
async doLoadOutput (terminal: TerminalTabComponent) {
private async doLoadOutput (terminal: TerminalTabComponent) {
const data = await this.loadFile()
if (data) {
terminal.frontend.write(data)
}
}
async doPasteOutput (terminal: TerminalTabComponent) {
private async doPasteOutput (terminal: TerminalTabComponent) {
let data = this.electron.clipboard.readText()
if (data) {
if (data.startsWith('`')) {

View File

@@ -19,7 +19,7 @@ export class PathDropDecorator extends TerminalDecorator {
})
}
injectPath (terminal: TerminalTabComponent, path: string) {
private injectPath (terminal: TerminalTabComponent, path: string) {
if (path.includes(' ')) {
path = `"${path}"`
}

View File

@@ -68,7 +68,7 @@ export class ZModemDecorator extends TerminalDecorator {
})
}
async process (terminal, detection) {
private async process (terminal, detection): Promise<void> {
this.showMessage(terminal, colors.bgBlue.black(' ZMODEM ') + ' Session started')
this.showMessage(terminal, '------------------------')

View File

@@ -76,5 +76,5 @@ export abstract class Frontend {
abstract findPrevious (term: string, searchOptions?: SearchOptions): boolean
abstract saveState (): any
abstract restoreState (state: any): void
abstract restoreState (state: string): void
}

View File

@@ -13,7 +13,7 @@ export class HTermFrontend extends Frontend {
private configuredBackgroundColor = 'transparent'
private zoom = 0
attach (host: HTMLElement) {
attach (host: HTMLElement): void {
if (!this.initialized) {
this.init()
this.initialized = true
@@ -29,15 +29,15 @@ export class HTermFrontend extends Frontend {
return this.term.getSelectionText()
}
copySelection () {
copySelection (): void {
this.term.copySelectionToClipboard()
}
clearSelection () {
clearSelection (): void {
this.term.getDocument().getSelection().removeAllRanges()
}
focus () {
focus (): void {
setTimeout(() => {
this.term.scrollPort_.resize()
this.term.scrollPort_.focus()
@@ -168,7 +168,7 @@ export class HTermFrontend extends Frontend {
saveState (): any { }
// eslint-disable-next-line @typescript-eslint/no-empty-function
restoreState (_state: any): void { }
restoreState (_state: string): void { }
private setFontSize () {
const size = this.configuredFontSize * Math.pow(1.1, this.zoom)
@@ -262,7 +262,7 @@ export class HTermFrontend extends Frontend {
// Drop whitespace at the end of selection
const range = selection.getRangeAt(0)
if (range.endOffset > 0 && range.endContainer.nodeType === 3 && range.endContainer.textContent !== '') {
while (/[\s\S]+\s$/.test(range.endContainer.textContent.substr(0,range.endOffset))) {
while (/[\s\S]+\s$/.test(range.endContainer.textContent.substr(0, range.endOffset))) {
range.setEnd(range.endContainer, range.endOffset - 1)
}
}

View File

@@ -259,7 +259,7 @@ export class XTermFrontend extends Frontend {
return this.serializeAddon.serialize(1000)
}
restoreState (state: any): void {
restoreState (state: string): void {
this.xterm.write(state)
}

View File

@@ -1,18 +1,18 @@
import { Injectable } from '@angular/core'
import { TabRecoveryProvider, RecoveredTab } from 'terminus-core'
import { TabRecoveryProvider, RecoveredTab, RecoveryToken } from 'terminus-core'
import { TerminalTabComponent } from './components/terminalTab.component'
/** @hidden */
@Injectable()
export class RecoveryProvider extends TabRecoveryProvider {
async recover (recoveryToken: any): Promise<RecoveredTab|null> {
if (recoveryToken && recoveryToken.type === 'app:terminal-tab') {
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
if (recoveryToken?.type === 'app:terminal-tab') {
return {
type: TerminalTabComponent,
options: {
sessionOptions: recoveryToken.sessionOptions,
savedState: recoveryToken.savedState,
sessionOptions: recoveryToken['sessionOptions'],
savedState: recoveryToken['savedState'],
},
}
}

View File

@@ -17,7 +17,7 @@ export class DockMenuService {
config.changed$.subscribe(() => this.update())
}
update () {
update (): void {
if (this.hostApp.platform === Platform.Windows) {
this.electron.app.setJumpList(this.config.store.terminal.profiles.length ? [{
type: 'custom',

View File

@@ -52,7 +52,7 @@ export abstract class BaseSession {
get closed$ (): Observable<void> { return this.closed }
get destroyed$ (): Observable<void> { return this.destroyed }
emitOutput (data: Buffer) {
emitOutput (data: Buffer): void {
if (!this.initialDataBufferReleased) {
this.initialDataBuffer = Buffer.concat([this.initialDataBuffer, data])
} else {
@@ -61,7 +61,7 @@ export abstract class BaseSession {
}
}
releaseInitialDataBuffer () {
releaseInitialDataBuffer (): void {
this.initialDataBufferReleased = true
this.output.next(this.initialDataBuffer.toString())
this.binaryOutput.next(this.initialDataBuffer)
@@ -99,7 +99,7 @@ export class Session extends BaseSession {
super()
}
start (options: SessionOptions) {
start (options: SessionOptions): void {
this.name = options.name || ''
const env = {
@@ -182,31 +182,13 @@ export class Session extends BaseSession {
this.pauseAfterExit = options.pauseAfterExit || false
}
processOSC1337 (data: Buffer) {
if (data.includes(OSC1337Prefix)) {
const preData = data.subarray(0, data.indexOf(OSC1337Prefix))
let params = data.subarray(data.indexOf(OSC1337Prefix) + OSC1337Prefix.length)
const postData = params.subarray(params.indexOf(OSC1337Suffix) + OSC1337Suffix.length)
const paramString = params.subarray(0, params.indexOf(OSC1337Suffix)).toString()
if (paramString.startsWith('CurrentDir=')) {
this.reportedCWD = paramString.split('=')[1]
if (this.reportedCWD.startsWith('~')) {
this.reportedCWD = os.homedir() + this.reportedCWD.substring(1)
}
data = Buffer.concat([preData, postData])
}
}
return data
}
resize (columns, rows) {
resize (columns: number, rows: number): void {
if (this.pty._writable) {
this.pty.resize(columns, rows)
}
}
write (data: Buffer) {
write (data: Buffer): void {
if (this.open) {
if (this.pty._writable) {
this.pty.write(data)
@@ -216,7 +198,7 @@ export class Session extends BaseSession {
}
}
kill (signal?: string) {
kill (signal?: string): void {
this.pty.kill(signal)
}
@@ -323,6 +305,24 @@ export class Session extends BaseSession {
this.guessedCWD = match[0]
}
}
private processOSC1337 (data: Buffer) {
if (data.includes(OSC1337Prefix)) {
const preData = data.subarray(0, data.indexOf(OSC1337Prefix))
let params = data.subarray(data.indexOf(OSC1337Prefix) + OSC1337Prefix.length)
const postData = params.subarray(params.indexOf(OSC1337Suffix) + OSC1337Suffix.length)
const paramString = params.subarray(0, params.indexOf(OSC1337Suffix)).toString()
if (paramString.startsWith('CurrentDir=')) {
this.reportedCWD = paramString.split('=')[1]
if (this.reportedCWD.startsWith('~')) {
this.reportedCWD = os.homedir() + this.reportedCWD.substring(1)
}
data = Buffer.concat([preData, postData])
}
}
return data
}
}
/** @hidden */
@@ -339,7 +339,7 @@ export class SessionsService {
this.logger = log.create('sessions')
}
addSession (session: BaseSession, options: SessionOptions) {
addSession (session: BaseSession, options: SessionOptions): BaseSession {
this.lastID++
options.name = `session-${this.lastID}`
session.start(options)

View File

@@ -137,7 +137,7 @@ export class CopyPasteContextMenu extends TabContextMenuItemProvider {
return [
{
label: 'Copy',
click: () => {
click: (): void => {
this.zone.run(() => {
setTimeout(() => {
(tab as BaseTerminalTabComponent).frontend.copySelection()
@@ -148,7 +148,7 @@ export class CopyPasteContextMenu extends TabContextMenuItemProvider {
},
{
label: 'Paste',
click: () => {
click: (): void => {
this.zone.run(() => (tab as BaseTerminalTabComponent).paste())
},
},