UNPKG

readline-vim

Version:

Adds vim bindings to nodejs readline.

100 lines (77 loc) 2.71 kB
'use strict'; var utl = require('./utl') , log = utl.log , logl = utl.logl , stringifyKey = require('stringify-key') , parseKey = require('parse-key') ; module.exports = function createInsertMode(rli, vim, normalMode, original_ttyWrite) { var seq = { keys: [], last: undefined } , self = {}; function matchSequence(mapped) { var fastEnough = (new Date() - seq.last) <= vim.threshold; // delete sequence chars currently printed (exclude things like space) fastEnough && seq.keys.slice(-1) .filter(function (x) { return x.length === 1; }) .forEach(rli._deleteLeft.bind(rli)); self.clearSequence(); if (!fastEnough) return false; if(utl.isEsc(mapped)) normalMode(); return true; } function tryMatchImmediate(key) { var keyStr = stringifyKey(key) , mapStr = vim.map.matchInsert(keyStr) , mapKey; if (!mapStr) return true; mapKey = parseKey(mapStr); if(utl.isEsc(mapKey.name)) { normalMode(); return false; } original_ttyWrite.call(rli, mapKey.name, mapKey); return false; } // returns true if we are to write to terminal function tryMatchSequence(key) { seq.keys.push(key.name); // remember when last key was entered so we can decide if it counts as sequence or not var m = vim.map.matchInsert(seq.keys) // assume we'll match no complete sequence and therefore will want to print keyed char , passThru = true; if (!m) { // in case we buffered some keys hoping for a complete sequence, loose hope now self.clearSequence(); } else if (m === true) { // we hope for a future match } else if (matchSequence(m)) { // we matched our sequence and therefore will not print the char passThru = false; } if (passThru) seq.last = new Date(); return passThru; } self.clearSequence = function() { while(seq.keys.pop()); }; /** * Handles a given input in insert mode, including applying key mappings * * @name handleInput * @function * @param code {String} key code * @param key {Object} key * @return {Boolean} * false if the input was fully handled * true if it still needs to be handled and thus passed thru to original ttyWrite */ self.handleInput = function(code, key) { var passThru; // normal mode via escape or ctrl-[ if (key.name == 'escape') return normalMode(); if (key.name == '[' && key.ctrl) return normalMode(); passThru = utl.hasMeta(key) ? tryMatchImmediate(key) : tryMatchSequence(key); if (passThru) original_ttyWrite.apply(rli, arguments); }; return self; };