From 73987a4301642601a92922c3f9741832b29c58d3 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Mon, 14 Jul 2025 23:03:49 +0200 Subject: [PATCH] vim-patch:e85a66a: runtime(erlang): Add support for triple-quoted strings and docstrings Erlang recently added the `-moduledoc` attribute as well as triple quoted strings and the `~` prefix for binary strings, see [1]. Erlang also added nominal types. See EEP-69 [2]. This commit removes the documentation of "g:erlang_highlight_bifs" and "g:erlang_highlight_special_atoms", which are not longer supported. "g:erlang_old_style_highlight" is kept undocumented (as it should not be used by new users). This commit contains the modifications in the following PR and commits: - vim-erlang/vim-erlang-runtime#58 - vim-erlang/vim-erlang-runtime@43d18d3 - vim-erlang/vim-erlang-runtime@ac88ebf - vim-erlang/vim-erlang-runtime@19c1be9 - vim-erlang/vim-erlang-runtime@7f5cefc - vim-erlang/vim-erlang-runtime@976b10b [1]: https://www.erlang.org/doc/system/documentation.html [2]: https://www.erlang.org/eeps/eep-0069 closes: vim/vim#17687 https://github.com/vim/vim/commit/e85a66a4d4a44bc13862a7b43ca22d929b97503a Co-authored-by: Csaba Hoch Co-authored-by: Johannes Christ --- runtime/doc/syntax.txt | 42 ++++++++-- runtime/syntax/erlang.vim | 164 +++++++++++++++++++++++++++++++++++--- 2 files changed, 190 insertions(+), 16 deletions(-) diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index c3731a47ee..2b65884699 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -1091,15 +1091,47 @@ ERLANG *erlang.vim* *ft-erlang-syntax* Erlang is a functional programming language developed by Ericsson. Files with the following extensions are recognized as Erlang files: erl, hrl, yaws. -The BIFs (built-in functions) are highlighted by default. To disable this, -put the following line in your vimrc: > +Vim highlights triple-quoted docstrings as comments by default. - :let g:erlang_highlight_bifs = 0 +If you want triple-quoted docstrings highlighted as Markdown, add the +following line to your |vimrc|: > -To enable highlighting some special atoms, put this in your vimrc: > + :let g:erlang_use_markdown_for_docs = 1 - :let g:erlang_highlight_special_atoms = 1 +The plain text inside the docstrings (that is, the characters that are not +highlighted by the Markdown syntax) is still highlighted as a comment. +If you want to highlight the plain text inside the docstrings using a +different highlight group, add the following line to your |vimrc| (the +example highlights plain text using the String highlight group): > + + :let g:erlang_docstring_default_highlight = 'String' + +If you don't enable Markdown, this line highlights the full docstrings +according to the specified highlight group. + +Use the following line to disable highlighting for the plain text: > + + :let g:erlang_docstring_default_highlight = '' + +Configuration examples: > + + " Highlight docstrings as Markdown. + :let g:erlang_use_markdown_for_docs = 1 + + " 1. Highlight Markdown elements in docstrings as Markdown. + " 2. Highlight the plain text in docstrings as String. + :let g:erlang_use_markdown_for_docs = 1 + :let g:erlang_docstring_default_highlight = 'String' + + " Highlight docstrings as strings (no Markdown). + :let g:erlang_docstring_default_highlight = 'String' + + " 1. Highlight Markdown elements in docstrings as Markdown. + " 2. Don't highlight the plain text in docstrings. + :let g:erlang_use_markdown_for_docs = 1 + :let g:erlang_docstring_default_highlight = '' +< ELIXIR *elixir.vim* *ft-elixir-syntax* diff --git a/runtime/syntax/erlang.vim b/runtime/syntax/erlang.vim index 0b256193ab..3ef2c8d410 100644 --- a/runtime/syntax/erlang.vim +++ b/runtime/syntax/erlang.vim @@ -2,7 +2,8 @@ " Language: Erlang (http://www.erlang.org) " Maintainer: Csaba Hoch " Contributor: Adam Rutkowski -" Last Update: 2022-Sep-06 +" Johannes Christ +" Last Update: 2025-Jul-06 " License: Vim license " URL: https://github.com/vim-erlang/vim-erlang-runtime @@ -23,20 +24,121 @@ " To use the old highlighting style, add this to your .vimrc: " " let g:erlang_old_style_highlight = 1 -" -" To highlight further module attributes, add them to -" ~/.vim/after/syntax/erlang.vim: -" -" syn keyword erlangAttribute myattr1 myattr2 contained " quit when a syntax file was already loaded if exists("b:current_syntax") finish endif +if !exists('g:main_syntax') + " This is an Erlang source file, and this is the main execution of + " syntax/erlang.vim. + let g:main_syntax = 'erlang' +elseif g:main_syntax == 'erlang' + " This is an Erlang source file, and this is an inner execution of + " syntax/erlang.vim. For example: + " + " 1. The main execution of syntax/erlang.vim included syntax/markdown.vim + " because "g:erlang_use_markdown_for_docs == 1". + " + " 2. syntax/markdown.vim included syntax/erlang.vim because + " "g:markdown_fenced_languages == ['erlang']". This is the inner + " execution of syntax/erlang.vim. + " + " To avoid infinite recursion with Markdown and Erlang including each other, + " and to avoid the inner syntax/erlang.vim execution messing up the + " variables of the outer erlang.vim execution, we finish executing the inner + " erlang.vim. + " + " In the inner execution, we already have the Erlang syntax items included, + " so the highlighting of Erlang within Markdown within Erlang will be + " acceptable. It won't highlight Markdown inside Erlang inside Markdown + " inside Erlang. + finish +endif + let s:cpo_save = &cpo set cpo&vim +" "g:erlang_old_style_highlight": Whether to use old style highlighting. +" +" * "g:erlang_old_style_highlight == 0" (default): Use new style +" highlighting. +" +" * "g:erlang_old_style_highlight == 1": Use old style highlighting. +let s:old_style = (exists("g:erlang_old_style_highlight") && + \g:erlang_old_style_highlight == 1) + +" "g:erlang_use_markdown_for_docs": Whether to use Markdown highlighting in +" docstrings. +" +" * "g:erlang_use_markdown_for_docs == 1": Enable Markdown highlighting in +" docstrings. +" +" * "g:erlang_use_markdown_for_docs == 0" (default): Disable Markdown +" highlighting in docstrings. +" +" If "g:main_syntax" is not 'erlang', this is not an Erlang source file but +" for example a Markdown file, and syntax/markdown.vim is including +" syntax/erlang.vim. To avoid infinite recursion with Markdown and Erlang +" including each other, we disable sourcing syntax/markdown.vim in this case. +if exists("g:erlang_use_markdown_for_docs") && g:main_syntax == 'erlang' + let s:use_markdown = g:erlang_use_markdown_for_docs +else + let s:use_markdown = 0 +endif + +" "g:erlang_docstring_default_highlight": How to highlight the text inside +" docstrings (except the text which is highlighted by Markdown). +" +" If "g:erlang_use_markdown_for_docs == 1": +" +" * "g:erlang_docstring_default_highlight == 'Comment'" (default): the plugin +" highlights the plain text inside Markdown as Markdown normally does, +" with comment highlighting to regular text in the docstring. +" +" * If you set g:erlang_docstring_default_highlight to the name of highlight +" group, for example "String", the plugin highlights the plain text inside +" Markdown with the specified highlight group. See ":highlight" for the +" available groups. You may also set it to an empty string to disable any +" specific highlighting. +" +" If "g:erlang_use_markdown_for_docs == 0": +" +" * "g:erlang_docstring_default_highlight == 'Comment'" (default): the plugin +" does not highlight the contents of the docstring as markdown, but +" continues to display them in the style of comments. +" +" * If you set g:erlang_docstring_default_highlight to the name of highlight +" group, for example "String", the plugin highlights the plain text inside +" Markdown with the specified highlight group. See ":highlight" for the +" available groups. You may also set it to an empty string to disable any +" specific highlighting. +" +" Configuration examples: +" +" " Highlight docstrings as Markdown. +" let g:erlang_use_markdown_for_docs = 1 +" let g:erlang_docstring_default_highlight = 'Comment' +" +" " 1. Highlight Markdown elements in docstrings as Markdown. +" " 2. Highlight the plain text in docstrings as String. +" let g:erlang_use_markdown_for_docs = 1 +" let g:erlang_docstring_default_highlight = 'String' +" +" " Highlight docstrings as strings. +" let g:erlang_use_markdown_for_docs = 0 +" let g:erlang_docstring_default_highlight = 'String' +" +" " Highlight docstrings as comments (default). +" let g:erlang_use_markdown_for_docs = 0 +" let g:erlang_docstring_default_highlight = 'Comment' +if exists("g:erlang_docstring_default_highlight") + let s:docstring_default_highlight = g:erlang_docstring_default_highlight +else + let s:docstring_default_highlight = 'Comment' +endif + " Case sensitive syn case match @@ -55,6 +157,21 @@ syn match erlangNumberFloat '\<\d\+\.\d\+\%([eE][+-]\=\d\+\)\=\>' " Strings, atoms, characters syn region erlangString start=/"/ end=/"/ contains=erlangStringModifier +syn region erlangStringTripleQuoted matchgroup=String start=/"""/ end=/\%(^\s*\)\@<="""/ keepend + +" Documentation +syn region erlangDocString start=/^-\%(module\)\=doc\s*\~\="/ end=/"\.$/ contains=@erlangDocStringCluster keepend +syn region erlangDocString start=/^-\%(module\)\=doc\s*<<"/ end=/">>\.$/ contains=@erlangDocStringCluster keepend +syn region erlangDocString start=/^-\%(module\)\=doc\s*\~\="""/ end=/\%(^\s*\)\@<="""\.$/ contains=@erlangDocStringCluster keepend +syn region erlangDocString start=/^-\%(module\)\=doc\s*<<"""/ end=/\%(^\s*\)\@<=""">>\.$/ contains=@erlangDocStringCluster keepend +syn cluster erlangDocStringCluster contains=erlangInnerDocAttribute,erlangDocStringDelimiter +syn region erlangDocStringDelimiter matchgroup=erlangString start=/"/ end=/"/ contains=@erlangDocStringContained contained +syn region erlangDocStringDelimiter matchgroup=erlangString start=/"""/ end=/"""/ contains=@erlangDocStringContained contained + +if s:use_markdown + syn cluster erlangDocStringContained contains=@markdown +endif + syn region erlangQuotedAtom start=/'/ end=/'/ contains=erlangQuotedAtomModifier syn match erlangStringModifier '\\\%(\o\{1,3}\|x\x\x\|x{\x\+}\|\^.\|.\)\|\~\%([ni~]\|\%(-\=\d\+\|\*\)\=\.\=\%(\*\|\d\+\)\=\%(\..\)\=[tl]*[cfegswpWPBX#bx+]\)' contained syn match erlangQuotedAtomModifier '\\\%(\o\{1,3}\|x\x\x\|x{\x\+}\|\^.\|.\)' contained @@ -94,12 +211,14 @@ syn match erlangBitType '\%(\/\%(\s\|\n\|%.*\n\)*\)\@<=\%(integer\|float\|binary " Constants and Directives syn match erlangUnknownAttribute '^\s*-\%(\s\|\n\|%.*\n\)*\l[[:alnum:]_@]*' contains=erlangComment -syn match erlangAttribute '^\s*-\%(\s\|\n\|%.*\n\)*\%(behaviou\=r\|compile\|export\(_type\)\=\|file\|import\|module\|author\|copyright\|doc\|vsn\|on_load\|optional_callbacks\|feature\)\>' contains=erlangComment +syn match erlangAttribute '^\s*-\%(\s\|\n\|%.*\n\)*\%(behaviou\=r\|compile\|dialyzer\|export\|export_type\|file\|import\|module\|author\|copyright\|vsn\|on_load\|optional_callbacks\|feature\|mode\)\>' contains=erlangComment +syn match erlangDocAttribute '^\s*-\%(\s\|\n\|%.*\n\)*\%(moduledoc\|doc\)\>' contains=erlangComment,erlangDocString +syn match erlangInnerDocAttribute '^\s*-\%(\s\|\n\|%.*\n\)*\%(moduledoc\|doc\)\>' contained syn match erlangInclude '^\s*-\%(\s\|\n\|%.*\n\)*\%(include\|include_lib\)\>' contains=erlangComment syn match erlangRecordDef '^\s*-\%(\s\|\n\|%.*\n\)*record\>' contains=erlangComment syn match erlangDefine '^\s*-\%(\s\|\n\|%.*\n\)*\%(define\|undef\)\>' contains=erlangComment syn match erlangPreCondit '^\s*-\%(\s\|\n\|%.*\n\)*\%(ifdef\|ifndef\|else\|endif\)\>' contains=erlangComment -syn match erlangType '^\s*-\%(\s\|\n\|%.*\n\)*\%(spec\|type\|opaque\|callback\)\>' contains=erlangComment +syn match erlangType '^\s*-\%(\s\|\n\|%.*\n\)*\%(spec\|type\|opaque\|nominal\|callback\)\>' contains=erlangComment " Keywords syn keyword erlangKeyword after begin case catch cond end fun if let of else @@ -147,9 +266,21 @@ let b:erlang_syntax_synced = 1 " Define the default highlighting. See ":help group-name" for the groups and " their colors. -let s:old_style = (exists("g:erlang_old_style_highlight") && - \g:erlang_old_style_highlight == 1) +if s:use_markdown + " Add markdown syntax elements for docstrings (actually, for all + " triple-quoted strings). + unlet! b:current_syntax + syn include @markdown syntax/markdown.vim + let b:current_syntax = "erlang" + + " markdown-erlang.vim includes html.vim, which includes css.vim, which adds + " the dash character (-) to the list of syntax keywords, which causes + " `-VarName` not to be highlighted as a variable in the Erlang code. + " + " Here we override that. + syntax iskeyword @,48-57,192-255,$,_ +endif " Comments hi def link erlangComment Comment @@ -163,6 +294,12 @@ hi def link erlangNumberFloat Float " Strings, atoms, characters hi def link erlangString String +hi def link erlangStringTripleQuoted String + +" Triple quoted strings +if s:docstring_default_highlight != '' + execute 'hi def link erlangDocStringDelimiter '. s:docstring_default_highlight +endif if s:old_style hi def link erlangQuotedAtom Type @@ -232,6 +369,8 @@ hi def link erlangPreCondit Type hi def link erlangType Type else hi def link erlangAttribute Keyword +hi def link erlangDocAttribute Keyword +hi def link erlangInnerDocAttribute Keyword hi def link erlangMacroDef Macro hi def link erlangUnknownAttribute Normal hi def link erlangInclude Include @@ -257,9 +396,12 @@ hi def link erlangExtra Statement hi def link erlangSignal Statement endif - let b:current_syntax = "erlang" +if g:main_syntax ==# 'erlang' + unlet g:main_syntax +endif + let &cpo = s:cpo_save unlet s:cpo_save