├── .gitignore ├── test ├── linq.vader ├── vimrc ├── identifiers.vader ├── comments.vader ├── statements.vader ├── types.vader ├── modifiers.vader ├── keywords.vader ├── indent.vader ├── records.vader ├── properties.vader ├── operators.vader ├── preprocessors.vader ├── literals.vader └── strings.vader ├── README.md ├── .github └── workflows │ └── vader.yml ├── compiler └── dotnet.vim ├── ftplugin └── cs.vim ├── indent └── cs.vim └── syntax └── cs.vim /.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | -------------------------------------------------------------------------------- /test/linq.vader: -------------------------------------------------------------------------------- 1 | Given cs (LINQ): 2 | var foo = from bar in baz where bar < 42 select bar; 3 | 4 | Execute: 5 | AssertEqual 'csLinq', SyntaxOf('where') 6 | 7 | -------------------------------------------------------------------------------- /test/vimrc: -------------------------------------------------------------------------------- 1 | if &compatible 2 | set nocompatible 3 | endif 4 | 5 | filetype off 6 | 7 | " Assuming that plugins are installed in the same folder, e.g. ~/.vim/plugged 8 | let plugindir = expand("\:h:h:h") 9 | 10 | " Dependency to vader.vim 11 | let &runtimepath = plugindir . '/vim-cs,' . &runtimepath 12 | let &runtimepath .= ',' . plugindir . '/vader.vim' 13 | 14 | filetype plugin indent on 15 | syntax enable 16 | 17 | set nomore noswapfile 18 | set viminfo= 19 | set expandtab shiftwidth=4 softtabstop=-1 20 | -------------------------------------------------------------------------------- /test/identifiers.vader: -------------------------------------------------------------------------------- 1 | Given cs (verbatim identifiers): 2 | var @new = 42; 3 | 4 | Execute: 5 | AssertEqual 'csIdentifier', SyntaxOf('@new') 6 | 7 | Given cs (yield as identifier): 8 | var yield = 42; 9 | 10 | Execute: 11 | AssertEqual '', SyntaxOf('yield') 12 | 13 | Given cs (global namespace alias): 14 | global using global::System; 15 | 16 | Execute: 17 | AssertEqual 'csUsingModifier', SyntaxOf('global', 1) 18 | AssertEqual 'csGlobalNamespaceAlias', SyntaxOf('global', 2) 19 | AssertEqual 'csNamespaceAliasQualifier', SyntaxOf('::') 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-cs 2 | This is the home of the official Vim runtime files for C#. 3 | 4 | Changes made here will be included in future vim distributions, but if you want 5 | the latest version now then feel free to install the repo as a plugin, using 6 | your preferred plugin manager. 7 | 8 | # Contributions 9 | Issues, feature requests and especially pull requests are welcome! 10 | 11 | If submitting a pull request, please consider writing some tests to demonstrate 12 | your changes. 13 | Tests are performed using [Vader](https://github.com/junegunn/vader.vim). To try 14 | it out, install Vader, then open a `test/*.vader` file and run `:Vader` - easy 15 | peasy. 16 | 17 | # License 18 | The Vim License applies. See `:h license` 19 | -------------------------------------------------------------------------------- /test/comments.vader: -------------------------------------------------------------------------------- 1 | Given cs (line comment with TODO): 2 | // TODO: this won't get done 3 | 4 | Execute: 5 | AssertEqual 'csLineComment', SyntaxAt() 6 | normal! fT 7 | AssertEqual 'csTodo', SyntaxAt() 8 | 9 | Given cs (block comment with TODO): 10 | /* 11 | * TODO: this won't get done either 12 | */ 13 | 14 | Execute: 15 | AssertEqual 'csBlockComment', SyntaxAt() 16 | normal! jfT 17 | AssertEqual 'csTodo', SyntaxAt() 18 | 19 | Given cs (XML doc line comment): 20 | /// ... 21 | 22 | Execute: 23 | AssertEqual 'csXmlLineCommentLeader', SyntaxAt() 24 | normal! fs 25 | AssertEqual 'csXmlTag', SyntaxAt() 26 | 27 | Given cs (XML doc block comment): 28 | /** 29 | * ... 30 | */ 31 | 32 | Execute: 33 | AssertEqual 'csXmlBlockComment', SyntaxAt() 34 | normal! jfs 35 | AssertEqual 'csXmlTag', SyntaxAt() 36 | -------------------------------------------------------------------------------- /test/statements.vader: -------------------------------------------------------------------------------- 1 | Given cs (unsafe statement): 2 | unsafe { /* boom! */ } 3 | 4 | Execute: 5 | AssertEqual 'csStatement', SyntaxAt(1, 1) 6 | 7 | Given cs (checked statement): 8 | checked { /* boom! */ } 9 | 10 | Execute: 11 | AssertEqual 'csStatement', SyntaxAt(1, 1) 12 | 13 | Given cs (unchecked statement): 14 | unchecked { /* boom! */ } 15 | 16 | Execute: 17 | AssertEqual 'csStatement', SyntaxAt(1, 1) 18 | 19 | Given cs (fixed statement): 20 | fixed (int* i = foobar) { /* ... */ } 21 | 22 | Execute: 23 | AssertEqual 'csStatement', SyntaxAt(1, 1) 24 | 25 | Given cs (lock statement): 26 | lock (foobar) { /* ... */ } 27 | 28 | Execute: 29 | AssertEqual 'csStatement', SyntaxAt(1, 1) 30 | 31 | Given cs (yield statement): 32 | yield break; 33 | yield return 42; 34 | 35 | Execute: 36 | AssertEqual 'csStatement', SyntaxAt(1, 1) 37 | AssertEqual 'csStatement', SyntaxAt(2, 1) 38 | 39 | -------------------------------------------------------------------------------- /.github/workflows/vader.yml: -------------------------------------------------------------------------------- 1 | name: Vader 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | name: Test 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | cfg: 16 | - { editor: vim, neovim: false } 17 | - { editor: neovim, neovim: true } 18 | 19 | steps: 20 | - name: Checkout code 21 | uses: actions/checkout@main 22 | 23 | - name: Setup Vim 24 | uses: rhysd/action-setup-vim@v1 25 | with: 26 | neovim: ${{ matrix.cfg.neovim }} 27 | version: stable 28 | 29 | - name: Install Dependencies 30 | run: | 31 | git clone https://github.com/junegunn/vader.vim.git $GITHUB_WORKSPACE/../vader.vim 32 | 33 | - name: Run Test 34 | run: | 35 | cd test 36 | vim -esNu vimrc -c 'Vader! *' 37 | if: matrix.cfg.editor == 'vim' 38 | 39 | - name: Run Test 40 | run: | 41 | cd test 42 | nvim --headless -Nu vimrc -c 'Vader! *' 43 | env: 44 | VADER_OUTPUT_FILE: /dev/stderr 45 | if: matrix.cfg.editor == 'neovim' 46 | -------------------------------------------------------------------------------- /test/types.vader: -------------------------------------------------------------------------------- 1 | Given cs (nint and nuint): 2 | nint foo = 42; 3 | nuint foo = 42; 4 | 5 | Execute: 6 | AssertEqual 'csType', SyntaxAt(1, 1) 7 | AssertEqual 'csType', SyntaxAt(2, 1) 8 | 9 | Given cs (function pointer): 10 | delegate* managed foobar; 11 | delegate* unmanaged[Cdecl] foobar; 12 | 13 | Execute: 14 | AssertEqual 'csType', SyntaxOf('delegate') 15 | AssertEqual 'csOpSymbols', SyntaxOf('\*') 16 | AssertEqual 'csManagedModifier', SyntaxOf('managed') 17 | AssertEqual 'csType', SyntaxAt(2, 1) 18 | AssertEqual 'csType', SyntaxOf('delegate', 2) 19 | AssertEqual 'csOpSymbols', SyntaxOf('\*') 20 | AssertEqual 'csManagedModifier', SyntaxOf('unmanaged') 21 | 22 | Given cs (function pointer with whitespace before asterisk): 23 | delegate * managed foobar; 24 | 25 | Execute: 26 | AssertEqual 'csType', SyntaxOf('delegate') 27 | AssertEqual 'csOpSymbols', SyntaxOf('\*') 28 | AssertEqual 'csManagedModifier', SyntaxOf('\ where T : Bar {} 32 | 33 | Execute: 34 | AssertEqual 'csStorage', SyntaxOf('where') 35 | 36 | -------------------------------------------------------------------------------- /compiler/dotnet.vim: -------------------------------------------------------------------------------- 1 | " Vim compiler file 2 | " Compiler: dotnet build (.NET CLI) 3 | " Maintainer: Nick Jensen 4 | " Last Change: 2022-12-06 5 | " License: Vim (see :h license) 6 | " Repository: https://github.com/nickspoons/vim-cs 7 | 8 | if exists("current_compiler") 9 | finish 10 | endif 11 | let current_compiler = "dotnet" 12 | 13 | if exists(":CompilerSet") != 2 " older Vim always used :setlocal 14 | command -nargs=* CompilerSet setlocal 15 | endif 16 | 17 | let s:cpo_save = &cpo 18 | set cpo&vim 19 | 20 | if get(g:, "dotnet_errors_only", v:false) 21 | CompilerSet makeprg=dotnet\ build\ -nologo 22 | \\ -consoleloggerparameters:NoSummary 23 | \\ -consoleloggerparameters:ErrorsOnly 24 | else 25 | CompilerSet makeprg=dotnet\ build\ -nologo\ -consoleloggerparameters:NoSummary 26 | endif 27 | 28 | if get(g:, "dotnet_show_project_file", v:true) 29 | CompilerSet errorformat=%E%f(%l\\,%c):\ %trror\ %m, 30 | \%W%f(%l\\,%c):\ %tarning\ %m, 31 | \%-G%.%# 32 | else 33 | CompilerSet errorformat=%E%f(%l\\,%c):\ %trror\ %m\ [%.%#], 34 | \%W%f(%l\\,%c):\ %tarning\ %m\ [%.%#], 35 | \%-G%.%# 36 | endif 37 | 38 | let &cpo = s:cpo_save 39 | unlet s:cpo_save 40 | -------------------------------------------------------------------------------- /test/modifiers.vader: -------------------------------------------------------------------------------- 1 | Given cs (unsafe modifier): 2 | unsafe void foobar() { /* boom! */ } 3 | 4 | Execute: 5 | AssertEqual 'csModifier', SyntaxAt(1, 1) 6 | 7 | Given cs (async modifier): 8 | async void foobar() {} 9 | 10 | Execute: 11 | AssertEqual 'csAsyncModifier', SyntaxAt(1, 1) 12 | 13 | Given cs (partial types): 14 | partial class Foobar {} 15 | partial interface Foobar {} 16 | partial struct Foobar {} 17 | partial record Foobar {} 18 | partial record class Foobar {} 19 | partial record struct Foobar {} 20 | 21 | Execute: 22 | AssertEqual 'csModifier', SyntaxAt(1, 1) 23 | AssertEqual 'csModifier', SyntaxAt(2, 1) 24 | AssertEqual 'csModifier', SyntaxAt(3, 1) 25 | AssertEqual 'csModifier', SyntaxAt(4, 1) 26 | AssertEqual 'csModifier', SyntaxAt(5, 1) 27 | AssertEqual 'csModifier', SyntaxAt(6, 1) 28 | 29 | Given cs (partial methods): 30 | partial void Foobar(); 31 | 32 | Execute: 33 | AssertEqual 'csModifier', SyntaxAt(1, 1) 34 | 35 | Given cs (fixed modifier): 36 | fixed byte foobar[42]; 37 | 38 | Execute: 39 | AssertEqual 'csModifier', SyntaxAt(1, 1) 40 | 41 | Given cs (global using modifier): 42 | global using Foobar; 43 | 44 | Execute: 45 | AssertEqual 'csUsingModifier', SyntaxAt(1, 1) 46 | 47 | Given cs (operator modifier): 48 | public static T operator checked ++(T x) {...} 49 | 50 | Execute: 51 | AssertEqual 'csModifier', SyntaxOf("operator") 52 | AssertEqual 'csCheckedModifier', SyntaxOf("checked") 53 | 54 | -------------------------------------------------------------------------------- /test/keywords.vader: -------------------------------------------------------------------------------- 1 | Given cs (extern alias contextual keywords): 2 | extern alias Foobar; 3 | 4 | Execute: 5 | AssertEqual 'csStorage', SyntaxAt(1, 1) 6 | AssertEqual 'csStorage', SyntaxAt(1, 8) 7 | 8 | Given cs (extern modifier): 9 | extern void Foobar(); 10 | 11 | Execute: 12 | AssertEqual 'csModifier', SyntaxAt(1, 1) 13 | AssertEqual 'csType', SyntaxAt(1, 8) 14 | 15 | Given cs (base access): 16 | base.Foo(); 17 | base[42]; 18 | 19 | Execute: 20 | AssertEqual 'csAccess', SyntaxOf('base', 1) 21 | AssertEqual 'csAccess', SyntaxOf('base', 2) 22 | 23 | Given cs (base constructor intializer): 24 | Foo() : base() {} 25 | 26 | Execute: 27 | AssertEqual 'csAccess', SyntaxOf('base') 28 | 29 | Given cs (this access): 30 | Foo(this); 31 | this.Foo(); 32 | this[42]; 33 | 34 | Execute: 35 | AssertEqual 'csAccess', SyntaxOf('this', 1) 36 | AssertEqual 'csAccess', SyntaxOf('this', 2) 37 | AssertEqual 'csAccess', SyntaxOf('this', 3) 38 | 39 | Given cs (this constructor intializer): 40 | Foo() : this(42) {} 41 | 42 | Execute: 43 | AssertEqual 'csAccess', SyntaxOf('this') 44 | 45 | Given cs (this indexer declaration): 46 | public int this[int foo] => 42; 47 | public int Foo.this[int bar] => 42; 48 | 49 | Execute: 50 | AssertEqual 'csAccess', SyntaxOf('this', 1) 51 | AssertEqual 'csAccess', SyntaxOf('this', 2) 52 | 53 | Given cs (this parameter modifier): 54 | public static int Foo(this int bar) => 42 55 | 56 | Execute: 57 | AssertEqual 'csModifier', SyntaxOf('this') 58 | -------------------------------------------------------------------------------- /ftplugin/cs.vim: -------------------------------------------------------------------------------- 1 | " Vim filetype plugin file 2 | " Language: C# 3 | " Maintainer: Nick Jensen 4 | " Former Maintainer: Johannes Zellner 5 | " Last Change: 2022-11-16 6 | " License: Vim (see :h license) 7 | " Repository: https://github.com/nickspoons/vim-cs 8 | 9 | if exists('b:did_ftplugin') 10 | finish 11 | endif 12 | let b:did_ftplugin = 1 13 | 14 | let s:save_cpo = &cpoptions 15 | set cpoptions&vim 16 | 17 | " Set 'formatoptions' to break comment lines but not other lines, 18 | " and insert the comment leader when hitting or using "o". 19 | setlocal formatoptions-=t formatoptions+=croql 20 | 21 | " Set 'comments' to format dashed lists in comments. 22 | setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,:// 23 | 24 | setlocal cinoptions=J1 25 | 26 | let b:undo_ftplugin = 'setl com< fo< cino<' 27 | 28 | if exists('loaded_matchit') && !exists('b:match_words') 29 | " #if/#endif support included by default 30 | let b:match_ignorecase = 0 31 | let b:match_words = '\%(^\s*\)\@<=#\s*region\>:\%(^\s*\)\@<=#\s*endregion\>,' 32 | let b:undo_ftplugin .= ' | unlet! b:match_ignorecase b:match_words' 33 | endif 34 | 35 | if (has('gui_win32') || has('gui_gtk')) && !exists('b:browsefilter') 36 | let b:browsefilter = "C# Source Files (*.cs *.csx)\t*.cs;*.csx\n" . 37 | \ "C# Project Files (*.csproj)\t*.csproj\n" . 38 | \ "Visual Studio Solution Files (*.sln)\t*.sln\n" . 39 | \ "All Files (*.*)\t*.*\n" 40 | let b:undo_ftplugin .= ' | unlet! b:browsefilter' 41 | endif 42 | 43 | let &cpoptions = s:save_cpo 44 | unlet s:save_cpo 45 | 46 | " vim:et:sw=2:sts=2 47 | -------------------------------------------------------------------------------- /test/indent.vader: -------------------------------------------------------------------------------- 1 | Given cs (a declaration with an attribute): 2 | namespace UnitTest.SomeTest 3 | { 4 | [RequireComponent(typeof(Collider))] 5 | class Test { 6 | [SerializeField] 7 | public string m_PrettyName = ""; 8 | } 9 | } 10 | 11 | Execute: 12 | normal! gg=G 13 | 14 | Expect cs (correct indentation): 15 | namespace UnitTest.SomeTest 16 | { 17 | [RequireComponent(typeof(Collider))] 18 | class Test { 19 | [SerializeField] 20 | public string m_PrettyName = ""; 21 | } 22 | } 23 | 24 | Given cs (a declaration with a directive): 25 | namespace UnitTest.SomeTest 26 | { 27 | class Test { 28 | #if UNITY_EDITOR 29 | public 30 | #endif 31 | string m_PrettyName = ""; 32 | } 33 | } 34 | 35 | Execute: 36 | normal! gg=G 37 | 38 | Expect cs (correct indentation): 39 | namespace UnitTest.SomeTest 40 | { 41 | class Test { 42 | #if UNITY_EDITOR 43 | public 44 | #endif 45 | string m_PrettyName = ""; 46 | } 47 | } 48 | 49 | Given cs (a declaration with an attribute interleaved with directive): 50 | namespace UnitTest.SomeTest 51 | { 52 | [RequireComponent(typeof(Collider))] 53 | class Test { 54 | [SerializeField] 55 | #if UNITY_EDITOR 56 | public 57 | #endif 58 | string m_PrettyName = ""; 59 | } 60 | } 61 | 62 | Execute: 63 | normal! gg=G 64 | 65 | Expect cs(correct indentation): 66 | namespace UnitTest.SomeTest 67 | { 68 | [RequireComponent(typeof(Collider))] 69 | class Test { 70 | [SerializeField] 71 | #if UNITY_EDITOR 72 | public 73 | #endif 74 | string m_PrettyName = ""; 75 | } 76 | } 77 | 78 | Given cs (an object initialization with more than one property): 79 | return new LoginResponse 80 | { 81 | Success = false, 82 | Message = _frameworkSettings.InvalidLoginErrorMessage 83 | }; 84 | 85 | Execute: 86 | normal! gg=G 87 | 88 | Expect cs(correct indentation): 89 | return new LoginResponse 90 | { 91 | Success = false, 92 | Message = _frameworkSettings.InvalidLoginErrorMessage 93 | }; 94 | -------------------------------------------------------------------------------- /test/records.vader: -------------------------------------------------------------------------------- 1 | Given cs (record matching via body): 2 | record Foo {} 3 | record struct Foo {} 4 | record class Foo {} 5 | 6 | Execute: 7 | AssertEqual 'csStorage', SyntaxOf('record', 1) 8 | AssertEqual 'csStorage', SyntaxOf('record', 2) 9 | AssertEqual 'csStorage', SyntaxOf('record', 3) 10 | 11 | Given cs (record matching via body): 12 | record Foo; 13 | record struct Foo; 14 | record class Foo; 15 | 16 | Execute: 17 | AssertEqual 'csStorage', SyntaxOf('record', 1) 18 | AssertEqual 'csStorage', SyntaxOf('record', 2) 19 | AssertEqual 'csStorage', SyntaxOf('record', 3) 20 | 21 | Given cs (record matching via type parameter list): 22 | record Foo; 23 | record struct Foo; 24 | record class Foo; 25 | 26 | Execute: 27 | AssertEqual 'csStorage', SyntaxOf('record', 1) 28 | AssertEqual 'csStorage', SyntaxOf('record', 2) 29 | AssertEqual 'csStorage', SyntaxOf('record', 3) 30 | 31 | Given cs (record matching via parameter list): 32 | record Foo(int X, int Y); 33 | record struct Foo(int X, int Y); 34 | record class Foo(int X, int Y); 35 | 36 | Execute: 37 | AssertEqual 'csStorage', SyntaxOf('record', 1) 38 | AssertEqual 'csStorage', SyntaxOf('record', 2) 39 | AssertEqual 'csStorage', SyntaxOf('record', 3) 40 | 41 | Given cs (record matching via base type): 42 | record Foo : Bar; 43 | record struct Foo : Bar; 44 | record class Foo : Bar; 45 | 46 | Execute: 47 | AssertEqual 'csStorage', SyntaxOf('record', 1) 48 | AssertEqual 'csStorage', SyntaxOf('record', 2) 49 | AssertEqual 'csStorage', SyntaxOf('record', 3) 50 | 51 | Given cs (record matching via modifier): 52 | partial record Foo ... 53 | partial record struct ... 54 | partial record class ... 55 | 56 | Execute: 57 | AssertEqual 'csStorage', SyntaxOf('record', 1) 58 | AssertEqual 'csStorage', SyntaxOf('record', 2) 59 | AssertEqual 'csStorage', SyntaxOf('record', 3) 60 | 61 | Given cs (record matching via class or struct): 62 | record struct ... 63 | record class ... 64 | 65 | Execute: 66 | AssertEqual 'csStorage', SyntaxOf('record', 1) 67 | AssertEqual 'csStorage', SyntaxOf('record', 2) 68 | -------------------------------------------------------------------------------- /indent/cs.vim: -------------------------------------------------------------------------------- 1 | " Vim indent file 2 | " Language: C# 3 | " Maintainer: Nick Jensen 4 | " Former Maintainers: Aquila Deus 5 | " Johannes Zellner 6 | " Last Change: 2020-03-26 7 | " License: Vim (see :h license) 8 | " Repository: https://github.com/nickspoons/vim-cs 9 | 10 | if exists('b:did_indent') 11 | finish 12 | endif 13 | let b:did_indent = 1 14 | 15 | let s:save_cpo = &cpoptions 16 | set cpoptions&vim 17 | 18 | 19 | setlocal indentexpr=GetCSIndent(v:lnum) 20 | 21 | function! s:IsCompilerDirective(line) 22 | " Exclude #region and #endregion - these should be indented normally 23 | return a:line =~# '^\s*#' && !s:IsRegionDirective(a:line) 24 | endf 25 | 26 | function! s:IsRegionDirective(line) 27 | return a:line =~# '^\s*#\s*region' || a:line =~# '^\s*#\s*endregion' 28 | endf 29 | 30 | function! s:IsAttributeLine(line) 31 | return a:line =~# '^\s*\[[A-Za-z]' && a:line =~# '\]$' 32 | endf 33 | 34 | function! s:FindPreviousNonCompilerDirectiveLine(start_lnum) 35 | for delta in range(0, a:start_lnum) 36 | let lnum = a:start_lnum - delta 37 | let line = getline(lnum) 38 | if !s:IsCompilerDirective(line) && !s:IsRegionDirective(line) 39 | return lnum 40 | endif 41 | endfor 42 | return 0 43 | endf 44 | 45 | function! GetCSIndent(lnum) abort 46 | " Hit the start of the file, use zero indent. 47 | if a:lnum == 0 48 | return 0 49 | endif 50 | 51 | let this_line = getline(a:lnum) 52 | 53 | " Compiler directives use zero indent if so configured. 54 | let is_first_col_macro = s:IsCompilerDirective(this_line) && stridx(&l:cinkeys, '0#') >= 0 55 | if is_first_col_macro 56 | return cindent(a:lnum) 57 | endif 58 | 59 | let lnum = s:FindPreviousNonCompilerDirectiveLine(a:lnum - 1) 60 | let previous_code_line = getline(lnum) 61 | if s:IsAttributeLine(previous_code_line) 62 | return indent(lnum) 63 | elseif s:IsRegionDirective(this_line) 64 | return cindent(lnum) 65 | else 66 | return cindent(a:lnum) 67 | endif 68 | endfunction 69 | 70 | let b:undo_indent = 'setlocal indentexpr<' 71 | 72 | let &cpoptions = s:save_cpo 73 | unlet s:save_cpo 74 | 75 | " vim:et:sw=2:sts=2 76 | -------------------------------------------------------------------------------- /test/properties.vader: -------------------------------------------------------------------------------- 1 | # Property Accessors 2 | 3 | Given cs (standard get/set formatting): 4 | get { return 0; } 5 | set { _value = value; } 6 | 7 | Execute: 8 | AssertEqual 'csAccessor', SyntaxAt() 9 | normal! j 10 | AssertEqual 'csAccessor', SyntaxAt() 11 | 12 | 13 | Given cs (standard get/init formatting): 14 | get { return 0; } 15 | init { _value = value; } 16 | 17 | Execute: 18 | AssertEqual 'csAccessor', SyntaxAt() 19 | normal! j 20 | AssertEqual 'csAccessor', SyntaxAt() 21 | 22 | 23 | Given cs (automatic property get/set): 24 | get; set; 25 | 26 | Execute: 27 | AssertEqual 'csAccessor', SyntaxAt() 28 | normal! fs 29 | AssertEqual 'csAccessor', SyntaxAt() 30 | 31 | 32 | Given cs (automatic property get/init): 33 | get; init; 34 | 35 | Execute: 36 | AssertEqual 'csAccessor', SyntaxAt() 37 | normal! fi 38 | AssertEqual 'csAccessor', SyntaxAt() 39 | 40 | 41 | Given cs (automatic property get/set with whitespace): 42 | get ; set ; 43 | 44 | Execute: 45 | AssertEqual 'csAccessor', SyntaxAt() 46 | normal! fs 47 | AssertEqual 'csAccessor', SyntaxAt() 48 | 49 | 50 | Given cs (automatic property get/init with whitespace): 51 | get ; init ; 52 | 53 | Execute: 54 | AssertEqual 'csAccessor', SyntaxAt() 55 | normal! fi 56 | AssertEqual 'csAccessor', SyntaxAt() 57 | 58 | 59 | Given cs (in-line property get/set): 60 | get => 0; set => _value = value; 61 | 62 | Execute: 63 | AssertEqual 'csAccessor', SyntaxAt() 64 | normal! fs 65 | AssertEqual 'csAccessor', SyntaxAt() 66 | 67 | 68 | Given cs (in-line property get/init): 69 | get => 0; init => _value = value; 70 | 71 | Execute: 72 | AssertEqual 'csAccessor', SyntaxAt() 73 | normal! fi 74 | AssertEqual 'csAccessor', SyntaxAt() 75 | 76 | 77 | # Event Accessors 78 | 79 | Given cs (standard event add/remove formatting): 80 | add { _value += value; } 81 | remove { _value -= value; } 82 | 83 | Execute: 84 | AssertEqual 'csAccessor', SyntaxAt() 85 | normal! j 86 | AssertEqual 'csAccessor', SyntaxAt() 87 | 88 | 89 | Given cs (automatic event add/remove): 90 | add; remove; 91 | 92 | Execute: 93 | AssertEqual 'csAccessor', SyntaxAt() 94 | normal! fr 95 | AssertEqual 'csAccessor', SyntaxAt() 96 | 97 | 98 | Given cs (automatic event add/remove with whitespace): 99 | add ; remove ; 100 | 101 | Execute: 102 | AssertEqual 'csAccessor', SyntaxAt() 103 | normal! fr 104 | AssertEqual 'csAccessor', SyntaxAt() 105 | 106 | 107 | Given cs (in-line event add/remove): 108 | add => _value += value; remove => _value -= value; 109 | 110 | Execute: 111 | AssertEqual 'csAccessor', SyntaxAt() 112 | normal! fr 113 | AssertEqual 'csAccessor', SyntaxAt() 114 | 115 | -------------------------------------------------------------------------------- /test/operators.vader: -------------------------------------------------------------------------------- 1 | Given cs (order comparison at start of line): 2 | void f() { 3 | if (i 4 | < LongFunctionName()) 5 | } 6 | 7 | Execute: 8 | normal! 2jf< 9 | AssertEqual 'csOpSymbols', SyntaxAt() 10 | 11 | 12 | Given cs (order comparison at end of line): 13 | void f() { 14 | if (i < 15 | LongFunctionName()) 16 | } 17 | 18 | Execute: 19 | normal! jf< 20 | AssertEqual 'csOpSymbols', SyntaxAt() 21 | 22 | 23 | Given cs (order comparison with whitespace): 24 | void f() { 25 | if (7 < 8) 26 | } 27 | 28 | Execute: 29 | normal! jf< 30 | AssertEqual 'csOpSymbols', SyntaxAt() 31 | 32 | 33 | Given cs (order comparison missing whitespace): 34 | void f() { 35 | if (7<8) 36 | } 37 | 38 | Execute: 39 | normal! jf< 40 | AssertEqual 'csOpSymbols', SyntaxAt() 41 | 42 | 43 | Given cs (generic function): 44 | void f() { 45 | return Get(); 46 | } 47 | 48 | Execute: 49 | normal! f< 50 | AssertEqual 'csGenericBraces', SyntaxAt() 51 | normal! f> 52 | AssertEqual 'csGenericBraces', SyntaxAt() 53 | normal! j0f< 54 | AssertEqual 'csGenericBraces', SyntaxAt() 55 | normal! f> 56 | AssertEqual 'csGenericBraces', SyntaxAt() 57 | 58 | 59 | Given cs (generic inside generic): 60 | Dictionary> f() { 61 | return 'a' <> null; 62 | } 63 | 64 | Execute: 65 | normal! f< 66 | AssertEqual 'csGenericBraces', SyntaxAt() 67 | normal! f< 68 | AssertEqual 'csGenericBraces', SyntaxAt() 69 | normal! f> 70 | AssertEqual 'csGenericBraces', SyntaxAt() 71 | normal! f> 72 | AssertEqual 'csGenericBraces', SyntaxAt() 73 | 74 | # Keyword operators 75 | 76 | Given cs (typeof operator): 77 | typeof(Dictionary>) 78 | 79 | Execute: 80 | AssertEqual 'csTypeOf', SyntaxAt(1, 1) 81 | AssertEqual 'csParens', SyntaxAt(1, 7) 82 | AssertEqual 'csTypeOfOperand', SyntaxAt(1, 8) 83 | AssertEqual 'csParens', SyntaxAt(1, 38) 84 | 85 | Given cs (typeof operator with space before open paren): 86 | typeof (Dictionary>) 87 | 88 | Execute: 89 | AssertEqual 'csTypeOf', SyntaxAt(1, 1) 90 | AssertEqual 'csParens', SyntaxAt(1, 8) 91 | AssertEqual 'csTypeOfOperand', SyntaxAt(1, 9) 92 | AssertEqual 'csParens', SyntaxAt(1, 39) 93 | 94 | Given cs (typeof operator with missing operand parens): 95 | typeof Dictionary> 96 | 97 | Execute: 98 | AssertEqual 'csTypeOf', SyntaxAt(1, 1) 99 | AssertEqual 'csTypeOfError', SyntaxAt(1, 8) 100 | 101 | Given cs (await operator): 102 | await foobar(); 103 | 104 | Execute: 105 | AssertEqual 'csAsyncOperator', SyntaxAt(1, 1) 106 | 107 | Given cs (checked operator): 108 | var foobar = checked(42 + 1); 109 | 110 | Execute: 111 | AssertEqual 'csKeywordOperator', SyntaxOf('checked') 112 | 113 | Given cs (unchecked operator): 114 | var foobar = unchecked(42 + 1); 115 | 116 | Execute: 117 | AssertEqual 'csKeywordOperator', SyntaxOf('unchecked') 118 | 119 | -------------------------------------------------------------------------------- /test/preprocessors.vader: -------------------------------------------------------------------------------- 1 | Given cs (#define with comment): 2 | #define FOOBAR // define 3 | 4 | Execute: 5 | AssertEqual 'csPreProcDeclaration', SyntaxAt(1, 1) 6 | AssertEqual 'csPreProcDeclaration', SyntaxAt(1, 9) 7 | AssertEqual 'csLineComment', SyntaxAt(1, 16) 8 | 9 | Given cs (#undef with comment): 10 | #undef FOOBAR // undef 11 | 12 | Execute: 13 | AssertEqual 'csPreProcDeclaration', SyntaxAt(1, 1) 14 | AssertEqual 'csPreProcDeclaration', SyntaxAt(1, 8) 15 | AssertEqual 'csLineComment', SyntaxAt(1, 15) 16 | 17 | Given cs (indented #define): 18 | #define FOOBAR 19 | 20 | Execute: 21 | AssertEqual '', SyntaxAt(1, 1) 22 | AssertEqual 'csPreProcDeclaration', SyntaxAt(1, 5) 23 | AssertEqual 'csPreProcDeclaration', SyntaxAt(1, 13) 24 | 25 | Given cs (#if with comments): 26 | #if FOO // if 27 | Console.WriteLine("FOO") 28 | #elif BAR // elif 29 | Console.WriteLine("BAR") 30 | #else // else 31 | Console.WriteLine("BAZ") 32 | #endif // endif 33 | 34 | Execute: 35 | AssertEqual 'csPreProcConditional', SyntaxAt(1, 1) 36 | AssertEqual 'csPreProcConditional', SyntaxAt(1, 5) 37 | AssertEqual 'csLineComment', SyntaxAt(1, 11) 38 | AssertEqual 'csString', SyntaxAt(2, 24) 39 | AssertEqual 'csPreProcConditional', SyntaxAt(3, 1) 40 | AssertEqual 'csPreProcConditional', SyntaxAt(3, 7) 41 | AssertEqual 'csLineComment', SyntaxAt(3, 11) 42 | AssertEqual 'csString', SyntaxAt(4, 24) 43 | AssertEqual 'csPreProcConditional', SyntaxAt(5, 1) 44 | AssertEqual 'csLineComment', SyntaxAt(5, 11) 45 | AssertEqual 'csString', SyntaxAt(6, 24) 46 | AssertEqual 'csPreProcConditional', SyntaxAt(7, 1) 47 | AssertEqual 'csLineComment', SyntaxAt(7, 11) 48 | 49 | Given cs (#line with line number and comment): 50 | #line 42 // line 51 | 52 | Execute: 53 | AssertEqual 'csPreProcLine', SyntaxAt(1, 1) 54 | AssertEqual 'csPreProcLine', SyntaxAt(1, 7) 55 | AssertEqual 'csLineComment', SyntaxAt(1, 10) 56 | 57 | Given cs (#line with line number and filename): 58 | #line 42 "meaning.cs" // line 59 | 60 | Execute: 61 | AssertEqual 'csPreProcLine', SyntaxAt(1, 1) 62 | AssertEqual 'csPreProcLine', SyntaxAt(1, 7) 63 | AssertEqual 'csPreProcLine', SyntaxAt(1, 10) 64 | AssertEqual 'csLineComment', SyntaxAt(1, 23) 65 | 66 | Given cs (#line with comment): 67 | #line default // line 68 | 69 | Execute: 70 | AssertEqual 'csPreProcLine', SyntaxAt(1, 1) 71 | AssertEqual 'csPreProcLine', SyntaxAt(1, 7) 72 | AssertEqual 'csLineComment', SyntaxAt(1, 15) 73 | 74 | Given cs (#line with comment): 75 | #line hidden // error 76 | 77 | Execute: 78 | AssertEqual 'csPreProcLine', SyntaxAt(1, 1) 79 | AssertEqual 'csPreProcLine', SyntaxAt(1, 7) 80 | AssertEqual 'csLineComment', SyntaxAt(1, 14) 81 | 82 | Given cs (#error): 83 | #error This is the end 84 | 85 | Execute: 86 | AssertEqual 'csPreProcDiagnostic', SyntaxAt(1, 1) 87 | AssertEqual 'csPreProcDiagnostic', SyntaxAt(1, 8) 88 | 89 | Given cs (#warning): 90 | #warning The end is nigh 91 | 92 | Execute: 93 | AssertEqual 'csPreProcDiagnostic', SyntaxAt(1, 1) 94 | AssertEqual 'csPreProcDiagnostic', SyntaxAt(1, 10) 95 | 96 | Given cs (#region): 97 | #region enter region 98 | Console.WriteLine("Region") 99 | #endregion exit region 100 | 101 | Execute: 102 | AssertEqual 'csPreProcRegion', SyntaxAt(1, 1) 103 | AssertEqual 'csPreProcRegion', SyntaxAt(1, 9) 104 | AssertEqual 'csString', SyntaxAt(2, 24) 105 | AssertEqual 'csPreProcRegion', SyntaxAt(3, 1) 106 | AssertEqual 'csPreProcRegion', SyntaxAt(3, 12) 107 | 108 | Given cs (#pragma with comment): 109 | #pragma warning disable 414, CS3021 // pragma 110 | 111 | Execute: 112 | AssertEqual 'csPreProcPragma', SyntaxAt(1, 1) 113 | AssertEqual 'csPreProcPragma', SyntaxAt(1, 9) 114 | AssertEqual 'csPreProcPragma', SyntaxAt(1, 17) 115 | AssertEqual 'csLineComment', SyntaxAt(1, 37) 116 | 117 | Given cs (#nullable with comment): 118 | #nullable disable annotations // nullable 119 | 120 | Execute: 121 | AssertEqual 'csPreProcNullable', SyntaxAt(1, 1) 122 | AssertEqual 'csPreProcNullable', SyntaxAt(1, 11) 123 | AssertEqual 'csPreProcNullable', SyntaxAt(1, 19) 124 | AssertEqual 'csLineComment', SyntaxAt(1, 31) 125 | 126 | -------------------------------------------------------------------------------- /test/literals.vader: -------------------------------------------------------------------------------- 1 | Given cs (booleans): 2 | true 3 | false 4 | 5 | Execute: 6 | AssertEqual 'csBoolean', SyntaxAt(1, 1) 7 | AssertEqual 'csBoolean', SyntaxAt(2, 1) 8 | 9 | Given cs (null): 10 | null 11 | 12 | Execute: 13 | AssertEqual 'csNull', SyntaxAt(1, 1) 14 | 15 | Given cs (chars): 16 | 'a' 17 | '\'' 18 | 19 | Execute: 20 | AssertEqual 'csCharacter', SyntaxAt(1, 1) 21 | AssertEqual 'csCharacter', SyntaxAt(1, 2) 22 | AssertEqual 'csCharacter', SyntaxAt(1, 3) 23 | AssertEqual 'csCharacter', SyntaxAt(2, 1) 24 | AssertEqual 'csSpecialChar', SyntaxAt(2, 2) 25 | AssertEqual 'csSpecialChar', SyntaxAt(2, 3) 26 | AssertEqual 'csCharacter', SyntaxAt(2, 4) 27 | 28 | Given cs (decimal literals): 29 | 1234 30 | 1234l 31 | 1234u 32 | 1234ul 33 | 1234lu 34 | 35 | Execute: 36 | AssertEqual 'csInteger', SyntaxAt(1, 1) 37 | AssertEqual 'csInteger', SyntaxAt(2, 5) 38 | AssertEqual 'csInteger', SyntaxAt(3, 5) 39 | AssertEqual 'csInteger', SyntaxAt(4, 6) 40 | AssertEqual 'csInteger', SyntaxAt(5, 6) 41 | 42 | Given cs (hex literals): 43 | 0xf 44 | 0Xf 45 | 0xfl 46 | 0xfu 47 | 0xful 48 | 0xflu 49 | 0xg 50 | 51 | Execute: 52 | AssertEqual 'csInteger', SyntaxAt(1, 3) 53 | AssertEqual 'csInteger', SyntaxAt(2, 3) 54 | AssertEqual 'csInteger', SyntaxAt(3, 4) 55 | AssertEqual 'csInteger', SyntaxAt(4, 4) 56 | AssertEqual 'csInteger', SyntaxAt(5, 5) 57 | AssertEqual 'csInteger', SyntaxAt(6, 5) 58 | AssertNotEqual 'csInteger', SyntaxAt(7, 3), 'Not a hex digit' 59 | 60 | Given cs (binary literals): 61 | 0b0 62 | 0B0 63 | 0b0l 64 | 0b0u 65 | 0b0ul 66 | 0b0lu 67 | 0b2 68 | 69 | Execute: 70 | AssertEqual 'csInteger', SyntaxAt(1, 3) 71 | AssertEqual 'csInteger', SyntaxAt(2, 3) 72 | AssertEqual 'csInteger', SyntaxAt(3, 4) 73 | AssertEqual 'csInteger', SyntaxAt(4, 4) 74 | AssertEqual 'csInteger', SyntaxAt(5, 5) 75 | AssertEqual 'csInteger', SyntaxAt(6, 5) 76 | AssertNotEqual 'csInteger', SyntaxAt(7, 3), 'Not a binary digit' 77 | 78 | Given cs (floating point literals): 79 | 1.5f 80 | 1e10d 81 | 123.456D 82 | 123.456M 83 | 84 | Execute: 85 | AssertEqual 'csReal', SyntaxAt(1, 4) 86 | AssertEqual 'csReal', SyntaxAt(2, 5) 87 | AssertEqual 'csReal', SyntaxAt(3, 8) 88 | AssertEqual 'csReal', SyntaxAt(4, 8) 89 | 90 | Given cs (digit separators): 91 | 123_456 92 | 123__456 93 | 0x_be_af 94 | 0b_0011_0101 95 | 123_456.242_3D 96 | 97 | Execute: 98 | AssertEqual 'csInteger', SyntaxAt(1, 4) 99 | AssertEqual 'csInteger', SyntaxAt(2, 5) 100 | AssertEqual 'csInteger', SyntaxAt(3, 3) 101 | AssertEqual 'csInteger', SyntaxAt(4, 3) 102 | AssertEqual 'csReal', SyntaxAt(5, 4) 103 | AssertEqual 'csReal', SyntaxAt(5, 12) 104 | 105 | Given cs (valid char literals): 106 | '\x1' 107 | '\x41' 108 | '\x041' 109 | '\x0041' 110 | '\u0041' 111 | '\U00000041' 112 | 113 | Execute: 114 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(1, 2) 115 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(1, 3) 116 | AssertEqual 'csUnicodeNumber', SyntaxAt(1, 4) 117 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(2, 2) 118 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(2, 3) 119 | AssertEqual 'csUnicodeNumber', SyntaxAt(2, 4) 120 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(3, 2) 121 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(3, 3) 122 | AssertEqual 'csUnicodeNumber', SyntaxAt(3, 4) 123 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(4, 2) 124 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(4, 3) 125 | AssertEqual 'csUnicodeNumber', SyntaxAt(4, 4) 126 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(5, 2) 127 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(5, 3) 128 | AssertEqual 'csUnicodeNumber', SyntaxAt(5, 4) 129 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(6, 2) 130 | AssertEqual 'csUnicodeSpecifier', SyntaxAt(6, 3) 131 | AssertEqual 'csUnicodeNumber', SyntaxAt(6, 4) 132 | AssertEqual 'csUnicodeNumber', SyntaxAt(6, 11) 133 | 134 | Given cs (invalid char literals): 135 | '\xaaaaa' 136 | '\uaaaaa' 137 | '\U00aaaaaaa' 138 | '\x' 139 | '\uaaa' 140 | '\U00aaaaa' 141 | '\xg' 142 | '\ugggg' 143 | '\Ugggggggg' 144 | 145 | Execute: 146 | AssertEqual 'csSpecialCharError', SyntaxAt(1, 8), 'More than 4 digits (\x)' 147 | AssertEqual 'csSpecialCharError', SyntaxAt(2, 8), 'More than 4 digits (\u)' 148 | AssertEqual 'csSpecialCharError', SyntaxAt(3, 12), 'More than 8 digits (\U)' 149 | AssertEqual 'csSpecialCharError', SyntaxAt(4, 2), 'Less than 1 digit (\x)' 150 | AssertEqual 'csSpecialCharError', SyntaxAt(5, 2), 'Less than 4 digits (\u)' 151 | AssertEqual 'csSpecialCharError', SyntaxAt(6, 2), 'Less than 8 digits (\u)' 152 | AssertEqual 'csSpecialCharError', SyntaxAt(7, 4), 'Non-hex digit (\x)' 153 | AssertEqual 'csSpecialCharError', SyntaxAt(8, 4), 'Non-hex digit (\u)' 154 | AssertEqual 'csSpecialCharError', SyntaxAt(9, 4), 'Non-hex digit (\U)' 155 | 156 | -------------------------------------------------------------------------------- /syntax/cs.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: C# 3 | " Maintainer: Nick Jensen 4 | " Former Maintainers: Anduin Withers 5 | " Johannes Zellner 6 | " Last Change: 2022-11-16 7 | " Filenames: *.cs 8 | " License: Vim (see :h license) 9 | " Repository: https://github.com/nickspoons/vim-cs 10 | " 11 | " References: 12 | " - ECMA-334 5th Edition: C# Language Specification 13 | " https://www.ecma-international.org/publications-and-standards/standards/ecma-334/ 14 | " - C# Language Design: Draft 6th Edition and later proposals 15 | " https://github.com/dotnet/csharplang 16 | 17 | if exists('b:current_syntax') 18 | finish 19 | endif 20 | 21 | let s:save_cpo = &cpoptions 22 | set cpoptions&vim 23 | 24 | syn keyword csType bool byte char decimal double float int long object sbyte short string T uint ulong ushort var void dynamic 25 | syn keyword csType nint nuint " contextual 26 | 27 | syn keyword csStorage enum interface namespace struct 28 | syn match csStorage "\" 30 | syn match csStorage "\" 32 | syn keyword csRepeat break continue do for foreach goto return while 33 | syn keyword csConditional else if switch 34 | syn keyword csLabel case default 35 | 36 | syn match csNamespaceAlias "@\=\h\w*\ze\_s*::" display 37 | syn match csGlobalNamespaceAlias "global\ze\_s*::" display 38 | syn cluster csNamespaceAlias contains=csGlobalNamespaceAlias,csNamespaceAlias,csNamespaceAliasQualifier 39 | 40 | " user labels 41 | syn match csLabel display +^\s*\I\i*\s*:\%([^:]\)\@=+ 42 | 43 | " Function pointers 44 | syn match csType "\" 49 | syn keyword csAccessModifier internal private protected public 50 | syn keyword csModifier operator nextgroup=csCheckedModifier skipwhite skipempty 51 | syn keyword csCheckedModifier checked contained 52 | 53 | " TODO: in new out 54 | syn keyword csModifier abstract const event override readonly sealed static virtual volatile 55 | syn match csModifier "\<\%(extern\|fixed\|unsafe\)\>" 56 | syn match csModifier "\" 57 | 58 | syn keyword csException try catch finally throw when 59 | syn keyword csLinq ascending by descending equals from group in into join let on orderby select 60 | syn match csLinq "\" 61 | 62 | " Type parameter constraint clause 63 | syn match csStorage "\\ze\_s\+@\=\h\w*\_s*:" 64 | 65 | " Async 66 | syn keyword csAsyncModifier async 67 | syn keyword csAsyncOperator await 68 | 69 | syn match csStorage "\" 70 | syn match csStorage "\%(\" 71 | 72 | syn match csStatement "\<\%(checked\|unchecked\|unsafe\)\ze\_s*{" 73 | syn match csStatement "\" 76 | 77 | syn match csAccessor "\<\%(get\|set\|init\|add\|remove\)\ze\_s*\%([;{]\|=>\)" 78 | 79 | syn keyword csAccess base 80 | syn match csAccess "\" 81 | 82 | " Extension method parameter modifier 83 | syn match csModifier "\\{1,2}" display 102 | syn match csOpSymbols "<\{1,2}" display 103 | syn match csOpSymbols "[!><+\-*/]=" display 104 | syn match csOpSymbols "[!*/^]" display 105 | syn match csOpSymbols "=>" display 106 | syn match csEndColon ";" display 107 | syn match csLogicSymbols "&&" display 108 | syn match csLogicSymbols "||" display 109 | syn match csLogicSymbols "?" display 110 | syn match csLogicSymbols ":" display 111 | syn match csNamespaceAliasQualifier "::" display 112 | 113 | " Generics 114 | syn region csGeneric matchgroup=csGenericBraces start="<" end=">" oneline contains=csType,csGeneric,@csNamespaceAlias,csUserType,csUserIdentifier,csUserInterface,csUserMethod 115 | 116 | " Comments 117 | " 118 | " PROVIDES: @csCommentHook 119 | syn keyword csTodo contained TODO FIXME XXX NOTE HACK TBD 120 | syn region csBlockComment start="/\*" end="\*/" contains=@csCommentHook,csTodo,@Spell 121 | syn match csLineComment "//.*$" contains=@csCommentHook,csTodo,@Spell 122 | syn cluster csComment contains=csLineComment,csBlockComment 123 | 124 | syn region csSummary start="^\s*/// ' 164 | syn region csPreProcInclude start="^\s*\zs#\s*\%(load\|r\)\>" end="$" contains=csLineComment keepend 165 | syn match csShebang "\%^#!.*" display 166 | endif 167 | 168 | syn cluster csPreProcessor contains=csPreProc.* 169 | 170 | syn region csClassType start="\"hs=s+6 end=">" end="[:{]"me=e-1 contains=csClass 171 | " csUserType may be defined by user scripts/plugins - it should be contained in csNewType 172 | syn region csNewType start="\"hs=s+4 end="[;\n{(<\[]"me=e-1 contains=csNew,@csNamespaceAlias,csUserType 173 | syn region csIsType start=" is "hs=s+4 end="[A-Za-z0-9]\+" oneline contains=csIsAs 174 | syn region csIsType start=" as "hs=s+4 end="[A-Za-z0-9]\+" oneline contains=csIsAs 175 | syn keyword csNew new contained 176 | syn keyword csClass class contained 177 | syn keyword csIsAs is as 178 | 179 | syn keyword csBoolean false true 180 | syn keyword csNull null 181 | 182 | " Strings and constants 183 | syn match csSpecialError "\\." contained 184 | syn match csSpecialCharError "[^']" contained 185 | " Character literals 186 | syn match csSpecialChar +\\["\\'0abfnrtv]+ contained display 187 | syn match csUnicodeNumber +\\x\x\{1,4}+ contained contains=csUnicodeSpecifier display 188 | syn match csUnicodeNumber +\\u\x\{4}+ contained contains=csUnicodeSpecifier display 189 | syn match csUnicodeNumber +\\U00\x\{6}+ contained contains=csUnicodeSpecifier display 190 | syn match csUnicodeSpecifier +\\[uUx]+ contained display 191 | 192 | syn region csString matchgroup=csQuote start=+"+ end=+"\%(u8\)\=+ end=+$+ extend contains=csSpecialChar,csSpecialError,csUnicodeNumber,@Spell 193 | syn match csCharacter "'[^']*'" contains=csSpecialChar,csSpecialCharError,csUnicodeNumber display 194 | syn match csCharacter "'\\''" contains=csSpecialChar display 195 | syn match csCharacter "'[^\\]'" display 196 | 197 | " Numbers 198 | syn case ignore 199 | syn match csInteger "\<0b[01_]*[01]\%([lu]\|lu\|ul\)\=\>" display 200 | syn match csInteger "\<\d\+\%(_\+\d\+\)*\%([lu]\|lu\|ul\)\=\>" display 201 | syn match csInteger "\<0x[[:xdigit:]_]*\x\%([lu]\|lu\|ul\)\=\>" display 202 | syn match csReal "\<\d\+\%(_\+\d\+\)*\.\d\+\%(_\+\d\+\)*\%\(e[-+]\=\d\+\%(_\+\d\+\)*\)\=[fdm]\=" display 203 | syn match csReal "\.\d\+\%(_\+\d\+\)*\%(e[-+]\=\d\+\%(_\+\d\+\)*\)\=[fdm]\=\>" display 204 | syn match csReal "\<\d\+\%(_\+\d\+\)*e[-+]\=\d\+\%(_\+\d\+\)*[fdm]\=\>" display 205 | syn match csReal "\<\d\+\%(_\+\d\+\)*[fdm]\>" display 206 | syn case match 207 | syn cluster csNumber contains=csInteger,csReal 208 | 209 | syn region csInterpolatedString matchgroup=csQuote start=+\$"+ end=+"\%(u8\)\=+ extend contains=csInterpolation,csEscapedInterpolation,csSpecialChar,csSpecialError,csUnicodeNumber,@Spell 210 | 211 | syn region csInterpolation matchgroup=csInterpolationDelimiter start=+{+ end=+}+ keepend contained contains=@csAll,csBraced,csBracketed,csInterpolationAlign,csInterpolationFormat 212 | syn match csEscapedInterpolation "{{" transparent contains=NONE display 213 | syn match csEscapedInterpolation "}}" transparent contains=NONE display 214 | syn region csInterpolationAlign matchgroup=csInterpolationAlignDel start=+,+ end=+}+ end=+:+me=e-1 contained contains=@csNumber,csBoolean,csConstant,csCharacter,csParens,csOpSymbols,csString,csBracketed display 215 | syn match csInterpolationFormat +:[^}]\+}+ contained contains=csInterpolationFormatDel display 216 | syn match csInterpolationAlignDel +,+ contained display 217 | syn match csInterpolationFormatDel +:+ contained display 218 | 219 | syn region csVerbatimString matchgroup=csQuote start=+@"+ end=+"\%(u8\)\=+ skip=+""+ extend contains=csVerbatimQuote,@Spell 220 | syn match csVerbatimQuote +""+ contained 221 | 222 | syn region csInterVerbString matchgroup=csQuote start=+$@"+ start=+@$"+ end=+"\%(u8\)\=+ skip=+""+ extend contains=csInterpolation,csEscapedInterpolation,csSpecialChar,csSpecialError,csUnicodeNumber,csVerbatimQuote,@Spell 223 | 224 | syn cluster csString contains=csString,csInterpolatedString,csVerbatimString,csInterVerbString 225 | 226 | syn cluster csLiteral contains=csBoolean,@csNumber,csCharacter,@csString,csNull 227 | 228 | syn region csBracketed matchgroup=csParens start=+(+ end=+)+ extend contained transparent contains=@csAll,csBraced,csBracketed 229 | syn region csBraced matchgroup=csParens start=+{+ end=+}+ extend contained transparent contains=@csAll,csBraced,csBracketed 230 | 231 | syn cluster csAll contains=@csLiteral,csClassType,@csComment,csEndColon,csIsType,csLabel,csLogicSymbols,csNewType,csOpSymbols,csParens,@csPreProcessor,csSummary,@csNamespaceAlias,csType,csUnicodeNumber,csUserType,csUserIdentifier,csUserInterface,csUserMethod 232 | 233 | " Keyword identifiers 234 | syn match csIdentifier "@\h\w*" 235 | 236 | " The default highlighting. 237 | hi def link csUnspecifiedStatement Statement 238 | hi def link csUnsupportedStatement Statement 239 | hi def link csUnspecifiedKeyword Keyword 240 | 241 | hi def link csGlobalNamespaceAlias Include 242 | 243 | hi def link csType Type 244 | hi def link csClassType Type 245 | hi def link csIsType Type 246 | 247 | hi def link csStorage Structure 248 | hi def link csClass Structure 249 | hi def link csNew Statement 250 | hi def link csIsAs Keyword 251 | hi def link csAccessor Keyword 252 | hi def link csAccess Keyword 253 | 254 | hi def link csLinq Statement 255 | 256 | hi def link csStatement Statement 257 | hi def link csRepeat Repeat 258 | hi def link csConditional Conditional 259 | hi def link csLabel Label 260 | hi def link csException Exception 261 | 262 | hi def link csModifier StorageClass 263 | hi def link csAccessModifier csModifier 264 | hi def link csAsyncModifier csModifier 265 | hi def link csCheckedModifier csModifier 266 | hi def link csManagedModifier csModifier 267 | hi def link csUsingModifier csModifier 268 | 269 | hi def link csTodo Todo 270 | hi def link csComment Comment 271 | hi def link csLineComment csComment 272 | hi def link csBlockComment csComment 273 | 274 | hi def link csKeywordOperator Keyword 275 | hi def link csAsyncOperator csKeywordOperator 276 | hi def link csTypeOf csKeywordOperator 277 | hi def link csTypeOfOperand Typedef 278 | hi def link csTypeOfError Error 279 | hi def link csOpSymbols Operator 280 | hi def link csLogicSymbols Operator 281 | 282 | hi def link csSpecialError Error 283 | hi def link csSpecialCharError Error 284 | hi def link csString String 285 | hi def link csQuote String 286 | hi def link csInterpolatedString String 287 | hi def link csVerbatimString String 288 | hi def link csInterVerbString String 289 | hi def link csVerbatimQuote SpecialChar 290 | 291 | hi def link csPreProc PreProc 292 | hi def link csPreProcDeclaration Define 293 | hi def link csPreProcConditional PreCondit 294 | hi def link csPreProcLine csPreProc 295 | hi def link csPreProcDiagnostic csPreProc 296 | hi def link csPreProcRegion csPreProc 297 | hi def link csPreProcPragma csPreProc 298 | hi def link csPreProcNullable csPreProc 299 | hi def link csPreProcInclude csPreProc 300 | hi def link csShebang csPreProc 301 | 302 | hi def link csConstant Constant 303 | hi def link csNull Constant 304 | hi def link csBoolean Boolean 305 | hi def link csCharacter Character 306 | hi def link csSpecialChar SpecialChar 307 | hi def link csInteger Number 308 | hi def link csReal Float 309 | hi def link csUnicodeNumber SpecialChar 310 | hi def link csUnicodeSpecifier SpecialChar 311 | hi def link csInterpolationDelimiter Delimiter 312 | hi def link csInterpolationAlignDel csInterpolationDelimiter 313 | hi def link csInterpolationFormat csInterpolationDelimiter 314 | hi def link csInterpolationFormatDel csInterpolationDelimiter 315 | 316 | hi def link csGenericBraces csBraces 317 | 318 | " xml markup 319 | hi def link csXmlLineCommentLeader Comment 320 | hi def link csXmlLineComment Comment 321 | hi def link csXmlBlockComment Comment 322 | hi def link csXmlBlockCommentMiddle csXmlBlockComment 323 | hi def link csXmlTag Statement 324 | hi def link csXmlAttrib Statement 325 | 326 | let b:current_syntax = 'cs' 327 | 328 | let &cpoptions = s:save_cpo 329 | unlet s:save_cpo 330 | 331 | " vim: vts=16,28 332 | -------------------------------------------------------------------------------- /test/strings.vader: -------------------------------------------------------------------------------- 1 | Given cs (a simple string): 2 | "a" 3 | 4 | Execute: 5 | AssertEqual 'csQuote', SyntaxAt(1) 6 | AssertEqual 'csString', SyntaxAt(2) 7 | AssertEqual 'csQuote', SyntaxAt(3) 8 | 9 | Given cs (a simple string containing a single quote): 10 | "a'b" 11 | 12 | Execute: 13 | AssertEqual 'csString', SyntaxAt(3) 14 | 15 | Given cs (a string containing an escaped double quote): 16 | "a\"b" 17 | 18 | Execute: 19 | AssertEqual 'csString', SyntaxAt(2) 20 | AssertEqual 'csSpecialChar', SyntaxAt(3) 21 | AssertEqual 'csSpecialChar', SyntaxAt(4) 22 | AssertEqual 'csString', SyntaxAt(5) 23 | 24 | Given cs (a simple string containing {}): 25 | "a{b}c" 26 | 27 | Execute: 28 | AssertEqual 'csString', SyntaxAt(2) 29 | AssertEqual 'csString', SyntaxAt(3), 'Do not highlight {} in simple string' 30 | AssertEqual 'csString', SyntaxAt(4) 31 | AssertEqual 'csString', SyntaxAt(5), 'Do not highlight {} in simple string' 32 | AssertEqual 'csString', SyntaxAt(6) 33 | 34 | Given cs (a multiline string (illegal)): 35 | "a 36 | b" 37 | 38 | Execute: 39 | AssertEqual 'csString', SyntaxAt(1, 2) 40 | AssertNotEqual 'csString', SyntaxAt(2, 2) 41 | 42 | Given cs (a simple verbatim (@) string): 43 | @"a" 44 | 45 | Execute: 46 | AssertEqual 'csQuote', SyntaxAt(1) 47 | AssertEqual 'csQuote', SyntaxAt(2) 48 | AssertEqual 'csVerbatimString', SyntaxAt(3) 49 | AssertEqual 'csQuote', SyntaxAt(4) 50 | 51 | Given cs (a verbatim string containing ""): 52 | @"""a""b""" 53 | 54 | Execute: 55 | AssertEqual 'csQuote', SyntaxAt(1) 56 | AssertEqual 'csQuote', SyntaxAt(2) 57 | AssertEqual 'csVerbatimQuote', SyntaxAt(3), 'Highlight double quotes ("")' 58 | AssertEqual 'csVerbatimQuote', SyntaxAt(4) 59 | AssertEqual 'csVerbatimString', SyntaxAt(5) 60 | AssertEqual 'csVerbatimQuote', SyntaxAt(6) 61 | AssertEqual 'csVerbatimQuote', SyntaxAt(7) 62 | AssertEqual 'csVerbatimString', SyntaxAt(8) 63 | AssertEqual 'csVerbatimQuote', SyntaxAt(9) 64 | AssertEqual 'csVerbatimQuote', SyntaxAt(10) 65 | AssertEqual 'csQuote', SyntaxAt(11) 66 | 67 | Given cs (a verbatim string containing \"): 68 | @"a\"b 69 | 70 | Execute: 71 | AssertEqual 'csQuote', SyntaxAt(1) 72 | AssertEqual 'csQuote', SyntaxAt(2) 73 | AssertEqual 'csVerbatimString', SyntaxAt(3) 74 | AssertEqual 'csVerbatimString', SyntaxAt(4), 'Do not highlight \-escaped quotes' 75 | AssertEqual 'csQuote', SyntaxAt(5) 76 | AssertNotEqual 'csString', SyntaxAt(6) 77 | AssertNotEqual 'csQuote', SyntaxAt(6) 78 | AssertNotEqual 'csVerbatimString', SyntaxAt(6) 79 | 80 | Given cs (a multiline verbatim string): 81 | @"a 82 | b" 83 | 84 | Execute: 85 | AssertEqual 'csVerbatimString', SyntaxAt(1, 3) 86 | AssertEqual 'csVerbatimString', SyntaxAt(2, 3) 87 | 88 | Given cs (an interpolated string with no interpolation): 89 | $"a" 90 | 91 | Execute: 92 | AssertEqual 'csQuote', SyntaxAt(1) 93 | AssertEqual 'csQuote', SyntaxAt(2) 94 | AssertEqual 'csInterpolatedString', SyntaxAt(3) 95 | AssertEqual 'csQuote', SyntaxAt(4) 96 | 97 | Given cs (a simple interpolated string): 98 | $"a:{'a'}, n:{5}" 99 | 100 | Execute: 101 | AssertEqual 'csInterpolatedString', SyntaxAt(4) 102 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(5) 103 | AssertEqual 'csCharacter', SyntaxAt(6) 104 | AssertEqual 'csCharacter', SyntaxAt(7) 105 | AssertEqual 'csCharacter', SyntaxAt(8) 106 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(9) 107 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(14) 108 | AssertEqual 'csInteger', SyntaxAt(15) 109 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(16) 110 | 111 | Given cs (interpolated strings, containing strings): 112 | $"a:{"a\""} " 113 | $"b:{@"b"""} " 114 | $"c{$"c{1}"}\"" 115 | 116 | Execute: 117 | AssertEqual 'csQuote', SyntaxAt(1, 1) 118 | AssertEqual 'csQuote', SyntaxAt(1, 2) 119 | AssertEqual 'csInterpolatedString', SyntaxAt(1, 3) 120 | AssertEqual 'csInterpolatedString', SyntaxAt(1, 4) 121 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 5) 122 | AssertEqual 'csQuote', SyntaxAt(1, 6) 123 | AssertEqual 'csString', SyntaxAt(1, 7) 124 | AssertEqual 'csSpecialChar', SyntaxAt(1, 8) 125 | AssertEqual 'csSpecialChar', SyntaxAt(1, 9) 126 | AssertEqual 'csQuote', SyntaxAt(1, 10) 127 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 11) 128 | AssertEqual 'csInterpolatedString', SyntaxAt(1, 12) 129 | AssertEqual 'csQuote', SyntaxAt(1, 13) 130 | AssertEqual 'csInterpolatedString', SyntaxAt(2, 3) 131 | AssertEqual 'csInterpolatedString', SyntaxAt(2, 4) 132 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(2, 5) 133 | AssertEqual 'csQuote', SyntaxAt(2, 6) 134 | AssertEqual 'csQuote', SyntaxAt(2, 7) 135 | AssertEqual 'csVerbatimString', SyntaxAt(2, 8) 136 | AssertEqual 'csVerbatimQuote', SyntaxAt(2, 9) 137 | AssertEqual 'csVerbatimQuote', SyntaxAt(2, 10) 138 | AssertEqual 'csQuote', SyntaxAt(2, 11) 139 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(2, 12) 140 | AssertEqual 'csInterpolatedString', SyntaxAt(2, 13) 141 | AssertEqual 'csQuote', SyntaxAt(2, 14) 142 | AssertEqual 'csInterpolatedString', SyntaxAt(3, 3) 143 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(3, 4) 144 | AssertEqual 'csQuote', SyntaxAt(3, 5) 145 | AssertEqual 'csQuote', SyntaxAt(3, 6) 146 | AssertEqual 'csInterpolatedString', SyntaxAt(3, 7) 147 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(3, 8) 148 | AssertEqual 'csInteger', SyntaxAt(3, 9) 149 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(3, 10) 150 | AssertEqual 'csQuote', SyntaxAt(3, 11) 151 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(3, 12) 152 | AssertEqual 'csSpecialChar', SyntaxAt(3, 13) 153 | AssertEqual 'csSpecialChar', SyntaxAt(3, 14) 154 | AssertEqual 'csQuote', SyntaxAt(3, 15) 155 | 156 | Given cs (an interpolated string, containing aligned strings): 157 | $"a:{"a",3} b:{"b",-5}" 158 | 159 | Execute: 160 | AssertEqual 'csInterpolatedString', SyntaxAt(4) 161 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(5) 162 | AssertEqual 'csQuote', SyntaxAt(6) 163 | AssertEqual 'csString', SyntaxAt(7) 164 | AssertEqual 'csQuote', SyntaxAt(8) 165 | AssertEqual 'csInterpolationAlignDel', SyntaxAt(9) 166 | AssertEqual 'csInteger', SyntaxAt(10) 167 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(11) 168 | AssertEqual 'csInterpolatedString', SyntaxAt(12) 169 | AssertEqual 'csInterpolatedString', SyntaxAt(13) 170 | AssertEqual 'csInterpolatedString', SyntaxAt(14) 171 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(15) 172 | AssertEqual 'csQuote', SyntaxAt(16) 173 | AssertEqual 'csString', SyntaxAt(17) 174 | AssertEqual 'csQuote', SyntaxAt(18) 175 | AssertEqual 'csInterpolationAlignDel', SyntaxAt(19) 176 | AssertEqual 'csOpSymbols', SyntaxAt(20) 177 | AssertEqual 'csInteger', SyntaxAt(21) 178 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(22) 179 | AssertEqual 'csQuote', SyntaxAt(23) 180 | 181 | Given cs (strings interpolated with formatted numbers): 182 | $"a:{5:0} b:{5:F}" 183 | 184 | Execute: 185 | AssertEqual 'csInterpolatedString', SyntaxAt(4) 186 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(5) 187 | AssertEqual 'csInteger', SyntaxAt(6) 188 | AssertEqual 'csInterpolationFormatDel', SyntaxAt(7) 189 | AssertEqual 'csInterpolationFormat', SyntaxAt(8) 190 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(9) 191 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(13) 192 | AssertEqual 'csInteger', SyntaxAt(14) 193 | AssertEqual 'csInterpolationFormatDel', SyntaxAt(15) 194 | AssertEqual 'csInterpolationFormat', SyntaxAt(16) 195 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(17) 196 | 197 | Given cs (a string interpolated with an aligned, formatted integer): 198 | $"a:{ 5,-(true?-3:3):0,# }" 199 | 200 | Execute: 201 | AssertEqual 'csInterpolatedString', SyntaxAt(4) 202 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(5) 203 | AssertEqual 'csInterpolation', SyntaxAt(6) 204 | AssertEqual 'csInteger', SyntaxAt(7) 205 | AssertEqual 'csInterpolationAlignDel', SyntaxAt(8) 206 | AssertEqual 'csOpSymbols', SyntaxAt(9) 207 | AssertEqual 'csParens', SyntaxAt(10) 208 | AssertEqual 'csBoolean', SyntaxAt(11) 209 | AssertEqual 'csBoolean', SyntaxAt(12) 210 | AssertEqual 'csBoolean', SyntaxAt(13) 211 | AssertEqual 'csBoolean', SyntaxAt(14) 212 | AssertEqual 'csLogicSymbols', SyntaxAt(15) 213 | AssertEqual 'csOpSymbols', SyntaxAt(16) 214 | AssertEqual 'csInteger', SyntaxAt(17) 215 | AssertEqual 'csLogicSymbols', SyntaxAt(18) 216 | AssertEqual 'csInteger', SyntaxAt(19) 217 | AssertEqual 'csParens', SyntaxAt(20) 218 | AssertEqual 'csInterpolationFormatDel', SyntaxAt(21) 219 | AssertEqual 'csInterpolationFormat', SyntaxAt(22) 220 | AssertEqual 'csInterpolationFormat', SyntaxAt(23) 221 | AssertEqual 'csInterpolationFormat', SyntaxAt(24) 222 | AssertEqual 'csInterpolationFormat', SyntaxAt(25) 223 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(26) 224 | 225 | Given cs (an interpolated string containing escaped (doubled) {{ }}): 226 | $"{{{5}}} a:{{'ab'}} '{ab}'c" 227 | 228 | Execute: 229 | AssertEqual 'csQuote', SyntaxAt(1) 230 | AssertEqual 'csQuote', SyntaxAt(2) 231 | AssertEqual 'csInterpolatedString', SyntaxAt(3) 232 | AssertEqual 'csInterpolatedString', SyntaxAt(4) 233 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(5) 234 | AssertEqual 'csInteger', SyntaxAt(6) 235 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(7) 236 | AssertEqual 'csInterpolatedString', SyntaxAt(8) 237 | AssertEqual 'csInterpolatedString', SyntaxAt(9) 238 | AssertEqual 'csInterpolatedString', SyntaxAt(10) 239 | AssertEqual 'csInterpolatedString', SyntaxAt(11) 240 | AssertEqual 'csInterpolatedString', SyntaxAt(12) 241 | AssertEqual 'csInterpolatedString', SyntaxAt(13) 242 | AssertEqual 'csInterpolatedString', SyntaxAt(14) 243 | AssertEqual 'csInterpolatedString', SyntaxAt(15) 244 | AssertEqual 'csInterpolatedString', SyntaxAt(16) 245 | AssertEqual 'csInterpolatedString', SyntaxAt(17) 246 | AssertEqual 'csInterpolatedString', SyntaxAt(18) 247 | AssertEqual 'csInterpolatedString', SyntaxAt(19) 248 | AssertEqual 'csInterpolatedString', SyntaxAt(20) 249 | AssertEqual 'csInterpolatedString', SyntaxAt(21) 250 | AssertEqual 'csInterpolatedString', SyntaxAt(22) 251 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(23) 252 | AssertEqual 'csInterpolation', SyntaxAt(24) 253 | AssertEqual 'csInterpolation', SyntaxAt(25) 254 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(26) 255 | AssertEqual 'csInterpolatedString', SyntaxAt(27) 256 | AssertEqual 'csInterpolatedString', SyntaxAt(28) 257 | 258 | Given cs (a verbatim, interpolated string): 259 | $@"a:{'a'}"" 260 | b""" 261 | 262 | Execute: 263 | AssertEqual 'csQuote', SyntaxAt(1, 1) 264 | AssertEqual 'csQuote', SyntaxAt(1, 2) 265 | AssertEqual 'csQuote', SyntaxAt(1, 3) 266 | AssertEqual 'csInterVerbString', SyntaxAt(1, 4) 267 | AssertEqual 'csInterVerbString', SyntaxAt(1, 5) 268 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 6) 269 | AssertEqual 'csCharacter', SyntaxAt(1, 7) 270 | AssertEqual 'csCharacter', SyntaxAt(1, 8) 271 | AssertEqual 'csCharacter', SyntaxAt(1, 9) 272 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 10) 273 | AssertEqual 'csVerbatimQuote', SyntaxAt(1, 11) 274 | AssertEqual 'csVerbatimQuote', SyntaxAt(1, 12) 275 | AssertEqual 'csInterVerbString', SyntaxAt(2, 1) 276 | AssertEqual 'csInterVerbString', SyntaxAt(2, 2) 277 | AssertEqual 'csInterVerbString', SyntaxAt(2, 3) 278 | AssertEqual 'csVerbatimQuote', SyntaxAt(2, 4) 279 | AssertEqual 'csVerbatimQuote', SyntaxAt(2, 5) 280 | AssertEqual 'csQuote', SyntaxAt(2, 6) 281 | 282 | Given cs (a verbatim, interpolated string containing braces): 283 | $@"a:{new{'a'}}a" 284 | 285 | Execute: 286 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 6) 287 | AssertEqual 'csNew', SyntaxAt(1, 7) 288 | AssertEqual 'csNew', SyntaxAt(1, 8) 289 | AssertEqual 'csNew', SyntaxAt(1, 9) 290 | AssertEqual 'csParens', SyntaxAt(1, 10) 291 | AssertEqual 'csCharacter', SyntaxAt(1, 11) 292 | AssertEqual 'csCharacter', SyntaxAt(1, 12) 293 | AssertEqual 'csCharacter', SyntaxAt(1, 13) 294 | AssertEqual 'csParens', SyntaxAt(1, 14) 295 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 15) 296 | AssertEqual 'csInterVerbString', SyntaxAt(1, 16) 297 | AssertEqual 'csQuote', SyntaxAt(1, 17) 298 | 299 | Given cs (a verbatim, interpolated string containing brackets): 300 | $@"a:{('a')}a" 301 | 302 | Execute: 303 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 6) 304 | AssertEqual 'csParens', SyntaxAt(1, 7) 305 | AssertEqual 'csCharacter', SyntaxAt(1, 8) 306 | AssertEqual 'csCharacter', SyntaxAt(1, 9) 307 | AssertEqual 'csCharacter', SyntaxAt(1, 10) 308 | AssertEqual 'csParens', SyntaxAt(1, 11) 309 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 12) 310 | AssertEqual 'csInterVerbString', SyntaxAt(1, 13) 311 | AssertEqual 'csQuote', SyntaxAt(1, 14) 312 | 313 | Given cs (a nested verbatim, interpolated string): 314 | $@"a:{$@"b{'c'}"}"" 315 | c""" 316 | 317 | Execute: 318 | AssertEqual 'csQuote', SyntaxAt(1, 1) 319 | AssertEqual 'csQuote', SyntaxAt(1, 2) 320 | AssertEqual 'csQuote', SyntaxAt(1, 3) 321 | AssertEqual 'csInterVerbString', SyntaxAt(1, 4) 322 | AssertEqual 'csInterVerbString', SyntaxAt(1, 5) 323 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 6) 324 | AssertEqual 'csQuote', SyntaxAt(1, 7) 325 | AssertEqual 'csQuote', SyntaxAt(1, 8) 326 | AssertEqual 'csQuote', SyntaxAt(1, 9) 327 | AssertEqual 'csInterVerbString', SyntaxAt(1, 10) 328 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 11) 329 | AssertEqual 'csCharacter', SyntaxAt(1, 12) 330 | AssertEqual 'csCharacter', SyntaxAt(1, 13) 331 | AssertEqual 'csCharacter', SyntaxAt(1, 14) 332 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 15) 333 | AssertEqual 'csQuote', SyntaxAt(1, 16) 334 | AssertEqual 'csInterpolationDelimiter', SyntaxAt(1, 17) 335 | AssertEqual 'csVerbatimQuote', SyntaxAt(1, 18) 336 | AssertEqual 'csVerbatimQuote', SyntaxAt(1, 19) 337 | AssertEqual 'csInterVerbString', SyntaxAt(2, 1) 338 | AssertEqual 'csInterVerbString', SyntaxAt(2, 2) 339 | AssertEqual 'csInterVerbString', SyntaxAt(2, 3) 340 | AssertEqual 'csVerbatimQuote', SyntaxAt(2, 4) 341 | AssertEqual 'csVerbatimQuote', SyntaxAt(2, 5) 342 | AssertEqual 'csQuote', SyntaxAt(2, 6) 343 | 344 | Given cs (a verbatim, interpolated string with alternate open delimiter (@$ instead of $@)): 345 | @$"..." 346 | 347 | Execute: 348 | AssertEqual 'csQuote', SyntaxAt(1) 349 | AssertEqual 'csQuote', SyntaxAt(2) 350 | AssertEqual 'csQuote', SyntaxAt(3) 351 | AssertEqual 'csInterVerbString', SyntaxAt(4) 352 | 353 | Given cs (UTF8 string literals): 354 | "..."u8 355 | $"..."u8 356 | @"..."u8 357 | $@"..."u8 358 | 359 | Execute: 360 | AssertEqual 'csQuote', SyntaxOf("u8", 1) 361 | AssertEqual 'csQuote', SyntaxOf("u8", 2) 362 | AssertEqual 'csQuote', SyntaxOf("u8", 3) 363 | AssertEqual 'csQuote', SyntaxOf("u8", 4) 364 | --------------------------------------------------------------------------------