Как написать расширение скобок для нового языка?

Я пишу расширение скобок для нового текстового языка, который представляет собой смесь html и handlebars + javascript. И я хочу написать режим кода, используя существующие режимы CodeMirror, например. htmlmixed, javascript, руль.

Это то, что у меня есть сейчас (main.js),

define(function (require, exports, module) {

    var CodeMirror = brackets.getModule("thirdparty/CodeMirror/lib/codemirror"),
        LanguageManager = brackets.getModule("language/LanguageManager");

    CodeMirror.defineMode('htmlbars', function (config, parserConfig) {

        var htmlMode = CodeMirror.getMode(config, "htmlmixed"),
            javascriptMode = CodeMirror.getMode(config, "javascript"),
            handlebarsMode = CodeMirror.getMode(config, "handlebars");

        function html(stream, state) {
            var style = htmlMode.token(stream, state.htmlState);
            return style; 
        }

        return {
            startState: function() {
                var state = htmlMode.startState();
                return {token: html, localMode: null, localState: null, htmlState: state};
            },

            copyState: function(state) {
                if (state.localState)
                    var local = CodeMirror.copyState(state.localMode, state.localState);
                    return { token: state.token, localMode: state.localMode, localState: local,
                             htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
            },

            token: function(stream, state) {
                return state.token(stream, state);
            },

            indent: function(state, textAfter) {
                if (!state.localMode || /^\s*<\//.test(textAfter))
                    return htmlMode.indent(state.htmlState, textAfter);
                else if (state.localMode.indent)
                    return state.localMode.indent(state.localState, textAfter);
                else
                    return CodeMirror.Pass;
            },

            innerMode: function(state) {
                return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
            }
        };
    }); 

    CodeMirror.defineMIME("text/x-xhbs", "htmlbars");

    LanguageManager.defineLanguage("htmlbars", {
        name: "Htmlbars",
        mode: ["htmlbars", "text/x-hbs"],
        fileExtensions: ["xhbs"]
    });

});

Итак, что я хочу знать, так это то, как здесь можно определить использование режима javascript, если элемент начинается с <% и заканчивается на %> и т. д. ... в настоящее время он работает только для html

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

Спасибо! :)


person Jerad Rutnam    schedule 05.08.2016    source источник


Ответы (1)


Этого легко добиться с помощью мультиплексного режима CodeMirror,

e.g.

define(function (require, exports, module) {

    var CodeMirror = brackets.getModule("thirdparty/CodeMirror/lib/codemirror"),
        LanguageManager = brackets.getModule("language/LanguageManager");

    brackets.getModule(["thirdparty/CodeMirror/mode/handlebars/handlebars", "thirdparty/CodeMirror/mode/javascript/javascript"], function () {
        CodeMirror.defineMode("htmlbars", function (config) {
            return CodeMirror.multiplexingMode(
                CodeMirror.getMode(config, "text/html"),
                {
                    open: "<%",
                    close: "%>",
                    mode: CodeMirror.getMode(config, "javascript"),
                    parseDelimiters: true
                },
                {
                    open: "{{",
                    close: "}}",
                    mode: CodeMirror.getMode(config, "handlebars"),
                    parseDelimiters: true
                }
            );
        });

        CodeMirror.defineMIME("text/x-xhbs", "htmlbars");

        LanguageManager.defineLanguage("htmlbars", {
            name: "Htmlbars",
            mode: ["htmlbars", "text/x-hbs"],
            fileExtensions: ["xhbs"]
        });
    });

});

Официальная демонстрация: https://codemirror.net/demo/multiplex.html

Надеюсь, это поможет кому-то еще. :)

person Jerad Rutnam    schedule 19.08.2016