How to dynamically set language according to file extension in monaco editor?

Viewed 6270

I am working on monaco-editor to show content of local code files, which may be written in various languages, so I am wondering how to dynamically set/change language of monaco editor according to the extension of file, or the first line of file without extension (like #!/usr/bin/env python).

Seems that monaco-editor itself does not come with this feature, but the VSCode does apparently.

I want to define such a method called checkLanguage(file_path), which takes a file path and returns the string that represents the language supported by monaco-editor. If the language cannot be determined, just return plain text.

monaco.editor.setModelLanguage(model, checkLanguage(file_path))

Supported languages: https://github.com/microsoft/monaco-languages

3 Answers

The languages already define the file extensions that they can handle, so it's possible to allow Monaco to choose an appropriate language by giving it the filename:

const model = monaco.editor.createModel(
  value,
  undefined, // language
  monaco.Uri.file(filename) // uri
)

editor.setModel(model)

I have found a useful npm library that can detect the programming language according to the file name or content, and implmented the language detection in my project like this:

  const langDetector = require('language-detect')
  const langMapper = require('language-map')
  // async way
  let lang=''
  langDetector(abs_path, (err, language) => {
  if (err) {
     console.log(err)
     lang = 'plaintext'
  } else {
     lang = langMapper[language].aceMode
  }
  // sync way
  lang = langMapper[langDetector.sync(abs_path)].aceMode

[1] The library link: https://github.com/blakeembrey/node-language-detect

[2] The complete code : https://github.com/Symbolk/SmartCommit/blob/master/src/components/utils/gitutils.js

I just have an object that looks something like this:

fileTypes: {
    css: 'css',
    js: 'javascript',
    json: 'json',
    md: 'markdown',
    mjs: 'javascript',
    ts: 'typescript',
}

When I create a model I call monaco.editor.createModel(file.content, fileTypes[file.extension]). You can obviously expand the list to include whatever you want. Maybe at some point they'll add in a mapping so you can initialize with just the extension.

In your case you could do monaco.editor.setModelLanguage(model, fileTypes[file_path.split['.'].pop()]). This will cover cases where you have a file with multiple periods, like test.min.js.

Related