From a0423994bc3d15ac254896a96a2a2f5cb7d47eca Mon Sep 17 00:00:00 2001 From: Daniel Perrett Date: Thu, 17 Nov 2016 08:35:30 +0000 Subject: [PATCH 1/4] Refactor out label class --- lib/ui/FindForm.js | 5 ++--- lib/ui/GoLineForm.js | 5 ++--- lib/ui/Label.js | 24 ++++++++++++++++++++++++ lib/ui/SaveAsForm.js | 5 ++--- 4 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 lib/ui/Label.js diff --git a/lib/ui/FindForm.js b/lib/ui/FindForm.js index de8e4c5..7beaf18 100644 --- a/lib/ui/FindForm.js +++ b/lib/ui/FindForm.js @@ -6,6 +6,7 @@ var util = require('slap-util'); var BaseWidget = require('base-widget'); var Slap = require('./Slap'); var BaseFindForm = require('./BaseFindForm'); +var Label = require('./Label'); FindForm._label = " find (/.*/ for regex): "; FindForm._regExpRegExp = /^\/(.+)\/(\w*)$/i; @@ -19,15 +20,13 @@ function FindForm (opts) { findField: {left: FindForm._label.length} }, Slap.global.options.form.find, opts)); - self.findLabel = new BaseWidget(_.merge({ + self.findLabel = new Label(_.merge({ parent: self, tags: true, content: FindForm._label, top: 0, - height: 1, left: 0, width: FindForm._label.length, - style: self.options.style }, self.options.findLabel)); } FindForm.prototype.__proto__ = BaseFindForm.prototype; diff --git a/lib/ui/GoLineForm.js b/lib/ui/GoLineForm.js index 0507656..d80b9c0 100644 --- a/lib/ui/GoLineForm.js +++ b/lib/ui/GoLineForm.js @@ -4,6 +4,7 @@ var BaseWidget = require('base-widget'); var Slap = require('./Slap'); var BaseFindForm = require('./BaseFindForm'); +var Label = require('./Label'); GoLineForm._label = " line number: "; function GoLineForm (opts) { @@ -15,15 +16,13 @@ function GoLineForm (opts) { findField: {left: GoLineForm._label.length} }, Slap.global.options.form.goLine, opts)); - self.goLineLabel = new BaseWidget(_.merge({ + self.goLineLabel = new Label(_.merge({ parent: self, tags: true, content: GoLineForm._label, top: 0, - height: 1, left: 0, width: GoLineForm._label.length, - style: self.options.style }, self.options.goLineLabel)); } GoLineForm.prototype.__proto__ = BaseFindForm.prototype; diff --git a/lib/ui/Label.js b/lib/ui/Label.js new file mode 100644 index 0000000..97c06c7 --- /dev/null +++ b/lib/ui/Label.js @@ -0,0 +1,24 @@ +var blessed = require('blessed'); +var _ = require('lodash'); + +var util = require('slap-util'); + +var BaseWidget = require('base-widget'); +var Slap = require('./Slap'); + +function Label (opts) { + var self = this; + + if (!(self instanceof Label)) return new Label(opts); + + opts = _.merge({ + height: 1 + }, Slap.global.options.label, opts); + + BaseWidget.blessed.Text.call(self, opts); + BaseWidget.call(self, opts); +} + +Label.prototype.__proto__ = BaseWidget.blessed.Text.prototype; + +module.exports = Label; diff --git a/lib/ui/SaveAsForm.js b/lib/ui/SaveAsForm.js index 401ac64..73ea364 100644 --- a/lib/ui/SaveAsForm.js +++ b/lib/ui/SaveAsForm.js @@ -4,6 +4,7 @@ var BaseWidget = require('base-widget'); var Field = require('editor-widget').Field; var Slap = require('./Slap'); var BaseForm = require('./BaseForm'); +var Label = require('./Label'); SaveAsForm._label = " save as: "; function SaveAsForm (opts) { @@ -15,15 +16,13 @@ function SaveAsForm (opts) { field: {left: SaveAsForm._label.length} }, Slap.global.options.form.saveAs, opts)); - self.saveAsLabel = new BaseWidget(_.merge({ + self.saveAsLabel = new Label(_.merge({ parent: self, tags: true, content: SaveAsForm._label, top: 0, - height: 1, left: 0, width: SaveAsForm._label.length, - style: self.options.style }, self.options.saveAsLabel)); self.pathField = new Field(_.merge({ From 0c1672c5cb85271025810e79ac3486f81df6cb66 Mon Sep 17 00:00:00 2001 From: Daniel Perrett Date: Tue, 25 Oct 2016 08:45:52 +0100 Subject: [PATCH 2/4] Find/replace now works --- lib/ui/FindForm.js | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/ui/FindForm.js b/lib/ui/FindForm.js index 7beaf18..c392747 100644 --- a/lib/ui/FindForm.js +++ b/lib/ui/FindForm.js @@ -7,8 +7,10 @@ var BaseWidget = require('base-widget'); var Slap = require('./Slap'); var BaseFindForm = require('./BaseFindForm'); var Label = require('./Label'); +var Field = require('editor-widget').Field; +var Button = require('./Button'); -FindForm._label = " find (/.*/ for regex): "; +FindForm._label = " Find (/.*/ for regex): "; FindForm._regExpRegExp = /^\/(.+)\/(\w*)$/i; FindForm._invalidRegExpMessageRegExp = /^(Invalid regular expression:|Invalid flags supplied to RegExp constructor)/; function FindForm (opts) { @@ -17,9 +19,33 @@ function FindForm (opts) { if (!(self instanceof FindForm)) return new FindForm(opts); BaseFindForm.call(self, _.merge({ + height: 2, findField: {left: FindForm._label.length} }, Slap.global.options.form.find, opts)); + self.replaceLabel = new Label(_.merge({ + parent: self, + tags: true, + content: ' Replace with: ', + top: 1, + height: 1, + left: 0 + }, self.options.findLabel)); + + self.replaceField = new Field(_.merge({ + parent: self, + top: 1, + left: 15, + right: 9 + }, Slap.global.options.editor, Slap.global.options.field, self.options.replaceField)); + + self.replaceButton = new Button(_.merge({ + parent: self, + content: "Replace", + top: 1, + right: 0 + }, Slap.global.options.button, self.options.replaceButton)); + self.findLabel = new Label(_.merge({ parent: self, tags: true, @@ -50,7 +76,8 @@ FindForm.prototype._initHandlers = function () { editor.destroyMarkers({type: 'findMatch'}); editor._updateContent(); }); - self.on('find', lodash.throttle(function (pattern, direction) { + + var findOrReplace = function (pattern, direction, replacement) { direction = direction || 0; editor.destroyMarkers({type: 'findMatch'}); try { @@ -84,6 +111,9 @@ FindForm.prototype._initHandlers = function () { var cmp = matchRange.start.compare(selectionRange.start); if (cmp === direction) { self.selectRange(matchRange); + if (replacement) { + editor.textBuf.setTextInRange(editor.selection.getRange(), replacement); + } return true; } else if (!cmp && matches.length === 1) { header.message("this is the only occurrence", 'info'); @@ -92,8 +122,17 @@ FindForm.prototype._initHandlers = function () { })) { header.message("search wrapped", 'info'); self.selectRange(matches[0].range); + if (replacement) { + editor.textBuf.setTextInRange(editor.selection.getRange(), replacement); + } } editor._updateContent(); + }; + + self.on('find', lodash.throttle(findOrReplace, self.options.perf.findThrottle)); + + self.replaceButton.on('press', lodash.throttle( function () { + findOrReplace(self.findField.value(), 0, self.replaceField.value()); }, self.options.perf.findThrottle)); self.findField.on('keypress', function (ch, key) { From 1fa263225a22ae8710e71b804b5cf67e3a42147e Mon Sep 17 00:00:00 2001 From: Daniel Perrett Date: Fri, 23 Dec 2016 22:07:44 +0000 Subject: [PATCH 3/4] When replace field is focussed, enter should trigger replace action --- lib/ui/FindForm.js | 14 +++++++++++++- slap.ini | 8 ++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/ui/FindForm.js b/lib/ui/FindForm.js index c392747..c3a99c6 100644 --- a/lib/ui/FindForm.js +++ b/lib/ui/FindForm.js @@ -135,11 +135,23 @@ FindForm.prototype._initHandlers = function () { findOrReplace(self.findField.value(), 0, self.replaceField.value()); }, self.options.perf.findThrottle)); + self.replaceField.on('keypress', function (ch, key) { + var text = self.findField.value(); + switch (self.resolveBinding(key)) { + case 'next': self.find(text, 1); return false; + case 'prev': self.find(text, -1); return false; + case 'submit': findOrReplace(text, 1, self.replaceField.value()); return false; + case 'submitAlt': findOrReplace(text, -1, self.replaceField.value()); return false; + }; + }); + self.findField.on('keypress', function (ch, key) { - var text = self.findField.textBuf.getText(); + var text = self.findField.value(); switch (self.resolveBinding(key)) { case 'next': self.find(text, 1); return false; case 'prev': self.find(text, -1); return false; + case 'submit': self.find(text, 1); return false; + case 'submitAlt': self.find(text, -1); return false; }; }); diff --git a/slap.ini b/slap.ini index c5a5338..75cc8d9 100644 --- a/slap.ini +++ b/slap.ini @@ -48,13 +48,13 @@ goLine = "C-g" cancel = "escape" [form.baseFind.bindings] -next[] = "enter" +submit[] = "enter" next[] = "down" prev[] = "up" ; These don't work in most terminal emulators -prev[] = "S-enter" -prev[] = "M-enter" -prev[] = "C-enter" +submitAlt[] = "S-enter" +submitAlt[] = "M-enter" +submitAlt[] = "C-enter" [dialog.bindings] hide = "escape" From c55b5f55a2a46868dc231fb73a22bac1aef31644 Mon Sep 17 00:00:00 2001 From: Daniel Perrett Date: Tue, 13 Dec 2016 08:09:39 +0000 Subject: [PATCH 4/4] Interpolate replacement text --- lib/ui/FindForm.js | 9 +++++++-- package.json | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/ui/FindForm.js b/lib/ui/FindForm.js index c3a99c6..ba8c2e2 100644 --- a/lib/ui/FindForm.js +++ b/lib/ui/FindForm.js @@ -9,6 +9,7 @@ var BaseFindForm = require('./BaseFindForm'); var Label = require('./Label'); var Field = require('editor-widget').Field; var Button = require('./Button'); +var Interpolator = require('regexp-capture-interpolation'); FindForm._label = " Find (/.*/ for regex): "; FindForm._regExpRegExp = /^\/(.+)\/(\w*)$/i; @@ -77,6 +78,10 @@ FindForm.prototype._initHandlers = function () { editor._updateContent(); }); + var interpolateReplacement = function (match, replacement) { + return Interpolator.interpolate(match.concat([match.index,match.input]), replacement); + }; + var findOrReplace = function (pattern, direction, replacement) { direction = direction || 0; editor.destroyMarkers({type: 'findMatch'}); @@ -112,7 +117,7 @@ FindForm.prototype._initHandlers = function () { if (cmp === direction) { self.selectRange(matchRange); if (replacement) { - editor.textBuf.setTextInRange(editor.selection.getRange(), replacement); + editor.textBuf.setTextInRange(editor.selection.getRange(), interpolateReplacement(match.match, replacement)); } return true; } else if (!cmp && matches.length === 1) { @@ -123,7 +128,7 @@ FindForm.prototype._initHandlers = function () { header.message("search wrapped", 'info'); self.selectRange(matches[0].range); if (replacement) { - editor.textBuf.setTextInRange(editor.selection.getRange(), replacement); + editor.textBuf.setTextInRange(editor.selection.getRange(), interpolateReplacement(matches[0].match, replacement)); } } editor._updateContent(); diff --git a/package.json b/package.json index 37784b7..af9112e 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "mkdirp": "0.5.1", "node-clap": "0.0.5", "rc": "1.1.6", + "regexp-capture-interpolation": "0.1.1", "slap-util": "1.0.7", "ttys": "0.0.3", "update-notifier": "1.0.2"