diff --git a/example/ansi-viewer/index.js b/example/ansi-viewer/index.js index 0b4a9ba..86e1099 100644 --- a/example/ansi-viewer/index.js +++ b/example/ansi-viewer/index.js @@ -11,7 +11,7 @@ var blessed = require('../../') , screen; // $ wget -r -o log --tries=10 'http://artscene.textfiles.com/ansi/' -// $ grep 'http.*\.ans$' log | awk '{ print $3 }' > blessed/ansi-art.list +// $ grep 'http.*\.ans$' log | awk '{ print $3 }' > ansi-art.list var urls = fs.readFileSync(__dirname + '/ansi-art.list', 'utf8').trim().split('\n'); @@ -57,7 +57,6 @@ var list = blessed.list({ } }, style: { - //transparent: true, item: { hover: { bg: 'blue' @@ -67,6 +66,12 @@ var list = blessed.list({ bg: 'blue', bold: true } + }, + search: function(callback) { + prompt.input('Search:', '', function(err, value) { + if (err) return; + return callback(value); + }); } }); @@ -78,24 +83,84 @@ var status = blessed.box({ width: 'shrink', style: { bg: 'blue' - } + }, + content: 'Select your piece of ANSI art (`/` to search).' +}); + +var loader = blessed.loading({ + parent: screen, + top: 'center', + left: 'center', + height: 5, + align: 'center', + width: '50%', + tags: true, + hidden: true, + border: 'line' +}); + +var msg = blessed.message({ + parent: screen, + top: 'center', + left: 'center', + height: 'shrink', + width: '50%', + align: 'center', + tags: true, + hidden: true, + border: 'line' +}); + +var prompt = blessed.prompt({ + parent: screen, + top: 'center', + left: 'center', + height: 'shrink', + width: 'shrink', + keys: true, + vi: true, + mouse: true, + tags: true, + content: 'Label:', + border: 'line', + hidden: true }); list.setItems(Object.keys(map)); list.on('select', function(url, selected) { + if (list._.rendering) return; + url = map[url.getText()]; status.setContent(url); + + list._.rendering = true; + loader.load('Loading...'); + request(url, function(err, res, body) { - if (err || !body) return; + list._.rendering = false; + loader.stop(); + + if (err) { + return msg.error(err.message); + } + + if (!body) { + return msg.error('No body.'); + } + + // Remove MCI codes: + body = body.replace(/%[A-Z]{2}/g, ''); + + // Reset and write the art: art.term.reset(); art.term.write(body); art.term.cursorHidden = true; + screen.render(); }); }); -list.select(0); list.focus(); screen.key('q', function() { diff --git a/lib/widget.js b/lib/widget.js index c8146fc..2feb325 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -2884,13 +2884,23 @@ Element.prototype.setLabel = function(options) { this._label.rtop = 0; } - this.on('scroll', function() { + var reposition = function() { var visible = self.height - self.iheight; self._label.rtop = self.childBase - (self.border ? 1 : 0); if (!self.screen.autoPadding) { self._label.rtop = self.childBase; } self.screen.render(); + }; + + this.on('scroll', function() { + reposition(); + }); + + this.on('resize', function() { + nextTick(function() { + reposition(); + }); }); }; @@ -5119,15 +5129,14 @@ function List(options) { return; } - if (options.vi && key.ch === '/') { + if (options.vi && (key.ch === '/' || key.ch === '?')) { if (typeof self.options.search !== 'function') { return; } - - return self.options.search(function(searchString) { - self.select(self.fuzzyFind(searchString)); + return self.options.search(function(value) { + self.select(self.fuzzyFind(value, key.ch === '?')); self.screen.render(); - }) + }); } }); } @@ -5235,12 +5244,26 @@ List.prototype.appendItem = function(item) { } }; -List.prototype.fuzzyFind = function(search) { +List.prototype.fuzzyFind = function(search, back) { var index = this.getItemIndex(this.selected); + var start = this.selected + (back ? -1 : 1); + var finder = typeof search === 'string' + ? function(item) { return !!~item.indexOf(search); } + : search.test.bind(search); - for (var i = 0; i < this.ritems.length; i++){ - if (this.ritems[i].indexOf(search) === 0) { - return i; + if (!back) { + for (var i = start; i < this.ritems.length; i++){ + if (finder(this.ritems[i])) return i; + } + for (var i = 0; i < start; i++){ + if (finder(this.ritems[i])) return i; + } + } else { + for (var i = start; i >= 0; i--){ + if (finder(this.ritems[i])) return i; + } + for (var i = this.ritems.length - 1; i > start; i--){ + if (finder(this.ritems[i])) return i; } }