0

我正在使用Readline模塊製作一個帶NodeJS的簡單CLI應用程序。我想自動完成用戶的輸入。對於這一點,我使用的模塊autocompletion functionNodeJS readline自動完成幾個單詞

function completer(line) { 
    const completions = '.help .error .exit .quit .q'.split(' '); 
    const hits = completions.filter((c) => c.startsWith(line)); 
    // show all completions if none found 
    return [hits.length ? hits : completions, line]; 
} 

有了這個功能,我能夠完成一個命令,但在同一行中沒有幾個命令:

例如:

(CLI App) > .e<tab> 
      .error .exit 

(CLI App) > .err<tab> 
(CLI App) > .error 

(CLI App) > .error .ex<tab> 
      .help .error .exit .quit .q 

我修改完成者的功能,僅保留自動完成的,用戶在寫當前命令的建議:

function completer(line) { 
    const completions = '.help .error .exit .quit .q'.split(' '); 
    const hits = completions.filter((c) => c.startsWith(line.split(' ').slice(-1))); 

    return [hits.length ? hits : completions, line]; 
} 

,我得到正確的建議,但用戶輸入並沒有改變:

(CLI App) > .e<tab> 
      .error .exit 

(CLI App) > .err<tab> 
(CLI App) > .error 

(CLI App) > .error .ex<tab> 
      .exit 
(CLI App) > .error .ex 

有什麼辦法解決?任何援助,你可以給予非常感激。

謝謝。

+0

如果只有一次命中,用命中替換'line'的最後部分怎麼樣?應該不難添加 –

+1

謝謝@ChrisSatchell。我替換了'line'的最後一部分,它的工作原理! –

回答

1

使用克里斯的提示我得到了一個解決方案:用擊中(當我只有一個)替換line的最後一部分。

我計算line(我想要自動完成的實際命令)的最後部分的長度,以將光標移動到此命令的開頭。然後,我得到所有的線減去當前的命令,我concat命中。最後,我將光標放在行的末尾。

我試圖使用docs的方法,但運氣不好:readline.cursorTo(stream, x, y)readline.moveCursor(stream, dx, dy)不適用於我。

readline.clearLine(stream, dir)方法清除所有行並且沒有'從光標向右'(我想要的行爲),儘管存在於doc中。

function completer(line) { 
    const completions = '.help .error .exit .quit .q'.split(' '); 
    let cmds = line.split(' '); 
    const hits = completions.filter((c) => c.startsWith(cmds.slice(-1))); 

    if ((cmds.length > 1) && (hits.length === 1)) { 
     let lastCmd = cmds.slice(-1)[0]; 
     let pos = lastCmd.length; 
     rl.line = line.slice(0, -pos).concat(hits[0]); 
     rl.cursor = rl.line.length + 1; 
    } 

    return [hits.length ? hits.sort() : completions.sort(), line]; 
}