From fd351a5b9322d40b1924e49b493fb8031f0758ce Mon Sep 17 00:00:00 2001 From: Philippe Potvin Date: Sat, 13 Aug 2016 17:03:44 -0400 Subject: [PATCH] Provide clear selection of text in terminal view (#608) * Permit clearSelection on text enter and mouse selection. Fix #591 * Add config for copyOnSelect * Update with descriptive comment --- app/config-default.js | 5 ++++- lib/components/term.js | 12 ++++++++++++ lib/components/terms.js | 3 ++- lib/containers/terms.js | 3 ++- lib/hterm.js | 13 +++++++++++++ lib/reducers/ui.js | 7 ++++++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/app/config-default.js b/app/config-default.js index c702ec75..2abf4166 100644 --- a/app/config-default.js +++ b/app/config-default.js @@ -64,7 +64,10 @@ module.exports = { env: {}, // set to false for no bell - bell: 'SOUND' + bell: 'SOUND', + + // if true, selected text will automatically be copied to the clipboard + copyOnSelect: false // URL to custom bell // bellSoundURL: 'http://example.com/bell.mp3', diff --git a/lib/components/term.js b/lib/components/term.js index b259f0fb..4bb212b9 100644 --- a/lib/components/term.js +++ b/lib/components/term.js @@ -45,6 +45,12 @@ export default class Term extends Component { this.term.prefs_.set('audible-bell-sound', ''); } + if (props.copyOnSelect) { + this.term.prefs_.set('copy-on-select', true); + } else { + this.term.prefs_.set('copy-on-select', false); + } + this.term.onTerminalReady = () => { const io = this.term.io.push(); io.onVTKeystroke = io.sendString = props.onData; @@ -215,6 +221,12 @@ export default class Term extends Component { } else { this.term.prefs_.set('audible-bell-sound', ''); } + + if (this.props.copyOnSelect) { + this.term.prefs_.set('copy-on-select', true); + } else { + this.term.prefs_.set('copy-on-select', false); + } } componentWillUnmount () { diff --git a/lib/components/terms.js b/lib/components/terms.js index fdbb7dca..f7995fa9 100644 --- a/lib/components/terms.js +++ b/lib/components/terms.js @@ -145,7 +145,8 @@ export default class Terms extends Component { onData: this.bind(this.props.onData, null, uid), onURLAbort: this.bind(this.props.onURLAbort, null, uid), bell: this.props.bell, - bellSoundURL: this.props.bellSoundURL + bellSoundURL: this.props.bellSoundURL, + copyOnSelect: this.props.copyOnSelect }); return
{ diff --git a/lib/hterm.js b/lib/hterm.js index bec25a15..9b25d5e7 100644 --- a/lib/hterm.js +++ b/lib/hterm.js @@ -2,6 +2,12 @@ import { hterm, lib } from 'hterm-umdjs'; hterm.defaultStorage = new lib.Storage.Memory(); +// clear selection range of current selected term view +// Fix event when terminal text is selected and keyboard action is invoked +hterm.Terminal.prototype.clearSelection = function () { + this.document_.getSelection().removeAllRanges(); +}; + // override double click behavior to copy const oldMouse = hterm.Terminal.prototype.onMouse_; hterm.Terminal.prototype.onMouse_ = function (e) { @@ -85,6 +91,11 @@ hterm.Keyboard.prototype.onKeyDown_ = function (e) { if (e.metaKey || e.altKey) { return; + } else { + // Test for valid keys in order to clear the terminal selection + if ((!e.ctrlKey || e.code !== 'ControlLeft') && !e.shiftKey && e.code !== 'CapsLock') { + this.terminal.clearSelection(); + } } return oldKeyDown.call(this, e); }; @@ -93,6 +104,8 @@ const oldKeyPress = hterm.Keyboard.prototype.onKeyPress_; hterm.Keyboard.prototype.onKeyPress_ = function (e) { if (e.metaKey) { return; + } else { + this.terminal.clearSelection(); } return oldKeyPress.call(this, e); }; diff --git a/lib/reducers/ui.js b/lib/reducers/ui.js index ff35b204..c8998973 100644 --- a/lib/reducers/ui.js +++ b/lib/reducers/ui.js @@ -70,7 +70,8 @@ const initial = Immutable({ updateVersion: null, updateNotes: null, bell: 'SOUND', - bellSoundURL: 'lib-resource:hterm/audio/bell' + bellSoundURL: 'lib-resource:hterm/audio/bell', + copyOnSelect: false }); const reducer = (state = initial, action) => { @@ -138,6 +139,10 @@ const reducer = (state = initial, action) => { ret.bellSoundURL = config.bellSoundURL || initial.bellSoundURL; } + if (null !== config.copyOnSelect) { + ret.copyOnSelect = config.copyOnSelect; + } + if (null != config.colors) { if (Array.isArray(config.colors)) { const stateColors = Array.isArray(state.colors)