├── .gitignore ├── AUTHORS ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DartFmt.gif ├── LICENSE ├── README.md ├── autoload └── dart.vim ├── doc └── dart.txt ├── ftdetect └── dart.vim ├── ftplugin └── dart.vim ├── indent └── dart.vim ├── plugin └── dart.vim └── syntax └── dart.vim /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Below is a list of people and organizations that have contributed 2 | # to the Dart project. Names should be added to the list like so: 3 | # 4 | # If you contributed to the project(s) in this repository, and would 5 | # like your name included here, please contact misc@dartlang.org mailing list. 6 | # 7 | # Name/Organization 8 | 9 | Google Inc. 10 | 11 | Ladislav Thon 12 | Nishino Naruhiko (@rbtnn) 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | #### 0.2.1 2 | * Added `DartAnalyzer` and `Dart2Js`. 3 | * Renamed `DartFormat` to `DartFmt`. 4 | 5 | #### 0.2.0 6 | * `dartformat` renamed to `dartfmt`. 7 | 8 | #### 0.1.1 9 | * Added DartFormat command. 10 | 11 | #### 0.1.0 12 | * Added CHANGELOG.md. 13 | * Added CONTRIBUTING.md. 14 | * Added support for async, await, yield keywords. 15 | * Added triple-slash (doc comment) to accepted comment formats. 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | ### Sign our Contributor License Agreement (CLA) 4 | 5 | Even for small changes, we ask that you please sign the CLA electronically 6 | [here](https://developers.google.com/open-source/cla/individual). 7 | The CLA is necessary because you own the copyright to your changes, even 8 | after your contribution becomes part of our codebase, so we need your permission 9 | to use and distribute your code. You can find more details 10 | [here](https://code.google.com/p/dart/wiki/Contributing). 11 | -------------------------------------------------------------------------------- /DartFmt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dart-lang/dart-vim-plugin/4bdc04e2540edf90fda2812434c11d19dc04bc8f/DartFmt.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012, the Dart project authors. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following 11 | disclaimer in the documentation and/or other materials provided 12 | with the distribution. 13 | * Neither the name of Google LLC nor the names of its 14 | contributors may be used to endorse or promote products derived 15 | from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dart Support for Vim 2 | 3 | dart-vim-plugin provides filetype detection, syntax highlighting, and 4 | indentation for [Dart][] code in Vim. 5 | 6 | Looking for auto-complete, diagnostics as you type, jump to definition and other 7 | intellisense features? Try a vim plugin for the 8 | [Language Server Protocol](http://langserver.org/) such as [vim-lsc][] 9 | configured to start the Dart analysis server with the `--lsp` flag. 10 | 11 | Looking for an IDE experience? See the [Dart Tools][] page. 12 | 13 | [Dart]: https://dart.dev/ 14 | [Dart tools]: https://dart.dev/tools 15 | [vim-lsc]: https://github.com/natebosch/vim-lsc 16 | 17 | ## Commands 18 | 19 | ### :DartFmt 20 | 21 | ![](https://raw.github.com/dart-lang/dart-vim-plugin/master/DartFmt.gif) 22 | 23 | ## Installation 24 | 25 | Install as a typical vim plugin using your favorite approach. If you don't have 26 | a preference [vim-plug][] is a good place to start. Below are examples for 27 | common choices, be sure to read the docs for each option. 28 | 29 | ### [vim-plug][] 30 | 31 | [vim-plug]: https://github.com/junegunn/vim-plug 32 | 33 | ```vimscript 34 | call plug#begin() 35 | "... 36 | Plug 'dart-lang/dart-vim-plugin' 37 | 38 | call plug#end() 39 | ``` 40 | 41 | Then invoke `:PlugInstall` to install the plugin. 42 | 43 | ### [pathogen][] 44 | 45 | [pathogen]: https://github.com/tpope/vim-pathogen 46 | 47 | Clone the repository into your pathogen directory. 48 | 49 | ```sh 50 | mkdir -p ~/.vim/bundle && cd ~/.vim/bundle && \ 51 | git clone https://github.com/dart-lang/dart-vim-plugin 52 | ``` 53 | 54 | Ensure your `.vimrc` contains the line `execute pathogen#infect()` 55 | 56 | ### [vundle][] 57 | 58 | [vundle]: https://github.com/VundleVim/Vundle.vim 59 | 60 | ```vimscript 61 | set rtp+=~/.vim/bundle/Vundle.vim 62 | call vundle#begin() 63 | "... 64 | Plugin 'dart-lang/dart-vim-plugin' 65 | 66 | call vundle#end() 67 | ``` 68 | 69 | ## Configuration 70 | 71 | Enable HTML syntax highlighting inside Dart strings with `let 72 | g:dart_html_in_string = v:true` (default false). 73 | 74 | Highlighting for specific syntax groups can be disabled by defining custom 75 | highlight group links. See `:help dart-syntax` 76 | 77 | Enable Dart style guide syntax (like 2-space indentation) with 78 | `let g:dart_style_guide = 2` 79 | 80 | Enable DartFmt execution on buffer save with `let g:dart_format_on_save = v:true` 81 | 82 | Configure DartFmt options with `let g:dartfmt_options` 83 | (discover formatter options with `dartfmt -h`) 84 | 85 | ## FAQ 86 | 87 | ### Why doesn't the plugin indent identically to `dart format`? 88 | 89 | The indentation capabilities within vim are limited and it's not easy to fully 90 | express the indentation behavior of `dart format`. The major area where this 91 | plugin differs from `dart format` is indentation of function arguments when 92 | using a trailing comma in the argument list. When using a trailing comma (as is 93 | common in flutter widget code) `dart format` uses 2 space indent for argument 94 | parameters. In all other indentation following an open parenthesis (argument 95 | lists without a trailing comma, multi-line assert statements, etc) `dart format` 96 | uses 4 space indent. This plugin uses 4 space indent indent by default. To use 2 97 | space indent by default, `let g:dart_trailing_comma_indent = v:true`. 98 | 99 | 100 | ### How do I configure an LSP plugin to start the analysis server? 101 | 102 | The Dart SDK comes with an analysis server that can be run in LSP mode. The 103 | server ships with the SDK. Assuming the `bin` directory of the SDK is at 104 | `$DART_SDK` the full command to run the analysis server in LSP mode is 105 | `$DART_SDK/dart $DART_SDK/snapshots/analysis_server.dart.snapshot --lsp`. If 106 | you'll be opening files outside of the `rootUri` sent by your LSP client 107 | (usually `cwd`) you may want to pass `onlyAnalyzeProjectsWithOpenFiles: true` in 108 | the `initializationOptions`. See the documentation for your LSP client for how 109 | to configure initialization options. If you are using the [vim-lsc][] plugin 110 | there is an additional plugin which can configure everything for you at 111 | [vim-lsc-dart][]. A minimal config for a good default experience using 112 | [vim-plug][] would look like: 113 | 114 | ```vimscript 115 | call plug#begin() 116 | Plug 'dart-lang/dart-vim-plugin' 117 | Plug 'natebosch/vim-lsc' 118 | Plug 'natebosch/vim-lsc-dart' 119 | call plug#end() 120 | 121 | let g:lsc_auto_map = v:true 122 | ``` 123 | 124 | [vim-lsc-dart]: https://github.com/natebosch/vim-lsc-dart 125 | -------------------------------------------------------------------------------- /autoload/dart.vim: -------------------------------------------------------------------------------- 1 | 2 | function! s:error(text) abort 3 | echohl Error 4 | echomsg printf('[dart-vim-plugin] %s', a:text) 5 | echohl None 6 | endfunction 7 | 8 | function! s:cexpr(errorformat, lines, reason) abort 9 | call setqflist([], ' ', { 10 | \ 'lines': a:lines, 11 | \ 'efm': a:errorformat, 12 | \ 'context': {'reason': a:reason}, 13 | \}) 14 | copen 15 | endfunction 16 | 17 | " If the quickfix list has a context matching [reason], clear and close it. 18 | function! s:clearQfList(reason) abort 19 | let context = get(getqflist({'context': 1}), 'context', {}) 20 | if type(context) == v:t_dict && 21 | \ has_key(context, 'reason') && 22 | \ context.reason == a:reason 23 | call setqflist([], 'r') 24 | cclose 25 | endif 26 | endfunction 27 | 28 | function! dart#fmt(...) abort 29 | let l:dartfmt = s:FindDartFmt() 30 | if empty(l:dartfmt) | return | endif 31 | let buffer_content = getline(1, '$') 32 | let l:cmd = extend(l:dartfmt, ['--stdin-name', shellescape(expand('%'))]) 33 | if exists('g:dartfmt_options') 34 | call extend(l:cmd, g:dartfmt_options) 35 | endif 36 | call extend(l:cmd, a:000) 37 | let lines = systemlist(join(l:cmd), join(buffer_content, "\n")) 38 | " TODO(https://github.com/dart-lang/sdk/issues/38507) - Remove once the 39 | " tool no longer emits this line on SDK upgrades. 40 | if lines[-1] ==# 'Isolate creation failed' 41 | let lines = lines[:-2] 42 | endif 43 | if buffer_content == lines 44 | call s:clearQfList('dartfmt') 45 | return 46 | endif 47 | if 0 == v:shell_error 48 | let win_view = winsaveview() 49 | silent keepjumps call setline(1, lines) 50 | if line('$') > len(lines) 51 | silent keepjumps execute string(len(lines)+1).',$ delete' 52 | endif 53 | call winrestview(win_view) 54 | call s:clearQfList('dartfmt') 55 | else 56 | let errors = lines[2:] 57 | let error_format = '%Aline %l\, column %c of %f: %m,%C%.%#' 58 | call s:cexpr(error_format, errors, 'dartfmt') 59 | endif 60 | endfunction 61 | 62 | function! s:FindDartFmt() abort 63 | if executable('dart') 64 | let l:version_text = system('dart --version') 65 | let l:match = matchlist(l:version_text, 66 | \ '\vDart SDK version: (\d+)\.(\d+)\.\d+.*') 67 | if empty(l:match) 68 | call s:error('Unable to determine dart version') 69 | return [] 70 | endif 71 | let l:major = l:match[1] 72 | let l:minor = l:match[2] 73 | if l:major > 2 || l:major == 2 && l:minor >= 14 74 | return ['dart', 'format'] 75 | endif 76 | endif 77 | " Legacy fallback for Dart SDK pre 2.14 78 | if executable('dartfmt') | return ['dartfmt'] | endif 79 | if executable('flutter') 80 | let l:flutter_cmd = resolve(exepath('flutter')) 81 | let l:bin = fnamemodify(l:flutter_cmd, ':h') 82 | let l:dartfmt = l:bin.'/cache/dart-sdk/bin/dartfmt' 83 | if executable(l:dartfmt) | return [l:dartfmt] | endif 84 | endif 85 | call s:error('Cannot find a `dartfmt` command') 86 | return [] 87 | endfunction 88 | 89 | " Finds the path to `uri`. 90 | " 91 | " If the file is a package: uri, looks for a package_config.json or .packages 92 | " file to resolve the path. If the path cannot be resolved, or is not a 93 | " package: uri, returns the original. 94 | function! dart#resolveUri(uri) abort 95 | if a:uri !~# 'package:' 96 | return a:uri 97 | endif 98 | let package_name = substitute(a:uri, 'package:\(\w\+\)\/.*', '\1', '') 99 | let [found, package_map] = s:PackageMap() 100 | if !found 101 | call s:error('cannot find .packages or package_config.json file') 102 | return a:uri 103 | endif 104 | if !has_key(package_map, package_name) 105 | call s:error('no package mapping for '.package_name) 106 | return a:uri 107 | endif 108 | let package_lib = package_map[package_name] 109 | return substitute(a:uri, 110 | \ 'package:'.package_name, 111 | \ escape(package_map[package_name], '\'), 112 | \ '') 113 | endfunction 114 | 115 | " A map from package name to lib directory parse from a 'package_config.json' 116 | " or '.packages' file. 117 | " 118 | " Returns [found, package_map] 119 | function! s:PackageMap() abort 120 | let [found, package_config] = s:FindFile('.dart_tool/package_config.json') 121 | if found 122 | let dart_tool_dir = fnamemodify(package_config, ':p:h') 123 | let content = join(readfile(package_config), "\n") 124 | let packages_dict = json_decode(content) 125 | if packages_dict['configVersion'] != '2' 126 | s:error('Unsupported version of package_config.json') 127 | return [v:false, {}] 128 | endif 129 | let map = {} 130 | for package in packages_dict['packages'] 131 | let name = package['name'] 132 | let uri = package['rootUri'] 133 | let package_uri = package['packageUri'] 134 | if uri =~# 'file:/' 135 | let uri = substitute(uri, 'file://', '', '') 136 | let lib_dir = resolve(uri.'/'.package_uri) 137 | else 138 | let lib_dir = resolve(dart_tool_dir.'/'.uri.'/'.package_uri) 139 | endif 140 | let map[name] = lib_dir 141 | endfor 142 | return [v:true, map] 143 | endif 144 | 145 | let [found, dot_packages] = s:FindFile('.packages') 146 | if found 147 | let dot_packages_dir = fnamemodify(dot_packages, ':p:h') 148 | let lines = readfile(dot_packages) 149 | let map = {} 150 | for line in lines 151 | if line =~# '\s*#' 152 | continue 153 | endif 154 | let package = substitute(line, ':.*$', '', '') 155 | let lib_dir = substitute(line, '^[^:]*:', '', '') 156 | if lib_dir =~# 'file:/' 157 | let lib_dir = substitute(lib_dir, 'file://', '', '') 158 | if lib_dir =~# '/[A-Z]:/' 159 | let lib_dir = lib_dir[1:] 160 | endif 161 | else 162 | let lib_dir = resolve(dot_packages_dir.'/'.lib_dir) 163 | endif 164 | if lib_dir =~# '/$' 165 | let lib_dir = lib_dir[:len(lib_dir) - 2] 166 | endif 167 | let map[package] = lib_dir 168 | endfor 169 | return [v:true, map] 170 | endif 171 | return [v:false, {}] 172 | endfunction 173 | 174 | " Toggle whether dartfmt is run on save or not. 175 | function! dart#ToggleFormatOnSave() abort 176 | if get(g:, 'dart_format_on_save', 0) 177 | let g:dart_format_on_save = 0 178 | return 179 | endif 180 | let g:dart_format_on_save = 1 181 | endfunction 182 | 183 | " Finds a file named [a:path] in the cwd, or in any directory above the open 184 | " file. 185 | " 186 | " Returns [found, file] 187 | function! s:FindFile(path) abort 188 | if filereadable(a:path) 189 | return [v:true, a:path] 190 | endif 191 | let dir_path = expand('%:p:h') 192 | while v:true 193 | let file_path = dir_path.'/'.a:path 194 | if filereadable(file_path) 195 | return [v:true, file_path] 196 | endif 197 | let parent = fnamemodify(dir_path, ':h') 198 | if dir_path == parent 199 | break 200 | endif 201 | let dir_path = parent 202 | endwhile 203 | return [v:false, ''] 204 | endfunction 205 | 206 | " Prevent writes to files in the pub cache. 207 | function! dart#setModifiable() abort 208 | let full_path = expand('%:p') 209 | if full_path =~# '.pub-cache' || 210 | \ full_path =~# 'Pub\Cache' 211 | setlocal nomodifiable 212 | endif 213 | endfunction 214 | -------------------------------------------------------------------------------- /doc/dart.txt: -------------------------------------------------------------------------------- 1 | *dart-vim-plugin* Dart support for Vim 2 | 3 | INTRODUCTION *dart.vim* 4 | 5 | dart-vim-plugin provides filetype detection, syntax highlighting, and 6 | indentation for Dart code in Vim. 7 | 8 | https://github.com/dart-lang/dart-vim-plugin 9 | 10 | TOOLS *dart-tools* 11 | 12 | An `includeexpr` is set that can read `.packages` files and resolve `package:` 13 | uris to a file. See |gf| for an example use. 14 | 15 | COMMANDS *dart-commands* 16 | 17 | These commands are available in buffers with the dart filetype. 18 | 19 | *:DartFmt* 20 | Runs `dart format` and passes the current buffer content through stdin. If the 21 | format is successful replaces the current buffer content with the formatted 22 | result. If the format is unsuccessful errors are shown in the quickfix window. 23 | This command does not use the file content on disk so it is safe to run with 24 | unwritten changes. 25 | Options may be passed to `dart format` by setting |g:dartfmt_options| or passing 26 | arguments to the `:DartFmt` command. 27 | 28 | *:DartToggleFormatOnSave* 29 | 30 | Toggles the |g:dart_format_on_save| configuration to enable or disable automatic 31 | formatting of Dart buffers when they are written. 32 | 33 | CONFIGURATION *dart-configure* 34 | 35 | *g:dart_html_in_string* 36 | Set to `v:true` to highlights HTML syntax inside Strings within Dart files. 37 | Default `v:false` 38 | 39 | *g:dart_corelib_highlight* 40 | Set to `v:false` to disable highlighting of code Dart classes like `Map` or 41 | `List`. 42 | Default `v:true` 43 | 44 | *g:dart_format_on_save* 45 | Set to `v:true` to enable automatically formatting Dart buffers when they are 46 | written. 47 | 48 | *g:dart_style_guide* 49 | Set to any value (set to `2` by convention) to set tab and width behavior to 50 | match the Dart style guide - spaces only with an indent of 2. Also sets 51 | `formatoptions += t` to auto wrap text. 52 | 53 | *g:dart_trailing_comma_indent* 54 | Set to `v:true` to indent argument lists by the shiftwidth (2 spaces) instead of 55 | double that. This matches the indentation produced by `dart format` when the 56 | argument list uses a trailing comma. 57 | 58 | *g:dartfmt_options* 59 | Configure DartFmt options with `let g:dartfmt_options`, for example, enable 60 | auto syntax fixes with `let g:dartfmt_options = ['--fix']` 61 | (discover formatter options with `dart format -h`) 62 | 63 | 64 | SYNTAX HIGHLIGHTING *dart-syntax* 65 | 66 | This plugin uses narrow highlight groups to allow selectively disabling the 67 | syntax highlights. Link any of the following groups to the `Normal` highlight 68 | group to disable them: 69 | 70 | `dartSdkException`: Capitalized exception or error classes defined in the SDK. 71 | 72 | `dartCoreType`: `void`, `var`, `dynamic` 73 | 74 | `dartSdkClass`: Capitalized classes defined in the SDK, along with `bool`, 75 | `int`, `double`, and `num`. 76 | 77 | `dartUserType`: Any capitalized identifier. 78 | 79 | `dartType`: Combines `dartCoreType`, `dartSdkClass`, and `dartUserType`. 80 | 81 | `dartSdkTypedef`: SDK defined `typdef`s. 82 | 83 | `dartFunction`: Any lower cased identifier preceding an open parenthesis. 84 | 85 | For example, to remove the highlighting for type and function names: 86 | > 87 | highlight link dartType Normal 88 | highlight link dartFunction Normal 89 | < 90 | 91 | vim:tw=78:sw=4:ts=8:ft=help:norl: 92 | -------------------------------------------------------------------------------- /ftdetect/dart.vim: -------------------------------------------------------------------------------- 1 | augroup dart-vim-plugin-ftdetec 2 | autocmd! 3 | autocmd BufRead,BufNewFile *.dart set filetype=dart 4 | autocmd BufRead * call s:DetectShebang() 5 | augroup END 6 | 7 | function! s:DetectShebang() 8 | if did_filetype() | return | endif 9 | if getline(1) ==# '#!/usr/bin/env dart' 10 | setlocal filetype=dart 11 | endif 12 | endfunction 13 | -------------------------------------------------------------------------------- /ftplugin/dart.vim: -------------------------------------------------------------------------------- 1 | if exists('b:did_ftplugin') 2 | finish 3 | endif 4 | let b:did_ftplugin = 1 5 | 6 | " Enable automatic indentation (2 spaces) if variable g:dart_style_guide is set 7 | if exists('g:dart_style_guide') 8 | setlocal expandtab 9 | setlocal shiftwidth=2 10 | setlocal softtabstop=2 11 | 12 | setlocal formatoptions-=t 13 | endif 14 | 15 | " Set 'comments' to format dashed lists in comments. 16 | setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,:// 17 | 18 | setlocal commentstring=//%s 19 | let s:win_sep = (has('win32') || has('win64')) ? '/' : '' 20 | let &l:errorformat = 21 | \ join([ 22 | \ ' %#''file://' . s:win_sep . '%f'': %s: line %l pos %c:%m', 23 | \ '%m' 24 | \ ], ',') 25 | 26 | setlocal includeexpr=dart#resolveUri(v:fname) 27 | setlocal isfname+=: 28 | setlocal iskeyword+=$ 29 | 30 | let b:undo_ftplugin = 'setl et< fo< sw< sts< com< cms< inex< isf<' 31 | -------------------------------------------------------------------------------- /indent/dart.vim: -------------------------------------------------------------------------------- 1 | if exists('b:did_indent') 2 | finish 3 | endif 4 | let b:did_indent = 1 5 | 6 | setlocal cindent 7 | setlocal cinoptions+=j1,J1,U1,m1,+2s 8 | if get(g:, 'dart_trailing_comma_indent', v:false) 9 | setlocal cinoptions+=(2s,u2s 10 | else 11 | setlocal cinoptions+=(s,us 12 | endif 13 | 14 | setlocal indentexpr=DartIndent() 15 | 16 | let b:undo_indent = 'setl cin< cino<' 17 | 18 | if exists('*DartIndent') 19 | finish 20 | endif 21 | 22 | function! DartIndent() 23 | " Default to cindent in most cases 24 | let indentTo = cindent(v:lnum) 25 | 26 | let previousLine = getline(prevnonblank(v:lnum - 1)) 27 | let currentLine = getline(v:lnum) 28 | 29 | " Don't indent after an annotation 30 | if previousLine =~# '^\s*@.*$' 31 | let indentTo = indent(v:lnum - 1) 32 | endif 33 | 34 | " Indent after opening List literal 35 | if previousLine =~# '\[$' && !(currentLine =~# '^\s*\]') 36 | let indentTo = indent(v:lnum - 1) + &shiftwidth 37 | endif 38 | 39 | return indentTo 40 | endfunction 41 | -------------------------------------------------------------------------------- /plugin/dart.vim: -------------------------------------------------------------------------------- 1 | 2 | if exists('g:loaded_dart') 3 | finish 4 | endif 5 | let g:loaded_dart = 1 6 | 7 | let s:save_cpo = &cpo 8 | set cpo&vim 9 | 10 | function! s:FormatOnSave() 11 | " Dart code formatting on save 12 | if get(g:, 'dart_format_on_save', 0) 13 | call dart#fmt() 14 | endif 15 | endfunction 16 | 17 | augroup dart-vim-plugin 18 | autocmd! 19 | autocmd BufWritePre *.dart call s:FormatOnSave() 20 | autocmd FileType dart command! -buffer -nargs=? DartFmt call dart#fmt() 21 | autocmd FileType dart command! -buffer DartToggleFormatOnSave call dart#ToggleFormatOnSave() 22 | autocmd Filetype dart call dart#setModifiable() 23 | augroup END 24 | 25 | let &cpo = s:save_cpo 26 | -------------------------------------------------------------------------------- /syntax/dart.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file " Language: Dart 2 | " Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 3 | " for details. All rights reserved. Use of this source code is governed by a 4 | " BSD-style license that can be found in the LICENSE file. 5 | 6 | if !exists('g:main_syntax') 7 | if v:version < 600 8 | syntax clear 9 | elseif exists('b:current_syntax') 10 | finish 11 | endif 12 | let g:main_syntax = 'dart' 13 | syntax region dartFold start='{' end='}' transparent fold 14 | endif 15 | 16 | " Ensure long multiline strings are highlighted. 17 | syntax sync fromstart 18 | 19 | syntax case match 20 | 21 | " keyword definitions 22 | syntax keyword dartConditional if else switch when 23 | syntax keyword dartRepeat do while for 24 | syntax keyword dartBoolean true false 25 | syntax keyword dartConstant null 26 | syntax keyword dartTypedef this super class typedef enum mixin extension 27 | syntax keyword dartOperator new is as in 28 | syntax match dartOperator "+=\=\|-=\=\|*=\=\|/=\=\|%=\=\|\~/=\=\|<<=\=\|>>=\=\|[<>]=\=\|===\=\|\!==\=\|&=\=\|\^=\=\||=\=\|||\|&&\|\[\]=\=\|=>\|!\|\~\|?\|:" 29 | syntax keyword dartCoreType void var dynamic 30 | syntax keyword dartStatement return 31 | syntax keyword dartStorageClass static abstract final const factory late base 32 | \ interface sealed macro 33 | syntax keyword dartExceptions throw rethrow try on catch finally 34 | syntax keyword dartAssert assert 35 | syntax keyword dartClassDecl extends with implements 36 | syntax keyword dartBranch break continue nextgroup=dartUserLabelRef skipwhite 37 | syntax keyword dartKeyword get set operator call external async await 38 | \ yield sync native covariant required 39 | syntax match dartUserLabelRef "\k\+" contained 40 | 41 | syntax region dartLabelRegion transparent matchgroup=dartLabel start="\" matchgroup=NONE end=":" 42 | syntax keyword dartLabel default 43 | 44 | syntax match dartLibrary "^\(import\|export\)\>" nextgroup=dartUri skipwhite skipnl 45 | syntax region dartUri contained start=+r\=\z(["']\)+ end=+\z1+ nextgroup=dartCombinators skipwhite skipnl 46 | syntax region dartCombinators contained start="" end=";" contains=dartCombinator,dartComment,dartLineComment 47 | syntax keyword dartCombinator contained show hide deferred as 48 | syntax match dartLibrary "^\(library\|part of\|part\)\>" 49 | 50 | syntax match dartMetadata "@\([_$a-zA-Z][_$a-zA-Z0-9]*\.\)*[_$a-zA-Z][_$a-zA-Z0-9]*\>" 51 | 52 | " Numbers 53 | syntax match dartNumber "\<0[xX]\x\+\>\|\<\d\+\(\.\d\+\)\=\([eE][+-]\=\d\+\)\=\>" 54 | 55 | " User Types 56 | syntax match dartUserType "\<[_$]*\u[a-zA-Z0-9_$]*\>" 57 | 58 | " Function highlighting 59 | syntax match dartFunction "\zs\<\([_$]*[a-z][a-zA-Z0-9_$]*\)\ze\(<\|(\|\s\+=>\)" 60 | 61 | " SDK libraries 62 | syntax keyword dartSdkClass BidirectionalIterator Comparable DateTime 63 | \ Duration Expando Function Invocation Iterable Iterator List Map Match 64 | \ Object Pattern RegExp RuneIterator Runes Set StackTrace Stopwatch String 65 | \ StringBuffer StringSink Symbol Type bool int double num 66 | syntax keyword dartSdkTypedef Comparator 67 | syntax keyword dartSdkException AbstractClassInstantiationError 68 | \ ArgumentError AssertionError CastError ConcurrentModificationError 69 | \ Error Exception FallThroughError FormatException 70 | \ IntegerDivisionByZeroException NoSuchMethodError NullThrownError 71 | \ OutOfMemoryError RangeError RuntimeError StackOverflowError StateError 72 | \ TypeError UnimplementedError UnsupportedError 73 | 74 | " Comments 75 | syntax keyword dartTodo contained TODO FIXME XXX 76 | syntax region dartComment start="/\*" end="\*/" contains=dartComment,dartTodo,dartDocLink,@Spell 77 | syntax match dartLineComment "//.*" contains=dartTodo,@Spell 78 | syntax match dartLineDocComment "///.*" contains=dartTodo,dartDocLink,@Spell 79 | syntax match dartShebangLine /^\%1l#!.*/ 80 | syntax region dartDocLink oneline contained start=+\[+ end=+\]+ 81 | 82 | " Strings 83 | syntax cluster dartRawStringContains contains=@Spell 84 | if exists('dart_html_in_strings') && dart_html_in_strings 85 | syntax include @HTML syntax/html.vim 86 | syntax cluster dartRawStringContains add=@HTML 87 | endif 88 | syntax cluster dartStringContains contains=@dartRawStringContains,dartInterpolation,dartSpecialChar 89 | syntax region dartString oneline start=+\z(["']\)+ end=+\z1+ contains=@dartStringContains keepend 90 | syntax region dartRawString oneline start=+r\z(["']\)+ end=+\z1+ contains=@dartRawStringContains keepend 91 | syntax region dartMultilineString start=+\z("\{3\}\|'\{3\}\)+ end=+\z1+ contains=@dartStringContains keepend 92 | syntax region dartRawMultilineString start=+r\z("\{3\}\|'\{3\}\)+ end=+\z1+ contains=@dartSRawtringContains keepend 93 | syntax match dartInterpolation contained "\$\(\w\+\|{[^}]\+}\)" extend 94 | syntax match dartSpecialChar contained "\\\(u\x\{4\}\|u{\x\+}\|x\x\x\|x{\x\+}\|.\)" extend 95 | 96 | " The default highlighting. 97 | highlight default link dartBranch Conditional 98 | highlight default link dartUserLabelRef dartUserLabel 99 | highlight default link dartLabel Label 100 | highlight default link dartUserLabel Label 101 | highlight default link dartConditional Conditional 102 | highlight default link dartRepeat Repeat 103 | highlight default link dartExceptions Exception 104 | highlight default link dartAssert Statement 105 | highlight default link dartStorageClass StorageClass 106 | highlight default link dartClassDecl dartStorageClass 107 | highlight default link dartBoolean Boolean 108 | highlight default link dartString String 109 | highlight default link dartRawString String 110 | highlight default link dartMultilineString String 111 | highlight default link dartRawMultilineString String 112 | highlight default link dartNumber Number 113 | highlight default link dartStatement Statement 114 | highlight default link dartOperator Operator 115 | highlight default link dartComment Comment 116 | highlight default link dartLineComment Comment 117 | highlight default link dartLineDocComment Comment 118 | highlight default link dartShebangLine Comment 119 | highlight default link dartConstant Constant 120 | highlight default link dartTodo Todo 121 | highlight default link dartKeyword Keyword 122 | highlight default link dartInterpolation PreProc 123 | highlight default link dartDocLink SpecialComment 124 | highlight default link dartSpecialChar SpecialChar 125 | highlight default link dartLibrary Include 126 | highlight default link dartUri String 127 | highlight default link dartCombinator Keyword 128 | highlight default link dartMetadata PreProc 129 | highlight default link dartSdkTypedef Typedef 130 | highlight default link dartTypedef Typedef 131 | highlight default link dartSdkException Exception 132 | highlight default link dartSdkClass dartType 133 | highlight default link dartCoreType dartType 134 | highlight default link dartUserType dartType 135 | highlight default link dartType Type 136 | highlight default link dartFunction Function 137 | 138 | let b:current_syntax = 'dart' 139 | let b:spell_options = 'contained' 140 | 141 | if g:main_syntax is# 'dart' 142 | unlet g:main_syntax 143 | endif 144 | --------------------------------------------------------------------------------