diff --git a/CHANGELOG.md b/CHANGELOG.md index c7f49869d..5b693dc39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for SPARK Pro 25.0 (eng/recordflux/RecordFlux#1823) - Support for GNAT Pro 25.0 (eng/recordflux/RecordFlux#1823) +### Fixed + +- Keyword highlighting in GNAT Studio and VS Code (eng/recordflux/RecordFlux#1815) + ## [0.25.0] - 2024-11-05 ### Added diff --git a/doc/development_guide/index.rst b/doc/development_guide/index.rst index b3897f3bd..37b2cb6fa 100644 --- a/doc/development_guide/index.rst +++ b/doc/development_guide/index.rst @@ -68,7 +68,7 @@ Make targets for common development tasks are: - ``install`` Install project in editable mode - ``doc`` Generate HTML documentation - ``dist`` Create Python package -- ``vscode`` Build the VS Code extension (which can be then installed via `rflx install vscode`) +- ``vscode`` Build the VS Code extension (which can be then installed via ``rflx install vscode``) - ``clean`` Remove build directories and generated files - ``clean_all`` Bring the repository to a completely clean state @@ -529,7 +529,7 @@ Default Annotations ^^^^^^^^^^^^^^^^^^^ It is often useful to show a piece of user's code along with a message concerning the code. -The simplest way to do that is by using the default annotation mechanism implemented in the `ErrorEntry` class which can be used to construct messages of all the severity categories defined above. +The simplest way to do that is by using the default annotation mechanism implemented in the ``ErrorEntry`` class which can be used to construct messages of all the severity categories defined above. For instance, the following error message: @@ -547,7 +547,7 @@ is by default automatically augmented by the tool with a default annotation like 4 | session S is | ^^^^^^^ -However, if an explicit `help` annotation has been provided in the message constructor, then having it together with the default annotation leads to a duplicate underline under the highlighted code section: +However, if an explicit ``help`` annotation has been provided in the message constructor, then having it together with the default annotation leads to a duplicate underline under the highlighted code section: .. code:: console @@ -558,7 +558,7 @@ However, if an explicit `help` annotation has been provided in the message const | ^^^^^^^ | ------- help: use "machine" instead -To avoid this set the `generate_default_annotation` parameter to `False` when constructing an instance of `ErrorEntry` class. +To avoid this set the ``generate_default_annotation`` parameter to ``False`` when constructing an instance of ``ErrorEntry`` class. This yields a more optimal message like the one below: .. code:: console @@ -630,13 +630,13 @@ General ------- The primary specification for the RecordFlux language is the `Language Reference <../../doc/language_reference/language_reference.rst>`_ document which formally specifies its syntax and documents also the intended semantics. -The grammar specification in that document is machine-readable and `tools/check_grammar.py` can be used to validate whether the contents of a given `.rflx` file is compatible with that syntax definition. +The grammar specification in that document is machine-readable and ``tools/check_grammar.py`` can be used to validate whether the contents of a given ``.rflx`` file is compatible with that syntax definition. -A parser for the RecordFlux language is implemented in the `rflx` tool using the `Langkit `_ framework. +A parser for the RecordFlux language is implemented in the ``rflx`` tool using the `Langkit `_ framework. -Syntax highlighting of `.rflx` files has been provided for the following IDEs and editors: VS Code, GNAT Studio, Vim and Neovim. -These can be installed using the `rflx install` command. -A prerequisite for installing the RecordFlux VS Code extension is to build it locally with the command `make vscode`. +Syntax highlighting of ``.rflx`` files has been provided for the following IDEs and editors: VS Code, GNAT Studio, Vim and Neovim. +These can be installed using the ``rflx install`` command. +A prerequisite for installing the RecordFlux VS Code extension is to build it locally with the command ``make vscode``. Making changes to the syntax ---------------------------- @@ -660,4 +660,4 @@ Backwards compatibility When the RecordFlux syntax is changed in a backwards incompatible manner, for instance, a construct is removed or a keyword is changed, then the old construct must still be preserved in the parser and a dedicated syntax check must be implemented. This is more helpful to the user since generic parsing errors are difficult to interpret. -For instance, you can have a look at how the syntax check for modular type definitions of the form `type T is mod 8` is implemented in `parser.py <../../rflx/specification/parser.py>`_. \ No newline at end of file +For instance, you can have a look at how the syntax check for modular type definitions of the form ``type T is mod 8`` is implemented in `parser.py <../../rflx/specification/parser.py>`_. \ No newline at end of file diff --git a/rflx/ide/gnatstudio/recordflux.py b/rflx/ide/gnatstudio/recordflux.py index d352ee411..852938aeb 100644 --- a/rflx/ide/gnatstudio/recordflux.py +++ b/rflx/ide/gnatstudio/recordflux.py @@ -152,28 +152,89 @@ GPS.parse_xml(XML) # Highlighting + +recordflux_types = [ + "Channel", +] + +recordflux_attributes = [ + "Append", + "Extend", + "First", + "Has_Data", + "Last", + "Present", + "Read", + "Reset", + "Size", + "Valid", + "Valid_Checksum", + "Write", +] + +recordflux_attribute_expressions = [ + "Head", + "Opaque", +] + +recordflux_simple_aspects = [ + "Always_Valid", + "Readable", + "Writable", +] + +recordflux_value_aspects = [ + "Byte_Order", + "Checksum", + "Desc", + "First", + "Size", +] + recordflux_keywords = [ + "all", "and", - "sequence of", + "begin", + "case", "end", + "exception", "for", + "function", + "generic", + "goto", "if", + "in", "is", + "machine", "message", "mod", "new", + "not", "null", + "of", "or", "package", "range", + "renames", + "return", + "sequence", + "session", + "some", + "state", "then", + "transition", "type", + "unsigned", "use", + "when", + "where", "with", ] recordflux_literals = [ "False", + "High_Order_First", + "Low_Order_First", "True", ] @@ -188,19 +249,15 @@ spec=( hl.simple(r"--[^\n]*", tag=hl.tag_comment), type_region, - hl.simple(r"\b'First", tag=tag_aspect), - hl.simple(r"\b'Last", tag=tag_aspect), - hl.simple(r"\b'Length", tag=tag_aspect), - hl.simple(r"\b'Size", tag=tag_aspect), - hl.simple(r"\bFirst\s+=>", tag=tag_aspect), - hl.simple(r"\bLast\s+=>", tag=tag_aspect), - hl.simple(r"\bLength\s+=>", tag=tag_aspect), - hl.simple(r"\bSize\s+=>", tag=tag_aspect), + hl.words(recordflux_types, tag=hl.tag_keyword), + hl.words([rf"\b'{w}" for w in recordflux_attributes], tag=tag_aspect), + hl.words([rf"\b'{w}" for w in recordflux_attribute_expressions], tag=tag_aspect), + hl.words(recordflux_simple_aspects, tag=tag_aspect), + *[hl.simple(rf"\b{w}\s+=>", tag=tag_aspect) for w in recordflux_value_aspects], hl.words(recordflux_keywords, tag=hl.tag_keyword), hl.words(recordflux_literals, tag=hl.tag_keyword), hl.simple(r"16#[_A-Fa-f0-9]+#", tag=hl.tag_number), hl.simple(r"\b[_0-9]+\b", tag=hl.tag_number), - hl.words(("Always_Valid"), tag=tag_aspect), string_literal, ), ) diff --git a/rflx/ide/vim/recordflux.vim b/rflx/ide/vim/recordflux.vim index 5a5f7c604..8ad365d37 100644 --- a/rflx/ide/vim/recordflux.vim +++ b/rflx/ide/vim/recordflux.vim @@ -16,6 +16,7 @@ syntax keyword rflxKeyword when syntax keyword rflxKeyword First syntax keyword rflxKeyword Size syntax keyword rflxKeyword Last +syntax match rflxKeyword "'Opaque" syntax match rflxKeyword "[.]\\{2,\\}" syntax match rflxKeyword "Always_Valid" syntax keyword rflxKeyword end @@ -30,7 +31,6 @@ syntax keyword rflxKeyword of syntax keyword rflxKeyword generic syntax keyword rflxKeyword function syntax keyword rflxKeyword return -syntax keyword rflxKeyword Channel syntax keyword rflxKeyword Readable syntax keyword rflxKeyword Writable syntax keyword rflxKeyword machine @@ -103,8 +103,8 @@ syntax keyword rflxBoolean False hi link rflxBoolean Boolean " Builtin types +syntax keyword rflxType Channel syntax keyword rflxType Opaque -syntax keyword rflxType Boolean hi link rflxType Type " Match number literal such as `1` or in an explicit base `#16#FF#` diff --git a/rflx/ide/vscode/syntax/recordflux.tmLanguage.json b/rflx/ide/vscode/syntax/recordflux.tmLanguage.json index 1e6ad69c4..fec597a7c 100644 --- a/rflx/ide/vscode/syntax/recordflux.tmLanguage.json +++ b/rflx/ide/vscode/syntax/recordflux.tmLanguage.json @@ -38,7 +38,7 @@ }, "operators": { "name": "entity.name.operator.recordflux", - "match": "=>|=|\\*|\\+|\\-|/=|\\.\\.|<|<=|>|>=|:=|\\b(or|and|range|sequence|unsigned|'First|'Size|'Last|'Valid_Checksum|'Valid|'Write|'Read)\\b" + "match": "=>|=|\\*|\\+|\\-|/=|\\.\\.|<|<=|>|>=|:=|\\b(and|mod|or|range|sequence|unsigned|'Append|'Extend|'First|'Has_Data|'Head|'Last|'Opaque|'Present|'Read|'Reset|'Size|'Valid|'Valid_Checksum|'Write)\\b" }, "strings": { "name": "string.quoted.double.recordflux", @@ -62,7 +62,7 @@ }, { "name": "variable.language.recordflux", - "match": "\\b(Size|Byte_Order|Checksum)\\b" + "match": "\\b(Byte_Order|Checksum|Desc|First|Size)\\b" } ] }, @@ -70,7 +70,7 @@ "patterns": [ { "name": "entity.name.type.recordflux", - "match": "\\b(Opaque|Channel)" + "match": "\\b(Channel|Opaque)\\b" } ] } diff --git a/tools/rflxlexer.py b/tools/rflxlexer.py index 4b6330e78..f34a854e1 100644 --- a/tools/rflxlexer.py +++ b/tools/rflxlexer.py @@ -12,6 +12,7 @@ MAPPINGS = { pygments.token.Keyword: [ "All", + "Always_Valid", "Append", "Begin", "Byte_Order", @@ -22,6 +23,7 @@ "End", "Exception", "Extend", + "False", "First", "For", "Function", @@ -36,6 +38,7 @@ "Low_Order_First", "Machine", "Message", + "Mod", "New", "Null", "Of", @@ -54,13 +57,13 @@ "State", "Then", "Transition", + "True", "Type", "Unsigned", "Use", "Valid", "Valid_Checksum", "When", - "Where", "With", "Writable", "Write",