如何在NodeJS REPL中使用“反向交互式search”?

我想在NodeJS REPL中使用reverse interactive search ,像bashirb Ctrl + r

Ctrl + r不会触发交互式search。 有没有办法在Nodejs REPL中使用该函数?

我使用的是MacOS Sierra, v8.5.0的版本是v8.5.0

这个问题在最近我可怜的foo()博客文章中回答了…

在Node的REPL中可以使用命令历史中的反向search吗?

目前看来是不可能的。 Node REPL允许将历史logging保存到文件中,稍后加载它,但不允许对其进行反向search。

所以看起来反向历史search并不是REPL原生支持的。

但是,您可以安装rlwrap实用程序并在Node REPL上运行它,以提供类似的function。 REPL文档网站提供了一些基本的指导来启动和运行。 我有点好奇,幕后发生了什么,所以再多一点谷歌search从学习节点:移动到服务器端的这一部分,进一步详细了解与使用rlwrap相关的权衡。 例如…

像rlwrap一样有帮助,每次我们input一个不返回值的expression式时,我们仍然没有定义。 但是,我们可以通过创build我们自己的定制REPL来调整此function和其他function,接下来讨论。

我看到赏金即将结束…我可以拥有吗? 如果我告诉你:

如果您熟悉历史loggingsearch,并且希望将其用作备选项,请跳至“代码”部分。

你熟悉zsh的历史search吗? 这几乎就像反向search,除了在命令行上input内容并按up箭头键之后才能开始search。 我发现它比反向search更快,更经常使用。 不利的一面(在我看来是次要的)是你不能在search后更新你的原始search查询,除非你通过“退后”来返回它。 例如:

历史(自上而下)

 foo bar foo-ish fubar ... 

在你的提示下:

 > fo 

按下

 > foo 

按下

 > foo-ish 

按下

 > foo 

按下

 > fo 

注意:只要您更改search结果并再次点击,被更改的文本将成为您的新查询。

代码

 const PROMPT = '> '; // history search let input = ''; let searchInput = input; let searchResults = []; let searchResultIndex = 0; process.stdin.on('keypress', (_, key) => { // update 'input' on changes, excluding history if (input !== server.line && !['up', 'down'].includes(key.name)) { input = server.line; } // search is initiated if a user presses the 'up' key after having inputted if (input !== '' && ( key.name === 'up' || (key.name === 'down' && searchResultIndex > 0) )) { // reset on fresh search or if user changed input during search if (searchInput !== input) { searchResultIndex = 0; // first search result is always user's input searchResults = [input, ...server.history.filter(item => item.includes(input))]; searchInput = input; } const increment = key.name === 'up' ? 1 : -1; searchResultIndex = Math.min(searchResultIndex + increment, searchResults.length - 1); server.historyIndex = -1; server.line = ''; process.stdout.clearLine(); process.stdout.cursorTo(0); const result = searchResults[searchResultIndex]; process.stdout.write(PROMPT + result); server.cursor = result.length; server.line = result; } }); 

奖励 – 实施持续的历史:

 const HISTSIZE = 100; const server = repl.start({ prompt: PROMPT, historySize: HISTSIZE, removeHistoryDuplicates: true, }); // load history or create file historyFile = path.join(path.dirname(require.main.filename), '.repl_history'); try { fs.statSync(historyFile); fs.readFileSync(historyFile, 'utf8') .split('\n') .filter(line => line.trim()) .map(line => server.history.push(line)); } catch (e) { console.log(e); fs.closeSync(fs.openSync(historyFile, 'w')); } server.on('exit', () => { // save history fs.writeFileSync(historyFile, server.history.slice(0, HISTSIZE).join('\n')); console.log('Thank you. Come again.'); process.exit(); });