📜 ⬆️ ⬇️

Highlight syntax of the F # language in gedit

Introduction


Creating syntax highlighting for any language in gedit is done using the gtksourceview library. In general, the job of adding a syntax highlighting to any language in gnome-edit consists of writing a file with the .lang extension, which is essentially an XML file that stores a description of the syntax of a particular language. Usually the .lang files that gtksourceview supports are located in the /usr/share/gtksourceview-2.0/language-specs/ directory

Description of the .lang file format


Like any XML document, a .lang file consists of a root and nodes originating from the root of a document. In .lang, the document root is the tag. The root tag can contain the following attributes:

ID - Description ID. Used for external links to this item and must be unique. It may contain letters, numbers, and underscores. In the value of the ID attribute, no letters should be used in high case.

Name - The name of the language provided to the user.
')
Version - Format version. (GTKSOURCEVIEW uses 2.0)

Section - Determines which section of the menu the language will be in: scripting, scientific, etc. (For the gedit menu)

Hidden - Hint, tooltip for the user.

All attributes except hidden and section are required.

Also, the root element can contain the following elements:

Metadata - the element contains the metadata description. May contain properties element, which contains one attribute. name , the value of which can be:

Mimetypes - Contains a list of media types.
Globs - language file extension
line-comment-start - used to describe single-line comments.
block comment-start - used to describe the beginning of multi-line comments
block-comment-end - used to describe the beginning of multi-line comments
Styles - contains a description of the styles used in the current language. Contains one element - style

Style - describes the style that is associated with a specific ID. Contains 3 elements:
ID - Style ID
Name - Style Name
Map-to - Used to display a style with a specific font and color.

Definitions - the main element of the root, containing the definition of the language. Includes one attribute:
ID - The ID used to include defined regular expressions describing the language syntax

ontext is the most important element supporting the syntax description. May contain the following elements:
Start - contains the initial regular expression of the current context.
End - Contains the terminating regular expression of the current context.
Include - contains a list of contexts

The same element can contain the following attributes:

ID - unique context identifier
style-ref - highlighting style for a given context

Keyword - contains keywords for the given context.

That's basically all the standard elements, here are just the basic elements of gtksourceview.

Well, for a snack .lang file describing the language F #:

<? xml version ="1.0" encoding ="utf-8" ? >

< language id ="fsharp" _name ="F#" version ="2.0" _section ="Sources" >
< metadata >
< property name ="mimetypes" > text/x-fsharp </ property >
< property name ="globs" > *.fs; </ property >
< property name ="line-comment-start" > // </ property >
< property name ="block-comment-start" > (* </ property >
< property name ="block-comment-end" > *) </ property >
</ metadata >
< styles >
< style id ="comment" _name ="Comment" map-to ="def:comment" />
< style id ="base-n-integer" _name ="Base-N Integer" map-to ="def:base-n-integer" />
< style id ="floating-point" _name ="Floating Point number" map-to ="def:floating-point" />
< style id ="decimal" _name ="Decimal number" map-to ="def:decimal" />
< style id ="string" _name ="String" map-to ="def:string" />
< style id ="keyword" _name ="Keyword" map-to ="def:keyword" />
< style id ="meta-keyword" _name ="Type, module or object keyword" map-to ="def:keyword" />
< style id ="fun-keyword" _name ="Builtin-function keyword" map-to ="def:keyword" />
< style id ="type" _name ="Data Type" map-to ="def:type" />
< style id ="label" _name ="Labeled argument" map-to ="def:type" />
< style id ="poly-variant" _name ="Polymorphic Variant" map-to ="def:type" />
< style id ="variant" _name ="Variant Constructor" map-to ="def:type" />
< style id ="type-var" _name ="Type Variable" map-to ="def:type" />
< style id ="module" _name ="Module Path" map-to ="def:type" />
< style id ="escape" _name ="Escaped Character" map-to ="def:special-char" />
< style id ="boolean" _name ="Boolean value" map-to ="def:boolean" />
< style id ="preprocessor" _name ="Preprocessor" map-to ="def:preprocessor" />
</ styles >
< definitions >
< define-regex id ="cap-ident" > \b[AZ][A-Za-z0-9_']* </ define-regex >
< define-regex id ="low-ident" > \b[az][A-Za-z0-9_']* </ define-regex >
< define-regex id ="char-esc" > \\((\\|"|'|n|t|b|r)|[0-9]{3}|x[0-9a-fA-F]{2}) </ define-regex >
< define-regex id ="preproc-start" > ^\s*#\s* </ define-regex >
< define-regex id ="symbolchar" > [!#$%&*+. /> = <? @:\\^|~-] </ define-regex >

< context id ="escape-seq" style-ref ="escape" >
< match > \%{char-esc} </ match >
</ context >

< context id ="line-comment" style-ref ="comment" end-at-line-end ="true" >
< start > // </ start >
< include >
< context ref ="def:in-line-comment" />
</ include >
</ context >

< context id ="multiline-comment" style-ref ="comment" >
< start > \(\* </ start >
< end > \*\) </ end >
< include >
< context ref ="string" />
< context ref ="def:in-comment:*" />
</ include >
</ context >

< context id ="preprocessor" style-ref ="preprocessor" end-at-line-end ="false" >
< start extended ="true" >
\%{preproc-start}(if(n?def)?|else|endif|light|region|endregion)\b
</ start >
< include >
< context ref ="def:line-continue" ignore-style ="true" />
< context ref ="string" ignore-style ="true" />
</ include >
</ context >

< context id ="if-false-comment" style-ref ="comment" >
< start > \%{preproc-start}if\s*false\b </ start >
< end > \%{preproc-start}(endif|else|elif)\b </ end >
< include >
< context id ="if-in-if-false" >
< start > \%{preproc-start}if(n?def)?\b </ start >
< end > \%{preproc-start}endif\b </ end >
< include >
< context ref ="if-in-if-false" />
< context ref ="def:in-comment" />
</ include >
</ context >
< context ref ="def:in-comment" />
</ include >
</ context >

< context id ="poly-variant" style-ref ="poly-variant" >
< match > `\%{cap-ident} </ match >
</ context >

< context id ="modpath" style-ref ="module" >
< match > \%{cap-ident}(\.\%{cap-ident})*(?=\.) </ match >
</ context >

< context id ="variant" style-ref ="variant" >
< match > \%{cap-ident} </ match >
</ context >

< context id ="string" style-ref ="string" >
< start > " </ start >
< end > " </ end >
< include >
< context ref ="escape-seq" />
</ include >
</ context >

< context id ="character-constant" style-ref ="string" >
< match > ('\%{char-esc}')|('[^\\']') </ match >
</ context >

< context id ="type-var" style-ref ="type-var" >
< match > '\%{low-ident} </ match >
</ context >

< context id ="boolean-constant" style-ref ="boolean" >
< keyword > true </ keyword >
< keyword > false </ keyword >
</ context >

< context id ="keysymbol" style-ref ="keyword" >
< prefix > (? <! \%{symbolchar}) </ prefix >
< suffix > (?!\%{symbolchar}) </ suffix >
< keyword > \.\. </ keyword >
< keyword > :: </ keyword >
< keyword > = </ keyword >
< keyword > @ </ keyword >
< keyword > ~ </ keyword >
< keyword > - ></ keyword >
< keyword > | </ keyword >
< keyword > :? </ keyword >
< keyword > :? ></ keyword >
< keyword > ^ </ keyword >
< keyword >< - </ keyword >
< keyword > && </ keyword >
< keyword > & </ keyword >
</ context >

< context id ="keywords" style-ref ="keyword" >
< keyword > abstract </ keyword >
< keyword > and </ keyword >
< keyword > as </ keyword >
< keyword > assert </ keyword >
< keyword > asr </ keyword >
< keyword > begin </ keyword >
< keyword > class </ keyword >
< keyword > default </ keyword >
< keyword > delegate </ keyword >
< keyword > do </ keyword >
< keyword > done </ keyword >
< keyword > downcast </ keyword >
< keyword > downto </ keyword >
< keyword > else </ keyword >
< keyword > end </ keyword >
< keyword > enum </ keyword >
< keyword > exception </ keyword >
< keyword > false </ keyword >
< keyword > finaly </ keyword >
< keyword > for </ keyword >
< keyword > fun </ keyword >
< keyword > function </ keyword >
< keyword > if </ keyword >
< keyword > in </ keyword >
< keyword > iherit </ keyword >
< keyword > interface </ keyword >
< keyword > land </ keyword >
< keyword > lazy </ keyword >
< keyword > let </ keyword >
< keyword > lor </ keyword >
< keyword > lsl </ keyword >
< keyword > lsr </ keyword >
< keyword > lxor </ keyword >
< keyword > match </ keyword >
< keyword > member </ keyword >
< keyword > mod </ keyword >
< keyword > module </ keyword >
< keyword > mutable </ keyword >
< keyword > namespace </ keyword >
< keyword > new </ keyword >
< keyword > null </ keyword >
< keyword > of </ keyword >
< keyword > open </ keyword >
< keyword > or </ keyword >
< keyword > override </ keyword >
< keyword > sig </ keyword >
< keyword > static </ keyword >
< keyword > struct </ keyword >
< keyword > then </ keyword >
< keyword > to </ keyword >
< keyword > true </ keyword >
< keyword > try </ keyword >
< keyword > type </ keyword >
< keyword > val </ keyword >
< keyword > when </ keyword >
< keyword > inline </ keyword >
< keyword > upcast </ keyword >
< keyword > while </ keyword >
< keyword > with </ keyword >
</ context >

<!-- main context -->
< context id ="fsharp" >
< include >
< context ref ="keywords" />
< context ref ="keysymbol" />
< context ref ="boolean-constant" />
< context ref ="arraylit" />
< context ref ="character-constant" />
< context ref ="string" />
< context ref ="variant" />
< context ref ="modpath" />
< context ref ="poly-variant" />
< context ref ="label" />
< context ref ="line-comment" />
< context ref ="multiline-comment" />
< context ref ="type-var" />
< context ref ="if-false-comment" />
< context ref ="preprocessor" />
</ include >
</ context >
<!-- main context -->
</ definitions >
</ language >


* This source code was highlighted with Source Code Highlighter .


ps GtkSourceView official website

pps The first post on Habrahabr.

Source: https://habr.com/ru/post/73826/


All Articles