代码镜像 - 最小行数

Codemirror - minimum lines number

本文关键字:镜像 代码      更新时间:2023-09-26

Anbody确实有一个最小行数的解决方案 - 在Codemirror中?

最小高度对我有用,但不插入空行的高度。

.JS

var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
    lineNumbers: true,
    gutter: true,
    lineWrapping: true
});

.CSS

.CodeMirror-scroll {
  overflow: auto;
  height: auto; overflow: visible;
  position: relative;
  outline: none;
  min-height: 300px; /* the minimum height */
}

也许有一个简单的解决方案可以为此插入空行?

删除min-height: 300px;并使用新行作为起始值初始化编辑器:

var minLines = 3;
var startingValue = '';
for (var i = 0; i < minLines; i++) {
    startingValue += ''n';
}
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
    lineNumbers: true,
    gutter: true,
    lineWrapping: true,
    value: startingValue
});

目前,CodeMirror 的 value 选项似乎对 2.21 版本没有影响。 初始化后使用 setValue() 可以轻松绕过此操作:

///...
// initialize as before, omitting the value option
editor.setValue(startingValue);

注意:确保不要设置autoClearEmptyLines: true因为它会冲突并取消插入的空行。

所以伙计们我得到了解决方案。出于任何原因,编辑器都不会从配置选项中获取value,因此我在它之后设置了值。@Eliran谢谢,我使用您的方法来设置值。

editor.setValue(startingValue);

演示

http://jsfiddle.net/vujLv/1/

editor.setValue( value + "'n".repeat(10) )

在这里,我定义了一个CodeMirror选项"minLines"并操作一些键绑定和历史记录。

这将禁止 CodeMirror 实例的行低于 minLines 值,而不仅仅是在 init 上设置这么多行。

你可以把它放在一个名为"minLines.js"的文件中,然后把它放在/addons中,就可以使用了。

这是我的Codepen示例。

// set minimum number of lines CodeMirror instance is allowed to have
(function (mod) {
    mod(CodeMirror);
})(function (CodeMirror) {
    var fill = function (cm, start, n) {
        while (start < n) {
            let count = cm.lineCount();
            cm.replaceRange("'n", { line: count - 1 }), start++;
            // remove new line change from history (otherwise user could ctrl+z to remove line)
            let history = cm.getHistory();
            history.done.pop(), history.done.pop();
            cm.setHistory(history);
            if (start == n) break;
        }
    };
    var pushLines = function (cm, selection, n) {
        // push lines to last change so that "undo" doesn't add lines back
        var line = cm.lineCount() - 1;
        var history = cm.getHistory();
        history.done[history.done.length - 2].changes.push({
            from: {
                line: line - n,
                ch: cm.getLine(line - n).length,
                sticky: null
            },
            text: [""],
            to: { line: line, ch: 0, sticky: null }
        });
        cm.setHistory(history);
        cm.setCursor({ line: selection.start.line, ch: selection.start.ch });
    };
    var keyMap = {
        Backspace: function (cm) {
            var cursor = cm.getCursor();
            var selection = {
                start: cm.getCursor(true),
                end: cm.getCursor(false)
            };
            // selection
            if (selection.start.line !== selection.end.line) {
                let func = function (e) {
                    var count = cm.lineCount(); // current number of lines
                    var n = cm.options.minLines - count; // lines needed
                    if (e.key == "Backspace" || e.code == "Backspace" || e.which == 8) {
                        fill(cm, 0, n);
                        if (count <= cm.options.minLines) pushLines(cm, selection, n);
                    }
                    cm.display.wrapper.removeEventListener("keydown", func);
                };
                cm.display.wrapper.addEventListener("keydown", func); // fires after CodeMirror.Pass
                return CodeMirror.Pass;
            } else if (selection.start.ch !== selection.end.ch) return CodeMirror.Pass;
            // cursor
            var line = cm.getLine(cursor.line);
            var prev = cm.getLine(cursor.line - 1);
            if (
                cm.lineCount() == cm.options.minLines &&
                prev !== undefined &&
                cursor.ch == 0
            ) {
                if (line.length) {
                    // add a line because this line will be attached to previous line per default behaviour
                    cm.replaceRange("'n", { line: cm.lineCount() - 1 });
                    return CodeMirror.Pass;
                } else cm.setCursor(cursor.line - 1, prev.length); // set cursor at end of previous line
            }
            if (cm.lineCount() > cm.options.minLines || cursor.ch > 0)
                return CodeMirror.Pass;
        },
        Delete: function (cm) {
            var cursor = cm.getCursor();
            var selection = {
                start: cm.getCursor(true),
                end: cm.getCursor(false)
            };
            // selection
            if (selection.start.line !== selection.end.line) {
                let func = function (e) {
                    var count = cm.lineCount(); // current number of lines
                    var n = cm.options.minLines - count; // lines needed
                    if (e.key == "Delete" || e.code == "Delete" || e.which == 46) {
                        fill(cm, 0, n);
                        if (count <= cm.options.minLines) pushLines(cm, selection, n);
                    }
                    cm.display.wrapper.removeEventListener("keydown", func);
                };
                cm.display.wrapper.addEventListener("keydown", func); // fires after CodeMirror.Pass
                return CodeMirror.Pass;
            } else if (selection.start.ch !== selection.end.ch) return CodeMirror.Pass;
            // cursor
            var line = cm.getLine(cursor.line);
            if (cm.lineCount() == cm.options.minLines) {
                if (
                    cursor.ch == 0 &&
                    (line.length !== 0 || cursor.line == cm.lineCount() - 1)
                )
                    return CodeMirror.Pass;
                if (cursor.ch == line.length && cursor.line + 1 < cm.lineCount()) {
                    // add a line because next line will be attached to this line per default behaviour
                    cm.replaceRange("'n", { line: cm.lineCount() - 1 });
                    return CodeMirror.Pass;
                } else if (cursor.ch > 0) return CodeMirror.Pass;
            } else return CodeMirror.Pass;
        }
    };
    var onCut = function (cm) {
        var selection = {
            start: cm.getCursor(true),
            end: cm.getCursor(false)
        };
        setTimeout(function () {
            // wait until after cut is complete
            var count = cm.lineCount(); // current number of lines
            var n = cm.options.minLines - count; // lines needed
            fill(fm, 0, n);
            if (count <= cm.options.minLines) pushLines(cm, selection, n);
        });
    };
    var start = function (cm) {
        // set minimum number of lines on init
        var count = cm.lineCount(); // current number of lines
        cm.setCursor(count); // set the cursor at the end of existing content
        fill(cm, 0, cm.options.minLines - count);
        cm.addKeyMap(keyMap);
        // bind events
        cm.display.wrapper.addEventListener("cut", onCut, true);
    };
    var end = function (cm) {
        cm.removeKeyMap(keyMap);
        // unbind events
        cm.display.wrapper.removeEventListener("cut", onCut, true);
    };
    CodeMirror.defineOption("minLines", undefined, function (cm, val, old) {
        if (val !== undefined && val > 0) start(cm);
        else end(cm);
    });
});