复制粘贴时处理 Node.js REPL 中的自动缩进

Handling auto indent in Node.js REPL when copy pasting

我需要了解如何解决我的问题。我有 LIPS 的 REPL 我的 Scheme based LISP in JavaScript 并且我有 node.js 使用 readline 的 REPL。我需要解决的最后一件事是在复制粘贴已经有缩进的代码片段时修复双重缩进。

我有这样的代码:

var highlight = require('../../prism-cli/index.js'); // temporary local copy
rl._writeToOutput = function _writeToOutput(stringToWrite) {
    rl.output.write(highlight(stringToWrite, 'scheme', true));
};
process.stdin.on('keypress', (c, k) => {
    setTimeout(function() {
        rl._refreshLine(); // force refresh colors
    }, 0);
});
boostrap(interp).then(function() {
    rl.on('line', function(line) {
        code += line + '\n';
        try {
            if (balanced_parenthesis(code)) {
                rl.pause();
                prev_eval = prev_eval.then(function() {
                    var result = run(code, interp);
                    code = '';
                    return result;
                }).then(function(result) {
                    if (process.stdin.isTTY) {
                        print(result);
                        if (newline) {
                            // readline don't work with not endend lines
                            // it ignore those so we end then ourselfs
                            process.stdout.write("\n");
                            newline = false;
                        }
                        if (multiline) {
                            rl.setPrompt(prompt);
                            multiline = false;
                        }
                        rl.prompt();
                    }
                    rl.resume();
                }).catch(function() {
                    if (process.stdin.isTTY) {
                        if (multiline) {
                            rl.setPrompt(prompt);
                            multiline = false;
                        }
                        rl.prompt();
                    }
                });
            } else {
                multiline = true;
                var ind = indent(code, 2, prompt.length - continuePrompt.length);
                rl.setPrompt(continuePrompt);
                rl.prompt();
                var spaces = new Array(ind + 1).join(' ');
                if (terminal) {
                    rl.write(spaces);
                } else {
                    process.stdout.write(spaces);
                    code += spaces;
                }
            }
        } catch (e) {
            console.error(e.message);
            code = '';
            rl.prompt();
        }
    });
}).catch(function() {
    console.error('Internal Error: boostrap filed');
});

indent 函数计算需要在下一行添加的 space 的数量,当我手动输入代码时这工作正常但是当我用缩进复制粘贴代码时我最终双缩进。

我正在寻找解决此问题的解决方案,我对在终端 stdout 中编辑文本并在输入文本后通过删除 space 重写每一行的解决方案感到满意。我可以在每一行之后我可以更正上一行,但不知道如何。

我还想知道是否有办法检测用户是否输入了 space(实际按键)。

我无法检查行开头是否有 space,因为缩进发生在实际行之前。

我能够通过使用 ANSI 代码修补终端中的前一行来解决我的问题,另一个解决方法是我能够语法突出显示复制粘贴时不起作用的前一行代码:

boostrap(interp).then(function() {
    rl.on('line', function(line) {
        code += line + '\n';
        var format, spaces, stdout;
        var lines = code.split('\n');
        // fix previous line
        if (lines.length > 1) {
            var prev_line = lines[lines.length - 2].replace(/^\s+/, '');
            if (lines.length > 2) {
                var prev = lines.slice(0, -2).join('\n');
                fs.appendFileSync('lips.log', prev + '\n');
                var i = indent(prev, 2, prompt.length - continuePrompt.length);
                spaces = new Array(i + 1).join(' ');
                lines[lines.length - 2] = spaces + prev_line;
                code = lines.join('\n');
                stdout = continuePrompt + spaces;
            } else {
                stdout = prompt;
            }
            stdout += highlight(prev_line, 'scheme', true);
            // ANSI Codes: 1F move to the begining of prev line
            //             K clear from cursor to the end of the line
            format = '\x1b[1F\x1b[K' + stdout + '\n';
            process.stdout.write(format);
        }
        try {
            // rest of the code
        } catch (e) {
            console.error(e.message);
            code = '';
            rl.prompt();
        }
    });
}).catch(function() {
    console.error('Internal Error: boostrap filed');
});