Просмотр исходного кода

added hotkey to focus all panes (fixes #722)

Eugene Pankov 5 лет назад
Родитель
Сommit
b3fcfd0c8b

+ 11 - 7
terminus-core/src/components/splitTab.component.ts

@@ -157,6 +157,10 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
     /** @hidden */
     _spanners: SplitSpannerInfo[] = []
 
+    /** @hidden */
+    _allFocusMode = false
+
+    /** @hidden */
     private focusedTab: BaseTabComponent
     private maximizedTab: BaseTabComponent|null = null
     private hotkeysSubscription: Subscription
@@ -480,6 +484,12 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
         }
     }
 
+    layout () {
+        this.root.normalize()
+        this._spanners = []
+        this.layoutInternal(this.root, 0, 0, 100, 100)
+    }
+
     private attachTabView (tab: BaseTabComponent) {
         const ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any> // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
         this.viewRefs.set(tab, ref)
@@ -505,12 +515,6 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
         }
     }
 
-    private layout () {
-        this.root.normalize()
-        this._spanners = []
-        this.layoutInternal(this.root, 0, 0, 100, 100)
-    }
-
     private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
         const size = root.orientation === 'v' ? h : w
         const sizes = root.ratios.map(x => x * size)
@@ -535,7 +539,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
                     element.classList.toggle('child', true)
                     element.classList.toggle('maximized', child === this.maximizedTab)
                     element.classList.toggle('minimized', this.maximizedTab && child !== this.maximizedTab)
-                    element.classList.toggle('focused', child === this.focusedTab)
+                    element.classList.toggle('focused', this._allFocusMode || child === this.focusedTab)
                     element.style.left = `${childX}%`
                     element.style.top = `${childY}%`
                     element.style.width = `${childW}%`

+ 38 - 1
terminus-terminal/src/api/baseTerminalTab.component.ts

@@ -4,7 +4,7 @@ import { ToastrService } from 'ngx-toastr'
 import colors from 'ansi-colors'
 import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core'
 import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
-import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, Platform, LogService, Logger, TabContextMenuItemProvider } from 'terminus-core'
+import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent } from 'terminus-core'
 
 import { BaseSession, SessionsService } from '../services/sessions.service'
 import { TerminalFrontendService } from '../services/terminalFrontend.service'
@@ -92,6 +92,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
     private hotkeysSubscription: Subscription
     private bellPlayer: HTMLAudioElement
     private termContainerSubscriptions: Subscription[] = []
+    private allFocusModeSubscription: Subscription|null = null
 
     get input$ (): Observable<Buffer> { return this.frontend.input$ }
     get output$ (): Observable<string> { return this.output }
@@ -172,6 +173,9 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
                         this.element.nativeElement.querySelector('.search-input').focus()
                     })
                     break
+                case 'pane-focus-all':
+                    this.focusAllPanes()
+                    break
             }
         })
         this.bellPlayer = document.createElement('audio')
@@ -255,6 +259,10 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
         })
 
         this.frontend.focus()
+
+        this.blurred$.subscribe(() => {
+            this.cancelFocusAllPanes()
+        })
     }
 
     async buildContextMenu (): Promise<Electron.MenuItemConstructorOptions[]> {
@@ -366,6 +374,35 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
         this.frontend.setZoom(this.zoom)
     }
 
+    focusAllPanes (): void {
+        if (this.allFocusModeSubscription) {
+            return
+        }
+        if (this.parent instanceof SplitTabComponent) {
+            this.parent._allFocusMode = true
+            this.parent.layout()
+            this.allFocusModeSubscription = this.frontend.input$.subscribe(data => {
+                for (const tab of (this.parent as SplitTabComponent).getAllTabs()) {
+                    if (tab !== this && tab instanceof BaseTerminalTabComponent) {
+                        tab.sendInput(data)
+                    }
+                }
+            })
+        }
+    }
+
+    cancelFocusAllPanes (): void {
+        if (!this.allFocusModeSubscription) {
+            return
+        }
+        if (this.parent instanceof SplitTabComponent) {
+            this.allFocusModeSubscription?.unsubscribe?.()
+            this.allFocusModeSubscription = null
+            this.parent._allFocusMode = false
+            this.parent.layout()
+        }
+    }
+
     /** @hidden */
     ngOnDestroy (): void {
         this.frontend.detach(this.content.nativeElement)

+ 9 - 0
terminus-terminal/src/config.ts

@@ -109,6 +109,9 @@ export class TerminalConfigProvider extends ConfigProvider {
                 search: [
                     '⌘-F',
                 ],
+                'pane-focus-all': [
+                    '⌘-Shift-I',
+                ],
             },
         },
         [Platform.Windows]: {
@@ -152,6 +155,9 @@ export class TerminalConfigProvider extends ConfigProvider {
                 search: [
                     'Ctrl-Shift-F',
                 ],
+                'pane-focus-all': [
+                    'Ctrl-Shift-I',
+                ],
             },
         },
         [Platform.Linux]: {
@@ -192,6 +198,9 @@ export class TerminalConfigProvider extends ConfigProvider {
                 search: [
                     'Ctrl-Shift-F',
                 ],
+                'pane-focus-all': [
+                    'Ctrl-Shift-I',
+                ],
             },
         },
     }

+ 4 - 0
terminus-terminal/src/hotkeys.ts

@@ -66,6 +66,10 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
             id: 'search',
             name: 'Search',
         },
+        {
+            id: 'pane-focus-all',
+            name: 'Focus all panes at once',
+        },
     ]
 
     constructor (

+ 10 - 1
terminus-terminal/src/tabContextMenu.ts

@@ -1,6 +1,6 @@
 import { Injectable, NgZone, Optional, Inject } from '@angular/core'
 import { ToastrService } from 'ngx-toastr'
-import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent } from 'terminus-core'
+import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, SplitTabComponent } from 'terminus-core'
 import { TerminalTabComponent } from './components/terminalTab.component'
 import { UACService } from './services/uac.service'
 import { TerminalService } from './services/terminal.service'
@@ -113,6 +113,15 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
             })
         }
 
+        if (tab instanceof BaseTerminalTabComponent && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
+            items.push({
+                label: 'Focus all panes',
+                click: () => this.zone.run(() => {
+                    tab.focusAllPanes()
+                }),
+            })
+        }
+
         return items
     }
 }