2

VSCode has the great feature of per-language user snippets (e.g. in xml.json).

Is there a way to map those snippets to file extensions?

My situation: I develop a lot of xml lately. We have roughly three xsd files and name instances of them with file extensions (so an instance of foo.xsd is named my-instance.foo rather than my-instance.xml). I build the most common parts as user snippets to save my time. However the different xsds create similar elements with different meanings (e.g. one creates <foo bar="baz"/>, one creates <foo baz="bar"/>), so defining a user snippet with prefix "foo" for the xml language would be ambique.

I could prefix the prefixes (creating e.g. afoo and bfoo), but this feels unnatural. Is there a better way to say "although both foos belong to the xml language, one belongs to files of type x and one to y"?

1 Answer 1

1

Visual Studio Code doesn't currently supoport different snippets per file extension that work on the same language.

But there is a hacky workaround for it by defining a separate language for xsd. Decide yourself if you want to do it. I tested it on Windows with version 0.8.0 (insider preview).

  1. Go to the plugins folder of VSCode: %CODE%\resources\app\plugins and create a copy of vs.language.xml. Name the copied folder vs.language.xsd.

  2. Open vs.language.xsd in VSCode.

  3. Replace the content of ticino.plugin.json with

    {
        "pluginId": "vs.language.xsd",
        "activationEvents": ["textModel:xsd"],
        "mainModule": "./out/xmlMain",
        "contributes": {
            "language": [{
                "id": "xsd",
                "extensions": [ ".xsd", ".foo"],
                "firstLine" : "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
                "aliases": [ "XSD", "xsd" ],
                "mimetypes": ["text/xml", "application/xml", "application/xaml+xml"]
            }]
        },
        "scripts": {
            "compile": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../gulpfile.plugins.js compile-plugin:vs.language.xsd"
        },
        "_bundling": [
            { "name": "./out/xmlMain" },
            { "name": "./out/xmlWorker" }
        ]
    }
    
  4. Open to xmlDef.json. Change the value of displayName from XML to XSD. Change the value of name from xml to xsd.

  5. List Replace the content of xmlMain.js with

    'use strict';
    define(["require", "exports", './xmlDef', 'monaco'], function (require, exports, languageDef, monaco) {
        function activate() {
            monaco.Modes.registerMonarchDefinition('xsd', languageDef.language);
            var myWorker = monaco.Modes.loadInBackgroundWorker(require.toUrl('./xmlWorker.js'));
            function format(resource, range, options) {
                return myWorker.then(function (w) {
                    var model = monaco.Services.ModelService.getModel(resource);
                    var value = range ? model.getValueInRange(range) : model.getValue();
                    if (value.length < 1024 * 1024) {
                        return w.beautify(value, {
                            indent_size: options.insertSpaces ? options.tabSize : 1,
                            indent_char: options.insertSpaces ? ' ' : '\t',
                            wrap_line_length: 256
                        });
                    }
                    else {
                        return null;
                    }
                }).then(function (result) {
                    if (result) {
                        return [{
                                range: range,
                                text: result
                            }];
                    }
                    else {
                        return null;
                    }
                });
            }
            monaco.Modes.FormattingSupport.register('xsd', {
                formatDocument: function (resource, options) {
                    return format(resource, null, options);
                },
                formatRange: function (resource, range, options) {
                    return format(resource, range, options);
                }
            });
        }
        exports.activate = activate;
    });
    
  6. Restart VSCode. Now you are able to go to File -> Preferences - User Snippets and select the language XSD. You can define all .xsd and .foo related snippets here.

As I mentioned before: This is really hacky. The code highlighting looks slightly different in XSD files after applying this. If you don't like the result then you simply need to delete the folder vs.language.xsd and everything works like it did before.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow man, thanks for that insight into vscode. Bad that it doesn't support it out-of-the-box yet. I'll test it as soon as I find the time (and accept then, in the meantime I just upvoted your answer).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.