jupyterlab / jupyterlab

JupyterLab computational environment.

Home Page:https://jupyterlab.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Define syntax highlighting for different file extensions

billgreenwald opened this issue · comments

Is there a way to define which syntax highlighting scheme the text editor should use for different file extensions? If not, it would be nice if there was a way to define it in the advanced settings editor

For example, nextflow is written in groovy, but by convention uses the .nf file extension; it would be nice to be able to tell jupyterlab to default to groovy highlighting for .nf files instead of activating it manually every time I open a file in the text editor.

commented

As far as I know, you will need to define a Jupyterlab extension that adds the filetype to JupyterLab. The core code would be something like:

  app.docRegistry.addFileType({
    name: 'NetFlow',
    displayName: 'NextFlow File',
    extensions: ['.ng'],
    mimeTypes: ['application/x-groovy'],  // or text/x-groovy?
    iconClass: 'jp-MaterialIcon nextflow_icon',
  });

Thanks @BoPeng for your answer. It would be nice to be able to do this just with a setting.

Did this get resolved? Or is still scheduled to be an update for a future release?

So I'm trying to do exactly that but for different file format. I have a file format that I want to open with the text editor (codemirror) and the syntax highlighter mathematica that is already there. So I did a extension and tried what @BoPeng suggested. But it's not working like I want it to. It's opening the text editor but it's not setting the language (syntaxe highlighter) correctly. I tough that the "mimeTypes" was the thing that specified to the text editor what syntax highlight to use, but apparently it's not the case. I tried many type of mimeTypes but it's not changing the result.

Here's my code:

import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application';
import "../style/index.css";


// const MIME_TYPE = 'application/vdn.reactivecore.trd';
// const TRD_MIME_TYPE = 'application/vnd.wolfram.mathematica';
const TRD_MIME_TYPE = 'application/json';
// const OWL_MIME_TYPE = 'text/xml';


/**
 * Add the ReactiveCore file type into Jupyterlab document registery.
 */
const registerReactiveCoreFileType = (app: JupyterFrontEnd) => {
    app.docRegistry.addFileType({
        name: "TRD",
        displayName: "TRD File",
        extensions: [".trd", ".rrx", ".rrl", ".rrd", ".rr"],
        mimeTypes: [TRD_MIME_TYPE],
        iconClass: "jp-MaterialIcon reactivecore_icon"
    });
}

/**
 * Initialization data for the jupyterlab-ext-reactivecore-filetype extension.
 */
const extension: JupyterFrontEndPlugin<void> = {
    id: 'jupyterlab-ext-reactivecore-filetype',
    autoStart: true,
    activate: (app: JupyterFrontEnd) => {
        console.log('JupyterLab extension jupyterlab-ext-reactivecore-filetype is activated!');
        registerReactiveCoreFileType(app)
    }
};

export default extension;

I also tried to do a Mime Renderer Extensions, but it's seem to only give you the possibility to do your own render, where I would simply like to use the already existing jupyterlab code editor (codemirror) with a specific syntax highlight.

So what can I did to have the behaviour I'm locking for?

I finally found a solution. The key is this little line: Mode.getModeInfo().push(). I found the answer by exploring the source code and with the help of #7143, so thanks @wolfv.

First, here's the complete code I used to associate file type to a specific text editor syntax highlight:

import { JupyterFrontEnd, JupyterFrontEndPlugin } from "@jupyterlab/application";
import { Mode } from "@jupyterlab/codemirror";
import "../style/index.css";


const RR_MIME_TYPE = "text/x-mathematica";
const OWL_MIME_TYPE = "text/xml";

/**
 * Add the ReactiveCore file type into JupyterLab document registry and the CodeMirror mode.
 */
const registerReactiveCoreFileType = (app: JupyterFrontEnd) => {
    Mode.getModeInfo().push({
        name: ".ReactiveCore RR",
        mime: RR_MIME_TYPE,
        mode: "mathematica",
        ext: ["trd", "rrx", "rrl", "rrd", "rr"]
    });

    Mode.getModeInfo().push({
        name: ".ReactiveCore OWL",
        mime: OWL_MIME_TYPE,
        mode: "xml",
        ext: ["owl"]
    });

    app.docRegistry.addFileType({
        name: "rr",
        displayName: "RR File",
        extensions: [".trd", ".rrx", ".rrl", ".rrd", ".rr"],
        mimeTypes: [RR_MIME_TYPE],
        iconClass: "jp-MaterialIcon reactivecore_icon",
        iconLabel: "",
        contentType: "file",
        fileFormat: "text"
    });

    app.docRegistry.addFileType({
        name: "owl",
        displayName: "OWL File",
        extensions: [".owl"],
        mimeTypes: [OWL_MIME_TYPE],
        iconClass: "jp-MaterialIcon reactivecore_icon",
        iconLabel: "",
        contentType: "file",
        fileFormat: "text"
    });

    /**
     * Code to see all CodeMirror mode available in JupyterLab and the whole application object for debug
     */
    // let test = Mode.getModeInfo();
    // console.log(test)
    // console.log(app)
}

/**
 * Initialization data for the jupyterlab-ext-reactivecore-filetype extension.
 */
const extension: JupyterFrontEndPlugin<void> = {
    id: "jupyterlab-ext-reactivecore-filetype",
    autoStart: true,
    activate: (app: JupyterFrontEnd) => {
        console.log("JupyterLab extension jupyterlab-ext-reactivecore-filetype is activated!");
        registerReactiveCoreFileType(app)
    }
};

export default extension;

You will need those 3 dependencies in your "package.json" for this code to work:
"@jupyterlab/application",
"@jupyterlab/codemirror",
"@types/codemirror"

About this code:

  1. The only concrete thing that docRegistry.addFileType() function does is to associate the file type with the image icon. Strangely enough, the mime type in the docRegistry.addFileType() and getModeInfo().push() don’t have to match for it to work. But "mime" and "mode" properties in getModeInfo().push() have to match the syntax highlight (CodeMirror mode) you want to use. To have a complete list of those available in JupyterLab and their properties, print the result of Mode.getModeInfo().
  2. It's the "ext" property in getModeInfo().push() that associate your file type to the syntax highlight you want.
  3. When you open your file, the "name" property in getModeInfo().push() will be displayed in the bottom left corner of the application (current syntax highlight of the editor) . But the first name in the CodeMirror mode list (alphabetically ordered) that match the mode/mime of the file, will be the one displayed. For example: in my RR file type, if I put "ReactiveCore RR" in the "name" property, it will display "Mathematica" as the current editor's syntax highlight. But since I put a dot in front of my"name" property, it showed my value instead (eg. ".ReactiveCore RR"). I don't think it's the intended behavior, but it's just how it works in the current version.

I hope this will be help some people with this problem 🙂

Hi, I'd like to permanently associate all files called "Snakefile" and files that end with "*.smk" to the python highlighter. Is this now possible in Jupyterhub? Maybe even on the project level?

Are there any updates on this issue?