From d4190a1c2773bfc2bd517178a1fc138a4c85e4e3 Mon Sep 17 00:00:00 2001 From: Fred-Barclay Date: Sun, 30 Sep 2018 15:04:06 -0500 Subject: [PATCH] WIP: Align with upstream --- AUTHORS | 3 +++ CHANGELOG.md | 7 +++++ TODO | 2 ++ lib/process.coffee | 22 ++++++++-------- lib/status-bar.coffee | 36 +++++++++++++++++++------ lib/termination.coffee | 24 ++++++++++++++++- lib/view.coffee | 48 +++++++++++++++++++++++++++------- package.json | 13 +++++++-- styles/themes.less | 1 + styles/themes/city-lights.less | 11 ++++++++ 10 files changed, 135 insertions(+), 32 deletions(-) create mode 100644 styles/themes/city-lights.less diff --git a/AUTHORS b/AUTHORS index 8f58479..152d99b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -45,3 +45,6 @@ Jerry Yu (https://github.com/yubaoquan) Matt Pilott (https://github.com/matt3224) * Fix copy-paste + +Simas Čepaitis (https://github.com/geriBatai) + * Add City Lights theme diff --git a/CHANGELOG.md b/CHANGELOG.md index df063e9..1da13ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.7.0-dev +* More unity with upstream +* Bump atom-space-pen-views to 2.2.0 +* Add city lights theme (from @geriBatai) +* Add upstream API +* "clear" terminal option working + ## 0.6.3 * Fix copy-paste, Issue #53 and PR #55 on PIO upstream (from @matt3224) * Support for Atom 28 (Electron 2.0). See issue #77. diff --git a/TODO b/TODO index 7e392e9..f5fe805 100644 --- a/TODO +++ b/TODO @@ -7,3 +7,5 @@ Explain in README.md the differences between upstream and us Split termination window to a new pane on left or right Finish terminal colour settings + +Improvements to lib/view.coffee diff --git a/lib/process.coffee b/lib/process.coffee index 36090b2..396fcd5 100755 --- a/lib/process.coffee +++ b/lib/process.coffee @@ -13,23 +13,22 @@ systemLanguage = do -> return language filteredEnvironment = do -> - env = _.omit process.env, 'ATOM_HOME', 'ELECTRON_RUN_AS_NODE', 'GOOGLE_API_KEY', 'NODE_ENV', 'NODE_PATH', 'userAgent', 'taskPath' + env = _.omit process.env, 'ATOM_HOME', 'ELECTRON_RUN_AS_NODE', 'GOOGLE_API_KEY', 'NODE_ENV', 'NODE_PATH', 'userAgent', 'taskPath' env.LANG ?= systemLanguage env.TERM_PROGRAM = 'termination' return env -module.exports = (pwd, shell, args, options={}) -> +module.exports = (pwd, shell, args, env, options={}) -> callback = @async() - if /zsh|bash/.test(shell) and args.indexOf('--login') == -1 and process.platform isnt 'win32' - args.unshift '--login' - - ptyProcess = pty.fork shell, args, - cwd: pwd, - env: filteredEnvironment, - name: 'xterm-256color' - - title = shell = path.basename shell + if shell + ptyProcess = pty.fork shell, args, + cwd: pwd, + env: _.extend(filteredEnvironment, env), + name: 'xterm-256color' + title = shell = path.basename shell + else + ptyProcess = pty.open() emitTitle = _.throttle -> emit('termination:title', ptyProcess.process) @@ -47,3 +46,4 @@ module.exports = (pwd, shell, args, options={}) -> switch event when 'resize' then ptyProcess.resize(cols, rows) when 'input' then ptyProcess.write(text) + when 'pty' then emit('termination:pty', ptyProcess.pty) diff --git a/lib/status-bar.coffee b/lib/status-bar.coffee index 32b0499..b62cdfc 100644 --- a/lib/status-bar.coffee +++ b/lib/status-bar.coffee @@ -6,6 +6,7 @@ StatusIcon = require './status-icon' os = require 'os' path = require 'path' +_ = require 'underscore' module.exports = class StatusBar extends View @@ -54,6 +55,7 @@ class StatusBar extends View return if @activeTerminal.isAnimating() return @activeTerminal.toggle() if @activeTerminal == @terminalViews[3] @activeTerminal.open() if @activeTerminalView(3) + 'termination:clear': => @clear() 'termination:close': => @destroyActiveTerm() 'termination:close-all': => @closeAll() 'termination:rename': => @runInActiveView (i) -> i.rename() @@ -121,7 +123,7 @@ class StatusBar extends View handleFocus = => if @returnFocus setTimeout => - @returnFocus?.focus() + @returnFocus?.focus(true) @returnFocus = null , 100 @@ -170,6 +172,20 @@ class StatusBar extends View pane.onDidDestroy -> tabBar.off 'drop', @onDropTabBar createTerminalView: (autoRun) -> + shell = atom.config.get 'termination.core.shell' + shellArguments = atom.config.get 'termination.core.shellArguments' + args = shellArguments.split(/\s+/g).filter (arg) -> arg + shellEnv = atom.config.get 'termination.core.shellEnv' + env = {} + shellEnv.split(' ').forEach((element) => + configVar = element.split('=') + envVar = {} + envVar[configVar[0]] = configVar[1] + env = _.extend(env, envVar) + ) + @createEmptyTerminalView autoRun, shell, args, env + + createEmptyTerminalView: (autoRun=[], shell = null, args = [], env= {}) -> @registerPaneSubscription() unless @paneSubscription? projectFolder = atom.project.getPaths()[0] @@ -193,12 +209,8 @@ class StatusBar extends View id = editorPath or projectFolder or home id = filePath: id, folderPath: path.dirname(id) - shell = atom.config.get 'termination.core.shell' - shellArguments = atom.config.get 'termination.core.shellArguments' - args = shellArguments.split(/\s+/g).filter (arg) -> arg - statusIcon = new StatusIcon() - terminationView = new TerminationView(id, pwd, statusIcon, this, shell, args, autoRun) + terminationView = new TerminationView(id, pwd, statusIcon, this, shell, args, env, autoRun) statusIcon.initialize(terminationView) terminationView.attach() @@ -239,7 +251,6 @@ class StatusBar extends View if terminal = TerminationView.getFocusedTerminal() @activeTerminal.blur() - else @activeTerminal.focusTerminal() @@ -267,6 +278,11 @@ class StatusBar extends View return callback(view) return null + runNewTerminal: () -> + @activeTerminal = @createEmptyTerminalView() + @activeTerminal.toggle() + return @activeTerminal + runCommandInNewTerminal: (commands) -> @activeTerminal = @createTerminalView(commands) @activeTerminal.toggle() @@ -337,6 +353,10 @@ class StatusBar extends View @activeTerminal = @terminalViews[0] @activeTerminal.toggle() + clear: -> + @destroyActiveTerm() + @newTerminalView() + setStatusColor: (event) -> color = event.type.match(/\w+$/)[0] color = atom.config.get("termination.iconColors.#{color}").toRGBAString() @@ -424,7 +444,7 @@ class StatusBar extends View @statusContainer.children().eq(fromIndex).detach() view.statusIcon.removeTooltip() - pane.addItem view, { index: pane.getItems().length } + pane.addItem view, pane.getItems().length pane.activateItem view view.focus() diff --git a/lib/termination.coffee b/lib/termination.coffee index 547221c..842acb8 100755 --- a/lib/termination.coffee +++ b/lib/termination.coffee @@ -7,6 +7,17 @@ module.exports = @statusBarTile?.destroy() @statusBarTile = null + provideTerminationTerminal: -> + updateProcessEnv: (variables) -> + for name, value of variables + process.env[name] = value + run: (commands) => + @statusBarTile.runCommandInNewTerminal commands + getTerminalViews: () => + @statusBarTile.terminalViews + open: () => + @statusBarTile.runNewTerminal() + provideRunInTerminal: -> run: (commands) => @statusBarTile.runCommandInNewTerminal commands @@ -42,6 +53,11 @@ module.exports = description: 'Copies text to clipboard when selection happens.' type: 'boolean' default: true + loginShell: + title: 'Login Shell' + description: 'Use --login on zsh and bash.' + type: 'boolean' + default: true cloneTerminalPlus: title: 'Clone Terminal-Plus' description: 'Should there be a dedicated bottom panel for termination? @@ -91,6 +107,11 @@ module.exports = description: 'Specify some arguments to use when launching the shell.' type: 'string' default: '' + shellEnv: + title: 'Shell Environment Variables' + description: 'Specify some additional environment variables, space separated with the form `VAR=VALUE`' + type: 'string' + default: '' workingDirectory: title: 'Working Directory' description: 'Which directory should be the present working directory @@ -152,7 +173,8 @@ module.exports = 'one-dark', 'one-light', 'bliss', - 'gruvbox' + 'gruvbox', + 'city-lights' ] iconColors: type: 'object' diff --git a/lib/view.coffee b/lib/view.coffee index dee7589..760b03b 100644 --- a/lib/view.coffee +++ b/lib/view.coffee @@ -40,7 +40,7 @@ class TerminationView extends View @getFocusedTerminal: -> return Terminal.Terminal.focus - initialize: (@id, @pwd, @statusIcon, @statusBar, @shell, @args=[], @autoRun=[]) -> + initialize: (@id, @pwd, @statusIcon, @statusBar, @shell, @args=[], @env={}, @autoRun=[]) -> @subscriptions = new CompositeDisposable @emitter = new Emitter @@ -71,7 +71,12 @@ class TerminationView extends View @xterm.on 'mouseup', (event) => if event.which != 3 text = window.getSelection().toString() - atom.clipboard.write(text) if atom.config.get('termination.toggles.selectToCopy') and text + if atom.config.get('termination.toggles.selectToCopy') and text + rawLines = text.split(/\r?\n/g) + lines = rawLines.map (line) -> + line.replace(/\s/g, " ").trimRight() + text = lines.join("\n") + atom.clipboard.write(text) unless text @focus() @xterm.on 'dragenter', override @@ -82,6 +87,9 @@ class TerminationView extends View @subscriptions.add dispose: => @off 'focus', @focus + if /zsh|bash/.test(@shell) and @args.indexOf('--login') == -1 and Pty.platform isnt 'win32' and atom.config.get('termination.toggles.loginShell') + @args.unshift '--login' + attach: -> return if @panel? @panel = atom.workspace.addBottomPanel(item: this, visible: false) @@ -107,7 +115,7 @@ class TerminationView extends View @input "#{file.path} " forkPtyProcess: -> - Task.once Pty, path.resolve(@pwd), @shell, @args, => + Task.once Pty, path.resolve(@pwd), @shell, @args, @env, => @input = -> @resize = -> @@ -224,6 +232,7 @@ class TerminationView extends View @displayTerminal() @prevHeight = @nearestRow(@xterm.height()) @xterm.height(@prevHeight) + @emit "termination:terminal-open" else @focus() @@ -267,6 +276,28 @@ class TerminationView extends View @ptyProcess.send {event: 'resize', rows, cols} + pty: () -> + if not @opened + wait = new Promise (resolve, reject) => + @emitter.on "platformio-ide-terminal:terminal-open", () => + resolve() + setTimeout reject, 1000 + + wait.then () => + @ptyPromise() + else + @ptyPromise() + + ptyPromise: () -> + new Promise (resolve, reject) => + if @ptyProcess? + @ptyProcess.on "platformio-ide-terminal:pty", (pty) => + resolve(pty) + @ptyProcess.send {event: 'pty'} + setTimeout reject, 1000 + else + reject() + applyStyle: -> config = atom.config.get 'termination' @@ -414,10 +445,6 @@ class TerminationView extends View paste: -> @input atom.clipboard.read() - clear: -> - @terminal.destroy() - @displayTerminal() - copyAllToNewFile: -> text = @terminal.lines.map (line) -> line.map (cols) -> cols[1] @@ -446,9 +473,9 @@ class TerminationView extends View replace(/\$S/, selectionText). replace(/\$\$/, '$')}#{if runCommand then os.EOL else ''}" - focus: => + focus: (fromWindowEvent) => @resizeTerminalToView() - @focusTerminal() + @focusTerminal(fromWindowEvent) @statusBar.setActiveTerminalView(this) super() @@ -456,10 +483,11 @@ class TerminationView extends View @blurTerminal() super() - focusTerminal: => + focusTerminal: (fromWindowEvent) => return unless @terminal lastActiveElement = $(document.activeElement) + return if fromWindowEvent and not (lastActiveElement.is('div.terminal') or lastActiveElement.parents('div.terminal').length) @terminal.focus() if @terminal._textarea diff --git a/package.json b/package.json index cb9022b..e2b1a9d 100644 --- a/package.json +++ b/package.json @@ -41,14 +41,17 @@ "bugs": "https://github.com/Fred-Barclay/Termination/issues", "license": "MIT", "engines": { - "atom": ">=1.19.0" + "atom": ">=1.19.0 <2.0.0" }, "dependencies": { - "atom-space-pen-views": "^2.1.0", + "atom-space-pen-views": "^2.2.0", "pty.js": "https://github.com/platformio/pty.js/tarball/prebuilt", "term.js": "https://github.com/jeremyramin/term.js/tarball/master", "underscore": "^1.8.3" }, + "activationHooks": [ + "core:loaded-shell-environment" + ], "consumedServices": { "status-bar": { "versions": { @@ -57,6 +60,12 @@ } }, "providedServices": { + "platformioIDETerminal": { + "description": "PlatformIO IDE Terminal API", + "versions": { + "1.1.0": "providePlatformIOIDETerminal" + } + }, "runInTerminal": { "description": "Allow to run commands in terminal.", "versions": { diff --git a/styles/themes.less b/styles/themes.less index 5c88779..5c2208e 100644 --- a/styles/themes.less +++ b/styles/themes.less @@ -20,4 +20,5 @@ @import 'themes/one-light'; @import 'themes/bliss'; @import 'themes/gruvbox'; + @import 'themes/city-lights'; } diff --git a/styles/themes/city-lights.less b/styles/themes/city-lights.less new file mode 100644 index 0000000..81a10a5 --- /dev/null +++ b/styles/themes/city-lights.less @@ -0,0 +1,11 @@ +.city-lights { + background-color: #181d23; + color: #666d81; + ::selection { + background-color: #2a2f38; + color: #b7c5d3; + } + .terminal-cursor { + background-color: #528BFF; + } +}