【问题标题】:CodeMirror AutoComplete Custom ListCodeMirror 自动完成自定义列表
【发布时间】:2013-10-15 04:24:58
【问题描述】:

我对代码镜像中的自动完成功能有点困难。我想做的是两件事(我都在努力):

1) 我想为HTMLJavaScript 启用自动完成功能。 目前我一次只能使用例如:

 CodeMirror.commands.autocomplete = function (cm) {
     CodeMirror.showHint(cm, CodeMirror.hint.html);
 };

如何将CodeMirror.hint.javascriptHTML 添加到列表中?

2) (更重要的) -- 如何将自定义变量添加到来自 HTML 的提示列表中,该区域是从 ajax 调用中检索到的.....

即我想让下拉菜单显示来自 html 提示的当前数据列表,然后添加自定义条目,例如 ##SomeCode1####SomeCode2##

我有两个问题。首先,当我尝试对 'html-hint.js' 文件中的值进行硬编码时,所有值都会附加 <... 这不是我想要的。

第二个问题是我相信我必须编写一个新的“html-hint.js”文件对吗?我的意思是没有办法在上面的CodeMirror.hint.html 中的'options'参数中传递任何东西,基本上合并两个列表。

我的客人一和客人二想起来有点像...将两个自动完成的值列表合并在一起。

我猜框架中已经没有任何东西了,我必须编写一个自定义提示文件,对吗?

任何指针将不胜感激。示例代码会很棒。

【问题讨论】:

    标签: codemirror


    【解决方案1】:

    如果您不指定提示函数,则 show-hint 插件将采用为完成发生的 local 模式定义的提示帮助函数,因此 CodeMirror.hint.javascript 在 @ 987654322@ 代码和 HTML 中的 CodeMirror.hint.html

    如果您需要添加自己的完成逻辑,您可以通过简单地用您自己的代码覆盖它们来替换(或包装)这些函数。

    这是一个粗略的示例 hack,它总是在 JavaScript 补全中添加“bozo”:

    var orig = CodeMirror.hint.javascript;
    CodeMirror.hint.javascript = function(cm) {
      var inner = orig(cm) || {from: cm.getCursor(), to: cm.getCursor(), list: []};
      inner.list.push("bozo");
      return inner;
    };
    

    【讨论】:

    • 非常有帮助。也许您可以扩展您的答案如何进行真正的自动完成,例如当我输入“bo”时,只会建议“bozo”而不是 f.e. “foobar”,它没有在“bo”后面添加“bozo”,而是用“bozo”替换“bo”。谢谢:)
    • Marijn,上面的代码没有按预期工作。 “bozo”这个词确实被添加到列表中,但是当我输入“b-o-z ...”时,它没有被选中。相反,如果我的页面有一个名为“monkey”的函数,当我输入“m-o-n...”时,该名称确实被选中。此外,“bozo”这个词会总是显示,而不仅仅是在用户键入相似词时。这不是自动完成的预期行为。有没有其他方法可以做到这一点?
    • hint函数负责过滤。如果它只是无条件地添加一个单词,如我的示例所示,则不会发生过滤。但是如果你愿意,你可以在那里添加你自己的逻辑。
    【解决方案2】:

    感谢@Marjin 的简要解释,但由于它不包括过滤并且很多人需要它,这就是我在mongoclient 中按照 Marjin 的回答所做的。并部分获得了here的帮助

    附言不要忘记用你的改变提示,因为我使用的是javascript,所以我已经改变了javascript提示。

    CodeMirror.hint.javascript = function (editor) {
            var list = Session.get(Template.strSessionDistinctFields) || [];
            var cursor = editor.getCursor();
            var currentLine = editor.getLine(cursor.line);
            var start = cursor.ch;
            var end = start;
            while (end < currentLine.length && /[\w$]+/.test(currentLine.charAt(end))) ++end;
            while (start && /[\w$]+/.test(currentLine.charAt(start - 1))) --start;
            var curWord = start != end && currentLine.slice(start, end);
            var regex = new RegExp('^' + curWord, 'i');
            var result = {
                list: (!curWord ? list : list.filter(function (item) {
                    return item.match(regex);
                })).sort(),
                from: CodeMirror.Pos(cursor.line, start),
                to: CodeMirror.Pos(cursor.line, end)
            };
    
            return result;
        };
    

    【讨论】:

    • 是否可以仅将自定义提示列表添加到某个 CodeMirror 实例?
    • ofc,在这种情况下,您需要为 codemirror 创建自己的模式,stackoverflow.com/questions/24433552/…
    • 我不确定我们是否相互理解。我在具有自动完成功能的页面上有两个 CodeMirror“sql 模式”实例。除了内置的 sql 关键字之外,我还需要添加一些自定义关键字。我不明白我为什么要创建一个新模式。除此之外,我正在寻找一种从该列表中动态添加/删除关键字的方法
    • 不,当它们来自用户输入时,您需要对每个特殊字符进行转义,例如对于 @ 符号,您需要像 \@ 一样编写它,然后再使用 RegExp 构造函数
    • 非常感谢@SercanOzdemir,我一整天都在努力理解这一点。
    【解决方案3】:

    如果它对某人有帮助,这是一个结合了@Marjin 和 Sercan 部分内容的版本。它使用默认提示,并添加了我们的附加功能。

    const hintWords=["trap.our()", "trap.hints()", "trap"]; // custom hints
    const jsHinter = CodeMirror.hint.javascript; // copy default hinter for JavaScript
    CodeMirror.hint.javascript = function (editor) {
        // Find the word fragment near cursor that needs auto-complete...
        const cursor = editor.getCursor();
        const currentLine = editor.getLine(cursor.line);
        let start = cursor.ch;
        let end = start;
        const rex=/[\w.]/; // a pattern to match any characters in our hint "words"
        // Our hints include function calls, e.g. "trap.getSource()"
        // so we search for word charcters (\w) and periods.
        // First (and optional), find end of current "word" at cursor...
        while (end < currentLine.length && rex.test(currentLine.charAt(end))) ++end;
        // Find beginning of current "word" at cursor...
        while (start && rex.test(currentLine.charAt(start - 1))) --start;
        // Grab the current word, if any...
        const curWord = start !== end && currentLine.slice(start, end);
        // Get the default results object from the JavaScript hinter...
        const dflt=jsHinter(editor);
        // If the default hinter didn't hint, create a blank result for now...
        const result = dflt || {list: []};
        // Set the start/end of the replacement range...
        result.to=CodeMirror.Pos(cursor.line, end);
        result.from=CodeMirror.Pos(cursor.line, start);
        // Add our custom hintWords to the list, if they start with the curWord...
        hintWords.forEach(h=>{if (h.startsWith(curWord)) result.list.push(h);});
        result.list.sort(); // sort the final list of hints
        return result;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 1970-01-01
      相关资源
      最近更新 更多