A language server for ESMValTool recipes, and a Visual Studio Code extension that uses it.
The server checks recipes while you write them, with the same checks that ESMValCore runs before running a recipe. Problems are shown at the line where they occur. The server runs in the Python environment where ESMValTool is installed, so the checks match your installation: the preprocessor functions, the projects in your configuration, the CMOR tables, and, if ESMValTool is installed, the authors and references it defines.
- Problems in recipes, as you type: unknown preprocessor functions and arguments, invalid values, missing keys, unknown projects and MIP tables, keys that are defined more than once, and YAML syntax errors.
- Completion of keys and values: preprocessor functions and their
arguments, facets, projects, the MIP tables of the project, and the
branding suffixes of the variable; the preprocessors and tasks defined in
the recipe, and the datasets of the variable group for
reference_datasetandalternative_dataset; and, if ESMValTool is installed, its diagnostic scripts, authors, and references. Keys are inserted with the arguments they require or their default value. - Completion of the facets of datasets, such as
dataset,exp,ensemble,timerange,start_year, andend_year, with the values of the available datasets that match the other facets of the variable and dataset, including its supplementary variables. The values are found on the ESGF indices that are enabled in the intake-esgf configuration, so the facets in the recipe are sent to these indices, and in the other data sources that are configured in ESMValCore, such as local directories. The facets of the other data sources that can be completed are those that the data source can search for, for example the facets in the templates of the paths of local data.timerange,start_year, andend_yearare only completed from ESGF onceexpis given. The accuracy of the values depends on the metadata provided by ESGF. Finding the values usually takes less than a second; until then, the values that the recipe schema allows are suggested. The values are remembered for 2 hours, or for 10 minutes if an index or other data source could not be searched. To get fresh suggestions, for example for local files that you just added or after changing the indices in the intake-esgf configuration, restart the language server: in Visual Studio Code, press Ctrl+Shift+P (Cmd+Shift+P on macOS) and run ESMValTool: Restart Language Server; in Emacs, runM-x eglot-reconnect. - Documentation of preprocessor functions and other keys, their values, and
preprocessors, with default values, when you hover over them.
Hovering over the value of a facet, such as
dataset,exp,activity,institute,grid, orensemble, shows its description in the controlled vocabulary of the project, for example CMIP6 or CMIP7, that is included in the CMOR tables that ESMValCore uses. CMIP7 models are described by, and linked to, their Essential Model Documentation, which is downloaded when you hover over them. Hovering over the value of theprojectfacet, such asCMIP6, links to the website of the project, or for projects without a website, such asOBS6,native6, orICON, to the ESMValTool or ESMValCore documentation. If ESMValTool is installed, hovering over an author shows their name and institute, with links to their ORCID and GitHub profile, hovering over a project, theme, or realm shows its definition inconfig-references.yml, and hovering over a reference shows its first author, year, and title, with a link to its DOI. If the bibtex file of a reference cannot be read, its content is shown. The server readsconfig-references.ymland the list of bibtex files only once, so restart it after changing that file or adding a bibtex file. In Visual Studio Code, press Ctrl+Shift+P (Cmd+Shift+P on macOS) and run ESMValTool: Restart Language Server; in Emacs, runM-x eglot-reconnect. - Errata of the datasets in a recipe, from the
ESGF errata service, shown on the line of the
dataset with their status and a link to the description.
They are shown as information, to distinguish them from errors and warnings
about the recipe itself.
Resolved errata are only shown for a dataset with an affected
version. To find them, the project, name, and experiment of each dataset are sent to the service, which can take up to a minute for a recipe with many models. The answers are kept for a day. Turn this off with the settingesmvaltool.languageServer.erratain Visual Studio Code, or with the initialization optionerratain other editors. - Go to the definition of a preprocessor, of a task listed in
ancestors, of the dataset inreference_datasetoralternative_dataset, or of a diagnostic script. If ESMValTool is installed, go to the definition of an author, project, theme, or realm inconfig-references.yml, or open the bibtex file of a reference.
Other tools also use files named like recipes, for example recipe.yaml of
conda-forge.
The server ignores files that are not ESMValTool recipes: files with
top-level keys, none of which is documentation, datasets,
preprocessors, or diagnostics.
Planned: running a recipe from the editor.
The server requires ESMValCore v2.16 or later. Install it in the environment where ESMValTool is installed:
pip install esmvaltool-language-serverThen set up your editor as described below.
Other editors that support the language server protocol, such as
Neovim and Sublime Text with the
LSP package, can start the server with the
command esmvaltool-language-server --stdio, which communicates over stdin
and stdout.
Install the ESMValTool extension.
It uses the Python interpreter that is selected in the
Python extension,
or the one in the setting esmvaltool.languageServer.pythonPath.
In a workspace with multiple folders, put this setting in the workspace
settings: Visual Studio Code ignores it in the settings of a folder.
The extension checks files whose name starts with recipe and ends with
.yml or .yaml.
Suggestions are shown while you type. To show them at any other point, for example on an empty line or after the colon of a key, press Ctrl+Space. Press Ctrl+Space again while the suggestions are shown to show or hide the documentation of the selected suggestion.
If the language server cannot run, for example because it is not installed in the selected environment, the extension falls back to checking recipes against the recipe JSON Schema with the YAML extension, if that is installed. The schema is generated by the ESMValCore installed in the selected environment, or, if that is not possible, the schema of the latest ESMValCore release is used. The language status item of YAML files, shown in the status bar, says which of the two is used. The language server reports the same problems as the schema, so do not configure the YAML extension to use the recipe schema yourself: the problems would be shown twice. After switching from the schema to the language server, the problems found with the schema are shown until the recipe is edited.
Use Eglot, which is included in Emacs 29 and later. Add this to your Emacs configuration:
(define-derived-mode esmvaltool-recipe-mode yaml-mode "Recipe"
"Major mode for ESMValTool recipes.")
(add-to-list 'auto-mode-alist
'("/recipe[^/]*\\.ya?ml\\'" . esmvaltool-recipe-mode))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'((esmvaltool-recipe-mode :language-id "yaml")
. ("esmvaltool-language-server" "--stdio"))))
(add-hook 'esmvaltool-recipe-mode-hook #'eglot-ensure)This defines a mode for recipes, so the server is only used for recipes and
not for other YAML files.
It requires yaml-mode; if you use
yaml-ts-mode instead, replace yaml-mode by yaml-ts-mode.
If the environment where the server is installed is not active when Emacs
starts, replace "esmvaltool-language-server" by the full path to the
command, for example "/path/to/env/bin/esmvaltool-language-server".
Problems are shown with Flymake, completion works with
completion-at-point (C-M-i), documentation is shown by ElDoc, and M-.
goes to a definition.
To turn off the errata of datasets, add :initializationOptions (:errata :json-false) after "--stdio" in the command above.
The development environment is managed with pixi.
It uses the development version of ESMValCore from GitHub; to use a local
copy instead, see the comment in pyproject.toml.
pixi run test # run the tests and measure coverage
pixi run -e py312 test # run the tests with the oldest Python
pixi run test -m "not network" # run the tests without internet access
pixi run test-vscode # run the extension and server in VSCode
pixi run pre-commit install # check the code before each commit
pixi run pre-commit run -a # check all code nowThe pre-commit hooks run ruff and pyrefly from the pixi environment, and
ESLint and Prettier from client/node_modules, so run npm install in the
client directory first.
The Visual Studio Code extension has these commands, to be run in the
client directory:
npm run compile # check the types and bundle the extension
npm run lint # check the code with ESLint
npm run format # format the code with Prettier
npm run package # build a package that can be installedThe tests marked network need internet access.
They check the Essential Model Documentation of CMIP7 models, the API of the
ESGF errata service, and the links in the recipe schema and in the documentation
shown when hovering over tags, references, and facets.
Links to the latest documentation of ESMValCore and ESMValTool are checked
against the documentation of the development versions that the server is
developed with; to use other documentation, set ESMVALCORE_DOCS or
ESMVALTOOL_DOCS to its URL or to a local build directory, for example
ESMVALCORE_DOCS=../esmvalcore/doc/build/html/ pixi run pytest tests/test_links.py.
pixi run test-vscode downloads VSCode, starts it with the extension, and
checks that the problems, completion, hover, and go to definition work.
Set VSCODE_VERSION to test a version other than the latest one.
To try the extension yourself, open the client directory in Visual Studio Code and
press F5.
In the window that opens, set esmvaltool.languageServer.pythonPath to the
Python interpreter of the pixi environment, which is shown by
pixi run which python.
Apache License 2.0, see LICENSE.