Răsfoiți Sursa

Merge branch 'master' of github.com:Eugeny/terminus

Eugene Pankov 7 ani în urmă
părinte
comite
57de182013

+ 1 - 0
terminus-core/package.json

@@ -43,6 +43,7 @@
   "dependencies": {
     "deepmerge": "^1.5.0",
     "js-yaml": "^3.9.0",
+    "winreg": "^1.2.4",
     "winston": "^2.4.0"
   },
   "false": {}

+ 1 - 0
terminus-core/src/api/index.ts

@@ -13,4 +13,5 @@ export { Logger, LogService } from '../services/log.service'
 export { HomeBaseService } from '../services/homeBase.service'
 export { HotkeysService } from '../services/hotkeys.service'
 export { HostAppService, Platform } from '../services/hostApp.service'
+export { ShellIntegrationService } from '../services/shellIntegration.service'
 export { ThemesService } from '../services/themes.service'

+ 2 - 0
terminus-core/src/index.ts

@@ -14,6 +14,7 @@ import { LogService } from './services/log.service'
 import { HomeBaseService } from './services/homeBase.service'
 import { HotkeysService, AppHotkeyProvider } from './services/hotkeys.service'
 import { DockingService } from './services/docking.service'
+import { ShellIntegrationService } from './services/shellIntegration.service'
 import { TabRecoveryService } from './services/tabRecovery.service'
 import { ThemesService } from './services/themes.service'
 import { TouchbarService } from './services/touchbar.service'
@@ -51,6 +52,7 @@ const PROVIDERS = [
     HostAppService,
     HotkeysService,
     LogService,
+    ShellIntegrationService,
     TabRecoveryService,
     ThemesService,
     TouchbarService,

+ 85 - 0
terminus-core/src/services/shellIntegration.service.ts

@@ -0,0 +1,85 @@
+import * as path from 'path'
+import * as fs from 'mz/fs'
+import { exec } from 'mz/child_process'
+import { Injectable } from '@angular/core'
+import { ElectronService } from './electron.service'
+import { HostAppService, Platform } from './hostApp.service'
+
+let Registry = null
+try {
+    Registry = require('winreg')
+} catch (_) { } // tslint:disable-line no-empty
+
+@Injectable()
+export class ShellIntegrationService {
+    private automatorWorkflows = ['Open Terminus here.workflow', 'Paste path into Terminus.workflow']
+    private automatorWorkflowsLocation: string
+    private automatorWorkflowsDestination: string
+    private registryKeys = [
+        {
+            path: '\\Software\\Classes\\Directory\\Background\\shell\\Open Terminus here',
+            command: 'open "%V"'
+        },
+        {
+            path: '\\Software\\Classes\\*\\shell\\Paste path into Terminus',
+            command: 'paste "%V"'
+        },
+    ]
+    constructor (
+        private electron: ElectronService,
+        private hostApp: HostAppService,
+    ) {
+        if (this.hostApp.platform === Platform.macOS) {
+            this.automatorWorkflowsLocation = path.join(
+                path.dirname(path.dirname(this.electron.app.getPath('exe'))),
+                'Resources',
+                'extras',
+                'automator-workflows',
+            )
+            this.automatorWorkflowsDestination = path.join(process.env.HOME, 'Library', 'Services')
+        }
+    }
+
+    async isInstalled (): Promise<boolean> {
+        if (this.hostApp.platform === Platform.macOS) {
+            return await fs.exists(path.join(this.automatorWorkflowsDestination, this.automatorWorkflows[0]))
+        } else if (this.hostApp.platform === Platform.Windows) {
+            return await new Promise<boolean>(resolve => {
+                let reg = new Registry({ hive: Registry.HKCU, key: this.registryKeys[0].path, arch: 'x64' })
+                reg.keyExists((err, exists) => resolve(!err && exists))
+            })
+        }
+        return true
+    }
+
+    async install () {
+        if (this.hostApp.platform === Platform.macOS) {
+            for (let wf of this.automatorWorkflows) {
+                await exec(`cp -r "${this.automatorWorkflowsLocation}/${wf}" "${this.automatorWorkflowsDestination}"`)
+            }
+        } else if (this.hostApp.platform === Platform.Windows) {
+            for (let registryKey of this.registryKeys) {
+                let reg = new Registry({ hive: Registry.HKCU, key: registryKey.path, arch: 'x64' })
+                await new Promise(resolve => {
+                    reg.set('Icon', Registry.REG_SZ, this.electron.app.getPath('exe'), () => {
+                        reg.create(() => {
+                            let cmd = new Registry({
+                                hive: Registry.HKCU,
+                                key: registryKey.path + '\\command',
+                                arch: 'x64'
+                            })
+                            cmd.create(() => {
+                                cmd.set(
+                                    '',
+                                    Registry.REG_SZ,
+                                    this.electron.app.getPath('exe') + ' ' + registryKey.command,
+                                    () => resolve()
+                                )
+                            })
+                        })
+                    })
+                })
+            }
+        }
+    }
+}

+ 6 - 2
terminus-core/src/theme.paper.scss

@@ -106,8 +106,12 @@ window-controls {
         fill: $base01;
     }
 
-    button:hover svg {
-        fill: $black;
+    button:hover {
+        background: rgba($black, 0.125);
+        
+        svg {
+            fill: $black;
+        }
     }
 
     .btn-close:hover {

+ 4 - 0
terminus-core/yarn.lock

@@ -549,6 +549,10 @@ [email protected]:
     core-util-is "1.0.2"
     extsprintf "^1.2.0"
 
+winreg@^1.2.4:
+  version "1.2.4"
+  resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b"
+
 winston@^2.4.0:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.0.tgz#808050b93d52661ed9fb6c26b3f0c826708b0aee"

+ 3 - 3
terminus-settings/src/components/settingsTab.component.pug

@@ -19,11 +19,11 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
                     i.fa.fa-bug
                     span Report a problem
 
-            .form-line(*ngIf='!automatorWorkflowsInstalled')
+            .form-line(*ngIf='!isShellIntegrationInstalled')
                 .header
-                    .title Finder context menu items
+                    .title Shell integration
                     .description Allows quickly opening a terminal in the selected folder
-                button.btn.btn-primary((click)='installAutomatorWorkflows()')
+                button.btn.btn-primary((click)='installShellIntegration()')
                     i.fa.fa-check 
                     span Install
 

+ 19 - 23
terminus-settings/src/components/settingsTab.component.ts

@@ -1,10 +1,19 @@
 import * as yaml from 'js-yaml'
-import * as path from 'path'
-import * as fs from 'mz/fs'
-import { exec } from 'mz/child_process'
 import { Subscription } from 'rxjs'
 import { Component, Inject, Input } from '@angular/core'
-import { ElectronService, DockingService, ConfigService, IHotkeyDescription, HotkeyProvider, BaseTabComponent, Theme, HostAppService, Platform, HomeBaseService } from 'terminus-core'
+import {
+    ElectronService,
+    DockingService,
+    ConfigService,
+    IHotkeyDescription,
+    HotkeyProvider,
+    BaseTabComponent,
+    Theme,
+    HostAppService,
+    Platform,
+    HomeBaseService,
+    ShellIntegrationService
+} from 'terminus-core'
 
 import { SettingsTabProvider } from '../api'
 
@@ -24,11 +33,8 @@ export class SettingsTabComponent extends BaseTabComponent {
     Platform = Platform
     configDefaults: any
     configFile: string
-    automatorWorkflowsInstalled = false
+    isShellIntegrationInstalled = false
     private configSubscription: Subscription
-    private automatorWorkflows = ['Open Terminus here.workflow', 'Paste path into Terminus.workflow']
-    private automatorWorkflowsLocation: string
-    private automatorWorkflowsDestination: string
 
     constructor (
         public config: ConfigService,
@@ -36,6 +42,7 @@ export class SettingsTabComponent extends BaseTabComponent {
         public docking: DockingService,
         public hostApp: HostAppService,
         public homeBase: HomeBaseService,
+        public shellIntegration: ShellIntegrationService,
         @Inject(HotkeyProvider) hotkeyProviders: HotkeyProvider[],
         @Inject(SettingsTabProvider) public settingsProviders: SettingsTabProvider[],
         @Inject(Theme) public themes: Theme[],
@@ -52,19 +59,10 @@ export class SettingsTabComponent extends BaseTabComponent {
         this.configSubscription = config.changed$.subscribe(() => {
             this.configFile = config.readRaw()
         })
-
-        this.automatorWorkflowsLocation = path.join(
-            path.dirname(path.dirname(this.electron.app.getPath('exe'))),
-            'Resources',
-            'extras',
-            'automator-workflows',
-        )
-
-        this.automatorWorkflowsDestination = path.join(process.env.HOME, 'Library', 'Services')
     }
 
     async ngOnInit () {
-        this.automatorWorkflowsInstalled = await fs.exists(path.join(this.automatorWorkflowsDestination, this.automatorWorkflows[0]))
+        this.isShellIntegrationInstalled = await this.shellIntegration.isInstalled()
     }
 
     getRecoveryToken (): any {
@@ -96,10 +94,8 @@ export class SettingsTabComponent extends BaseTabComponent {
         }
     }
 
-    async installAutomatorWorkflows () {
-        for (let wf of this.automatorWorkflows) {
-            await exec(`cp -r "${this.automatorWorkflowsLocation}/${wf}" "${this.automatorWorkflowsDestination}"`)
-        }
-        this.automatorWorkflowsInstalled = true
+    async installShellIntegration () {
+        await this.shellIntegration.install()
+        this.isShellIntegrationInstalled = true
     }
 }

+ 2 - 2
terminus-terminal/src/services/terminal.service.ts

@@ -38,9 +38,9 @@ export class TerminalService {
         if (!cwd) {
             if (this.app.activeTab instanceof TerminalTabComponent && this.app.activeTab.session) {
                 cwd = await this.app.activeTab.session.getWorkingDirectory()
-            } else {
-                cwd = this.config.store.terminal.workingDirectory || null
             }
+            cwd = cwd || this.config.store.terminal.workingDirectory
+            cwd = cwd || null
         }
         if (!shell) {
             let shells = await this.shells$.toPromise()