From 6e162000a8eebf3f9e4d5c03f7f487753d81004d Mon Sep 17 00:00:00 2001 From: jortiz Date: Thu, 26 May 2016 11:26:32 -0400 Subject: [PATCH] added vim-elixir plugin --- README.md | 1 + sources_non_forked/ctrlp.vim/doc/tags-cn | 110 ++++++++++ sources_non_forked/vim-elixir/.travis.yml | 8 + sources_non_forked/vim-elixir/Gemfile | 4 + sources_non_forked/vim-elixir/Gemfile.lock | 20 ++ sources_non_forked/vim-elixir/LICENSE | 13 ++ sources_non_forked/vim-elixir/README.md | 62 ++++++ .../vim-elixir/compiler/exunit.vim | 25 +++ .../vim-elixir/ftdetect/elixir.vim | 15 ++ .../vim-elixir/ftplugin/eelixir.vim | 87 ++++++++ .../vim-elixir/ftplugin/elixir.vim | 57 ++++++ .../vim-elixir/indent/eelixir.vim | 67 +++++++ .../vim-elixir/indent/elixir.vim | 141 +++++++++++++ .../spec/indent/anonymous_functions_spec.rb | 73 +++++++ .../vim-elixir/spec/indent/blocks_spec.rb | 60 ++++++ .../vim-elixir/spec/indent/case_spec.rb | 15 ++ .../vim-elixir/spec/indent/cond_spec.rb | 13 ++ .../spec/indent/documentation_spec.rb | 16 ++ .../spec/indent/embedded_elixir_spec.rb | 29 +++ .../vim-elixir/spec/indent/if_spec.rb | 23 +++ .../vim-elixir/spec/indent/lists_spec.rb | 131 ++++++++++++ .../vim-elixir/spec/indent/pipeline_spec.rb | 71 +++++++ .../vim-elixir/spec/indent/tuples_spec.rb | 26 +++ .../vim-elixir/spec/spec_helper.rb | 115 +++++++++++ .../vim-elixir/spec/syntax/alias_spec.rb | 24 +++ .../spec/syntax/default_argument_spec.rb | 15 ++ .../spec/syntax/embedded_elixir_spec.rb | 26 +++ .../vim-elixir/spec/syntax/guard_spec.rb | 29 +++ .../vim-elixir/spec/syntax/heredoc_spec.rb | 70 +++++++ .../vim-elixir/spec/syntax/list_spec.rb | 12 ++ .../vim-elixir/spec/syntax/records_spec.rb | 11 + .../vim-elixir/spec/syntax/sigil_spec.rb | 104 ++++++++++ .../vim-elixir/spec/syntax/struct_spec.rb | 17 ++ .../vim-elixir/spec/syntax/variable_spec.rb | 12 ++ .../vim-elixir/syntax/eelixir.vim | 61 ++++++ .../vim-elixir/syntax/elixir.vim | 188 ++++++++++++++++++ 36 files changed, 1751 insertions(+) create mode 100644 sources_non_forked/ctrlp.vim/doc/tags-cn create mode 100644 sources_non_forked/vim-elixir/.travis.yml create mode 100644 sources_non_forked/vim-elixir/Gemfile create mode 100644 sources_non_forked/vim-elixir/Gemfile.lock create mode 100644 sources_non_forked/vim-elixir/LICENSE create mode 100644 sources_non_forked/vim-elixir/README.md create mode 100644 sources_non_forked/vim-elixir/compiler/exunit.vim create mode 100644 sources_non_forked/vim-elixir/ftdetect/elixir.vim create mode 100644 sources_non_forked/vim-elixir/ftplugin/eelixir.vim create mode 100644 sources_non_forked/vim-elixir/ftplugin/elixir.vim create mode 100644 sources_non_forked/vim-elixir/indent/eelixir.vim create mode 100644 sources_non_forked/vim-elixir/indent/elixir.vim create mode 100644 sources_non_forked/vim-elixir/spec/indent/anonymous_functions_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/blocks_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/case_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/cond_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/documentation_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/embedded_elixir_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/if_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/lists_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/pipeline_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/indent/tuples_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/spec_helper.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/alias_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/default_argument_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/embedded_elixir_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/guard_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/heredoc_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/list_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/records_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/sigil_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/struct_spec.rb create mode 100644 sources_non_forked/vim-elixir/spec/syntax/variable_spec.rb create mode 100644 sources_non_forked/vim-elixir/syntax/eelixir.vim create mode 100644 sources_non_forked/vim-elixir/syntax/elixir.vim diff --git a/README.md b/README.md index ab559418..93fbb80d 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ Remove all clutter and focus only on the essential. Similar to iA Writer or Writ * [vim-markdown](https://github.com/tpope/vim-markdown) * [nginx.vim](https://github.com/vim-scripts/nginx.vim): Highlights configuration files for nginx * [vim-go](https://github.com/fatih/vim-go) +* [vim-elixir]("https://github.com/elixir-lang/vim-elixir") ## How to include your own stuff? diff --git a/sources_non_forked/ctrlp.vim/doc/tags-cn b/sources_non_forked/ctrlp.vim/doc/tags-cn new file mode 100644 index 00000000..4ec0e5f9 --- /dev/null +++ b/sources_non_forked/ctrlp.vim/doc/tags-cn @@ -0,0 +1,110 @@ +!_TAG_FILE_ENCODING utf-8 // +'ctrl-p' ctrlp.cnx /*'ctrl-p'* +'ctrlp' ctrlp.cnx /*'ctrlp'* +'ctrlp-' ctrlp.cnx /*'ctrlp-'* +'ctrlp-autocompletion' ctrlp.cnx /*'ctrlp-autocompletion'* +'ctrlp-fullregexp' ctrlp.cnx /*'ctrlp-fullregexp'* +'ctrlp-pasting' ctrlp.cnx /*'ctrlp-pasting'* +'ctrlp-wildignore' ctrlp.cnx /*'ctrlp-wildignore'* +'g:ctrlp_abbrev' ctrlp.cnx /*'g:ctrlp_abbrev'* +'g:ctrlp_arg_map' ctrlp.cnx /*'g:ctrlp_arg_map'* +'g:ctrlp_brief_prompt' ctrlp.cnx /*'g:ctrlp_brief_prompt'* +'g:ctrlp_buffer_func' ctrlp.cnx /*'g:ctrlp_buffer_func'* +'g:ctrlp_bufname_mod' ctrlp.cnx /*'g:ctrlp_bufname_mod'* +'g:ctrlp_bufpath_mod' ctrlp.cnx /*'g:ctrlp_bufpath_mod'* +'g:ctrlp_buftag_ctags_bin' ctrlp.cnx /*'g:ctrlp_buftag_ctags_bin'* +'g:ctrlp_buftag_systemenc' ctrlp.cnx /*'g:ctrlp_buftag_systemenc'* +'g:ctrlp_buftag_types' ctrlp.cnx /*'g:ctrlp_buftag_types'* +'g:ctrlp_by_filename' ctrlp.cnx /*'g:ctrlp_by_filename'* +'g:ctrlp_cache_dir' ctrlp.cnx /*'g:ctrlp_cache_dir'* +'g:ctrlp_clear_cache_on_exit' ctrlp.cnx /*'g:ctrlp_clear_cache_on_exit'* +'g:ctrlp_cmd' ctrlp.cnx /*'g:ctrlp_cmd'* +'g:ctrlp_custom_ignore' ctrlp.cnx /*'g:ctrlp_custom_ignore'* +'g:ctrlp_default_input' ctrlp.cnx /*'g:ctrlp_default_input'* +'g:ctrlp_follow_symlinks' ctrlp.cnx /*'g:ctrlp_follow_symlinks'* +'g:ctrlp_key_loop' ctrlp.cnx /*'g:ctrlp_key_loop'* +'g:ctrlp_lazy_update' ctrlp.cnx /*'g:ctrlp_lazy_update'* +'g:ctrlp_line_prefix' ctrlp.cnx /*'g:ctrlp_line_prefix'* +'g:ctrlp_map' ctrlp.cnx /*'g:ctrlp_map'* +'g:ctrlp_match_current_file' ctrlp.cnx /*'g:ctrlp_match_current_file'* +'g:ctrlp_match_func' ctrlp.cnx /*'g:ctrlp_match_func'* +'g:ctrlp_match_window' ctrlp.cnx /*'g:ctrlp_match_window'* +'g:ctrlp_max_depth' ctrlp.cnx /*'g:ctrlp_max_depth'* +'g:ctrlp_max_files' ctrlp.cnx /*'g:ctrlp_max_files'* +'g:ctrlp_max_history' ctrlp.cnx /*'g:ctrlp_max_history'* +'g:ctrlp_mruf_case_sensitive' ctrlp.cnx /*'g:ctrlp_mruf_case_sensitive'* +'g:ctrlp_mruf_default_order' ctrlp.cnx /*'g:ctrlp_mruf_default_order'* +'g:ctrlp_mruf_exclude' ctrlp.cnx /*'g:ctrlp_mruf_exclude'* +'g:ctrlp_mruf_include' ctrlp.cnx /*'g:ctrlp_mruf_include'* +'g:ctrlp_mruf_max' ctrlp.cnx /*'g:ctrlp_mruf_max'* +'g:ctrlp_mruf_relative' ctrlp.cnx /*'g:ctrlp_mruf_relative'* +'g:ctrlp_mruf_save_on_update' ctrlp.cnx /*'g:ctrlp_mruf_save_on_update'* +'g:ctrlp_open_func' ctrlp.cnx /*'g:ctrlp_open_func'* +'g:ctrlp_open_multiple_files' ctrlp.cnx /*'g:ctrlp_open_multiple_files'* +'g:ctrlp_open_new_file' ctrlp.cnx /*'g:ctrlp_open_new_file'* +'g:ctrlp_open_single_match' ctrlp.cnx /*'g:ctrlp_open_single_match'* +'g:ctrlp_prompt_mappings' ctrlp.cnx /*'g:ctrlp_prompt_mappings'* +'g:ctrlp_regexp' ctrlp.cnx /*'g:ctrlp_regexp'* +'g:ctrlp_reuse_window' ctrlp.cnx /*'g:ctrlp_reuse_window'* +'g:ctrlp_root_markers' ctrlp.cnx /*'g:ctrlp_root_markers'* +'g:ctrlp_show_hidden' ctrlp.cnx /*'g:ctrlp_show_hidden'* +'g:ctrlp_status_func' ctrlp.cnx /*'g:ctrlp_status_func'* +'g:ctrlp_switch_buffer' ctrlp.cnx /*'g:ctrlp_switch_buffer'* +'g:ctrlp_tabpage_position' ctrlp.cnx /*'g:ctrlp_tabpage_position'* +'g:ctrlp_tilde_homedir' ctrlp.cnx /*'g:ctrlp_tilde_homedir'* +'g:ctrlp_use_caching' ctrlp.cnx /*'g:ctrlp_use_caching'* +'g:ctrlp_user_command' ctrlp.cnx /*'g:ctrlp_user_command'* +'g:ctrlp_working_path_mode' ctrlp.cnx /*'g:ctrlp_working_path_mode'* +'g:loaded_ctrlp' ctrlp.cnx /*'g:loaded_ctrlp'* +:CtrlP ctrlp.cnx /*:CtrlP* +:CtrlPBookmarkDir ctrlp.cnx /*:CtrlPBookmarkDir* +:CtrlPBookmarkDirAdd ctrlp.cnx /*:CtrlPBookmarkDirAdd* +:CtrlPBufTag ctrlp.cnx /*:CtrlPBufTag* +:CtrlPBufTagAll ctrlp.cnx /*:CtrlPBufTagAll* +:CtrlPBuffer ctrlp.cnx /*:CtrlPBuffer* +:CtrlPChange ctrlp.cnx /*:CtrlPChange* +:CtrlPChangeAll ctrlp.cnx /*:CtrlPChangeAll* +:CtrlPClearAllCaches ctrlp.cnx /*:CtrlPClearAllCaches* +:CtrlPClearCache ctrlp.cnx /*:CtrlPClearCache* +:CtrlPDir ctrlp.cnx /*:CtrlPDir* +:CtrlPLastMode ctrlp.cnx /*:CtrlPLastMode* +:CtrlPLine ctrlp.cnx /*:CtrlPLine* +:CtrlPMRU ctrlp.cnx /*:CtrlPMRU* +:CtrlPMixed ctrlp.cnx /*:CtrlPMixed* +:CtrlPQuickfix ctrlp.cnx /*:CtrlPQuickfix* +:CtrlPRTS ctrlp.cnx /*:CtrlPRTS* +:CtrlPRoot ctrlp.cnx /*:CtrlPRoot* +:CtrlPTag ctrlp.cnx /*:CtrlPTag* +:CtrlPUndo ctrlp.cnx /*:CtrlPUndo* +ClearAllCtrlPCaches ctrlp.cnx /*ClearAllCtrlPCaches* +ClearCtrlPCache ctrlp.cnx /*ClearCtrlPCache* +ControlP ctrlp.cnx /*ControlP* +CtrlP ctrlp.cnx /*CtrlP* +ResetCtrlP ctrlp.cnx /*ResetCtrlP* +ctrlp-autoignore-extension ctrlp.cnx /*ctrlp-autoignore-extension* +ctrlp-changelog ctrlp.cnx /*ctrlp-changelog* +ctrlp-commands ctrlp.cnx /*ctrlp-commands* +ctrlp-content ctrlp.cnx /*ctrlp-content* +ctrlp-credits ctrlp.cnx /*ctrlp-credits* +ctrlp-customization ctrlp.cnx /*ctrlp-customization* +ctrlp-default-value ctrlp.cnx /*ctrlp-default-value* +ctrlp-extensions ctrlp.cnx /*ctrlp-extensions* +ctrlp-input-formats ctrlp.cnx /*ctrlp-input-formats* +ctrlp-intro ctrlp.cnx /*ctrlp-intro* +ctrlp-mappings ctrlp.cnx /*ctrlp-mappings* +ctrlp-miscellaneous-configs ctrlp.cnx /*ctrlp-miscellaneous-configs* +ctrlp-options ctrlp.cnx /*ctrlp-options* +ctrlp.txt ctrlp.cnx /*ctrlp.txt* +g:ctrlp_dont_split ctrlp.cnx /*g:ctrlp_dont_split* +g:ctrlp_dotfiles ctrlp.cnx /*g:ctrlp_dotfiles* +g:ctrlp_highlight_match ctrlp.cnx /*g:ctrlp_highlight_match* +g:ctrlp_jump_to_buffer ctrlp.cnx /*g:ctrlp_jump_to_buffer* +g:ctrlp_live_update ctrlp.cnx /*g:ctrlp_live_update* +g:ctrlp_match_window_bottom ctrlp.cnx /*g:ctrlp_match_window_bottom* +g:ctrlp_match_window_reversed ctrlp.cnx /*g:ctrlp_match_window_reversed* +g:ctrlp_max_height ctrlp.cnx /*g:ctrlp_max_height* +g:ctrlp_mru_files ctrlp.cnx /*g:ctrlp_mru_files* +g:ctrlp_open_multi ctrlp.cnx /*g:ctrlp_open_multi* +g:ctrlp_persistent_input ctrlp.cnx /*g:ctrlp_persistent_input* +g:ctrlp_regexp_search ctrlp.cnx /*g:ctrlp_regexp_search* +string-match ctrlp.cnx /*string-match* diff --git a/sources_non_forked/vim-elixir/.travis.yml b/sources_non_forked/vim-elixir/.travis.yml new file mode 100644 index 00000000..3e67b0cf --- /dev/null +++ b/sources_non_forked/vim-elixir/.travis.yml @@ -0,0 +1,8 @@ +language: ruby +rvm: + - 1.9.3 +before_install: sudo apt-get install vim-gtk +before_script: + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" +script: "bundle exec rspec --color -f d" diff --git a/sources_non_forked/vim-elixir/Gemfile b/sources_non_forked/vim-elixir/Gemfile new file mode 100644 index 00000000..4a66996e --- /dev/null +++ b/sources_non_forked/vim-elixir/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem 'rspec' +gem 'vimrunner' diff --git a/sources_non_forked/vim-elixir/Gemfile.lock b/sources_non_forked/vim-elixir/Gemfile.lock new file mode 100644 index 00000000..d5603cc0 --- /dev/null +++ b/sources_non_forked/vim-elixir/Gemfile.lock @@ -0,0 +1,20 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.2.4) + rspec (2.13.0) + rspec-core (~> 2.13.0) + rspec-expectations (~> 2.13.0) + rspec-mocks (~> 2.13.0) + rspec-core (2.13.1) + rspec-expectations (2.13.0) + diff-lcs (>= 1.1.3, < 2.0) + rspec-mocks (2.13.1) + vimrunner (0.3.1) + +PLATFORMS + ruby + +DEPENDENCIES + rspec + vimrunner diff --git a/sources_non_forked/vim-elixir/LICENSE b/sources_non_forked/vim-elixir/LICENSE new file mode 100644 index 00000000..75cc8980 --- /dev/null +++ b/sources_non_forked/vim-elixir/LICENSE @@ -0,0 +1,13 @@ +Copyright 2012 Plataformatec + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/sources_non_forked/vim-elixir/README.md b/sources_non_forked/vim-elixir/README.md new file mode 100644 index 00000000..c47405c4 --- /dev/null +++ b/sources_non_forked/vim-elixir/README.md @@ -0,0 +1,62 @@ +# vim-elixir + +[![Build Status](https://travis-ci.org/elixir-lang/vim-elixir.svg?branch=master)](https://travis-ci.org/elixir-lang/vim-elixir) + +[Elixir](http://elixir-lang.org) support for vim. This plugin also adds support +for Elixir's templating language, EEx. + +Features included so far: + +* Syntax highlighting for Elixir and EEx +* Filetype detection for `.ex`, `.exs` and `.eex` files +* Automatic indentation + + +## Installation + +### Plugin managers + +The most common plugin managers include [vim-plug][vim-plug], +[NeoBundle][neobundle], [Vundle][vundle] and [pathogen.vim][pathogen]. + +With pathogen.vim, just clone this repository inside `~/.vim/bundle`: + +```bash +git clone https://github.com/elixir-lang/vim-elixir.git ~/.vim/bundle/vim-elixir +``` + +With the other plugin managers, just follow the instructions on the homepage of +each plugin. In general, you have to add a line to your `~/.vimrc`: + +```viml +" vim-plug +Plug 'elixir-lang/vim-elixir' +" NeoBundle +NeoBundle 'elixir-lang/vim-elixir' +" Vundle +Plugin 'elixir-lang/vim-elixir' +``` + +### Manual installation + +Copy the contents of each directory in the respective directories inside +`~/.vim`. + + +## Syntastic integration + +> :warning: **Warning:** older versions (`<= 3.4.0-106`) of +> [Syntastic][syntastic] check Elixir scripts *by executing them*. In addition +> to being unsafe, this can cause Vim to hang while saving Elixir scripts. This +> is not an error in `vim-elixir`. This issue [can be fixed in +> Syntastic][syntastic-issue-fix] by disabling Elixir checking by default. +> +> **If your version of Syntastic is below `3.4.0-107` (16 July 2014), you should +> update to a newer version.** + +[vim-plug]: https://github.com/junegunn/vim-plug +[vundle]: https://github.com/gmarik/Vundle.vim +[neobundle]: https://github.com/Shougo/neobundle.vim +[pathogen]: https://github.com/tpope/vim-pathogen +[syntastic]: https://github.com/scrooloose/syntastic +[syntastic-issue-fix]: https://github.com/scrooloose/syntastic/commit/1d19dff701524ebed90a4fbd7c7cd75ab954b79d diff --git a/sources_non_forked/vim-elixir/compiler/exunit.vim b/sources_non_forked/vim-elixir/compiler/exunit.vim new file mode 100644 index 00000000..197fb6be --- /dev/null +++ b/sources_non_forked/vim-elixir/compiler/exunit.vim @@ -0,0 +1,25 @@ +if exists("current_compiler") + finish +endif +let current_compiler = "exunit" + +if exists(":CompilerSet") != 2 " older Vim always used :setlocal + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C +CompilerSet makeprg=mix\ test +CompilerSet errorformat= + \%E\ \ %n)\ %m, + \%+G\ \ \ \ \ **\ %m, + \%+G\ \ \ \ \ stacktrace:, + \%C\ \ \ \ \ %f:%l, + \%+G\ \ \ \ \ \ \ (%\\w%\\+)\ %f:%l:\ %m, + \%+G\ \ \ \ \ \ \ %f:%l:\ %.%#, + \**\ (%\\w%\\+)\ %f:%l:\ %m + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim: nowrap sw=2 sts=2 ts=8: diff --git a/sources_non_forked/vim-elixir/ftdetect/elixir.vim b/sources_non_forked/vim-elixir/ftdetect/elixir.vim new file mode 100644 index 00000000..723a2e33 --- /dev/null +++ b/sources_non_forked/vim-elixir/ftdetect/elixir.vim @@ -0,0 +1,15 @@ +au BufRead,BufNewFile *.ex,*.exs call s:setf('elixir') +au BufRead,BufNewFile *.eex call s:setf('eelixir') +au BufRead,BufNewFile * call s:DetectElixir() + +au FileType elixir,eelixir setl sw=2 sts=2 et iskeyword+=!,? + +function! s:setf(filetype) abort + let &filetype = a:filetype +endfunction + +function! s:DetectElixir() + if getline(1) =~ '^#!.*\' + call s:setf('elixir') + endif +endfunction diff --git a/sources_non_forked/vim-elixir/ftplugin/eelixir.vim b/sources_non_forked/vim-elixir/ftplugin/eelixir.vim new file mode 100644 index 00000000..5ff6cc43 --- /dev/null +++ b/sources_non_forked/vim-elixir/ftplugin/eelixir.vim @@ -0,0 +1,87 @@ +if exists("b:did_ftplugin") + finish +endif + +let s:save_cpo = &cpo +set cpo-=C + +let s:undo_ftplugin = "" +let s:browsefilter = "All Files (*.*)\t*.*\n" +let s:match_words = "" + +if !exists("g:eelixir_default_subtype") + let g:eelixir_default_subtype = "html" +endif + +if !exists("b:eelixir_subtype") + let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$") + let b:eelixir_subtype = matchstr(s:lines,'eelixir_subtype=\zs\w\+') + if b:eelixir_subtype == '' + let b:eelixir_subtype = matchstr(&filetype,'^eex\.\zs\w\+') + endif + if b:eelixir_subtype == '' + let b:eelixir_subtype = matchstr(substitute(expand("%:t"),'\c\%(\.eex\|\.eelixir\)\+$','',''),'\.\zs\w\+$') + endif + if b:eelixir_subtype == 'ex' + let b:eelixir_subtype = 'elixir' + elseif b:eelixir_subtype == 'exs' + let b:eelixir_subtype = 'elixir' + elseif b:eelixir_subtype == 'yml' + let b:eelixir_subtype = 'yaml' + elseif b:eelixir_subtype == 'js' + let b:eelixir_subtype = 'javascript' + elseif b:eelixir_subtype == 'txt' + " Conventional; not a real file type + let b:eelixir_subtype = 'text' + elseif b:eelixir_subtype == '' + let b:eelixir_subtype = g:eelixir_default_subtype + endif +endif + +if exists("b:eelixir_subtype") && b:eelixir_subtype != '' + exe "runtime! ftplugin/".b:eelixir_subtype.".vim ftplugin/".b:eelixir_subtype."_*.vim ftplugin/".b:eelixir_subtype."/*.vim" +else + runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim +endif +unlet! b:did_ftplugin + +" Override our defaults if these were set by an included ftplugin. +if exists("b:undo_ftplugin") + let s:undo_ftplugin = b:undo_ftplugin + unlet b:undo_ftplugin +endif +if exists("b:browsefilter") + let s:browsefilter = b:browsefilter + unlet b:browsefilter +endif +if exists("b:match_words") + let s:match_words = b:match_words + unlet b:match_words +endif + +runtime! ftplugin/elixir.vim ftplugin/elixir_*.vim ftplugin/elixir/*.vim +let b:did_ftplugin = 1 + +" Combine the new set of values with those previously included. +if exists("b:undo_ftplugin") + let s:undo_ftplugin = b:undo_ftplugin . " | " . s:undo_ftplugin +endif +if exists ("b:browsefilter") + let s:browsefilter = substitute(b:browsefilter,'\cAll Files (\*\.\*)\t\*\.\*\n','','') . s:browsefilter +endif +if exists("b:match_words") + let s:match_words = b:match_words . ',' . s:match_words +endif + +" Load the combined list of match_words for matchit.vim +if exists("loaded_matchit") + let b:match_words = s:match_words +endif + +setlocal comments=:<%# +setlocal commentstring=<%#\ %s\ %> + +let b:undo_ftplugin = "setl cms< " + \ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin + +let &cpo = s:save_cpo diff --git a/sources_non_forked/vim-elixir/ftplugin/elixir.vim b/sources_non_forked/vim-elixir/ftplugin/elixir.vim new file mode 100644 index 00000000..907e6c49 --- /dev/null +++ b/sources_non_forked/vim-elixir/ftplugin/elixir.vim @@ -0,0 +1,57 @@ +if (exists("b:did_ftplugin")) + finish +endif +let b:did_ftplugin = 1 + +" Matchit support +if exists("loaded_matchit") && !exists("b:match_words") + let b:match_ignorecase = 0 + + let b:match_words = '\:\@' . + \ ':' . + \ '\<\%(else\|elsif\|catch\|after\|rescue\)\:\@!\>' . + \ ':' . + \ '\:\@' . + \ ',{:},\[:\],(:)' +endif + +setlocal comments=:# +setlocal commentstring=#\ %s + +function! GetElixirFilename(word) + let word = a:word + + " get first thing that starts uppercase, until the first space or end of line + let word = substitute(word,'^\s*\(\u[^ ]\+\).*$','\1','g') + + " remove any trailing characters that don't look like a nested module + let word = substitute(word,'\.\U.*$','','g') + + " replace module dots with slash + let word = substitute(word,'\.','/','g') + + " remove any special chars + let word = substitute(word,'[^A-z0-9-_/]','','g') + + " convert to snake_case + let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') + let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g') + let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g') + let word = substitute(word,'-','_','g') + let word = tolower(word) + + return word +endfunction + +let &l:path = + \ join([ + \ getcwd().'/lib', + \ getcwd().'/src', + \ getcwd().'/deps/**/lib', + \ getcwd().'/deps/**/src', + \ &g:path + \ ], ',') +setlocal includeexpr=GetElixirFilename(v:fname) +setlocal suffixesadd=.ex,.exs,.eex,.erl,.yrl,.hrl + +setlocal formatoptions-=t formatoptions+=croqlj diff --git a/sources_non_forked/vim-elixir/indent/eelixir.vim b/sources_non_forked/vim-elixir/indent/eelixir.vim new file mode 100644 index 00000000..1c415709 --- /dev/null +++ b/sources_non_forked/vim-elixir/indent/eelixir.vim @@ -0,0 +1,67 @@ +if exists("b:did_indent") + finish +endif + +runtime! indent/elixir.vim +unlet! b:did_indent +setlocal indentexpr= + +if exists("b:eelixir_subtype") + exe "runtime! indent/".b:eelixir_subtype.".vim" +else + runtime! indent/html.vim +endif +unlet! b:did_indent + +if &l:indentexpr == '' + if &l:cindent + let &l:indentexpr = 'cindent(v:lnum)' + else + let &l:indentexpr = 'indent(prevnonblank(v:lnum-1))' + endif +endif +let b:eelixir_subtype_indentexpr = &l:indentexpr + +let b:did_indent = 1 + +setlocal indentexpr=GetEelixirIndent() +setlocal indentkeys=o,O,*,<>>,{,},0),0],o,O,!^F,=end,=else,=elsif,=catch,=after,=rescue + +" Only define the function once. +if exists("*GetEelixirIndent") + finish +endif + +function! GetEelixirIndent(...) + if a:0 && a:1 == '.' + let v:lnum = line('.') + elseif a:0 && a:1 =~ '^\d' + let v:lnum = a:1 + endif + let vcol = col('.') + call cursor(v:lnum,1) + let inelixir = searchpair('<%','','%>','W') + call cursor(v:lnum,vcol) + if inelixir && getline(v:lnum) !~ '^<%\|^\s*%>' + let ind = GetElixirIndent() + else + exe "let ind = ".b:eelixir_subtype_indentexpr + endif + let lnum = prevnonblank(v:lnum-1) + let line = getline(lnum) + let cline = getline(v:lnum) + if cline =~# '^\s*<%\s*\%(end\|else\|elsif\|catch\|after\|rescue\)\>.*%>' + let ind = ind - &sw + elseif line =~# '\S\s*<%\s*end\s*%>' + let ind = ind - &sw + endif + if line =~# '<%[=%]\=\s*.*\' + let ind = ind + &sw + elseif line =~# '<%\s*\%(else\|elsif\|catch\|after\|rescue\)\>.*%>' + let ind = ind + &sw + endif + if cline =~# '^\s*%>\s*$' + let ind = ind - &sw + endif + return ind +endfunction diff --git a/sources_non_forked/vim-elixir/indent/elixir.vim b/sources_non_forked/vim-elixir/indent/elixir.vim new file mode 100644 index 00000000..32747990 --- /dev/null +++ b/sources_non_forked/vim-elixir/indent/elixir.vim @@ -0,0 +1,141 @@ +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent + +setlocal indentexpr=GetElixirIndent() +setlocal indentkeys+=0),0],0=end,0=else,0=match,0=elsif,0=catch,0=after,0=rescue + +if exists("*GetElixirIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +let s:no_colon_before = ':\@$' +let s:skip_syntax = '\%(Comment\|String\)$' +let s:block_skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '".s:skip_syntax."'" +let s:block_start = '\<\%(do\|fn\)\>' +let s:block_middle = 'else\|match\|elsif\|catch\|after\|rescue' +let s:block_end = 'end' +let s:starts_with_pipeline = '^\s*|>.*$' +let s:ending_with_assignment = '=\s*$' + +let s:indent_keywords = '\<'.s:no_colon_before.'\%('.s:block_start.'\|'.s:block_middle.'\)$'.'\|'.s:arrow +let s:deindent_keywords = '^\s*\<\%('.s:block_end.'\|'.s:block_middle.'\)\>'.'\|'.s:arrow + +let s:pair_start = '\<\%('.s:no_colon_before.s:block_start.'\)\>'.s:no_colon_after +let s:pair_middle = '\<\%('.s:block_middle.'\)\>'.s:no_colon_after.'\zs' +let s:pair_end = '\<\%('.s:no_colon_before.s:block_end.'\)\>\zs' + +let s:inside_block = 0 + +function! GetElixirIndent() + let lnum = prevnonblank(v:lnum - 1) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let opened_symbol = 0 + let current_line = getline(v:lnum) + let last_line = getline(lnum) + let ind = indent(lnum) + + " TODO: Remove these 2 lines + " I don't know why, but for the test on spec/indent/lists_spec.rb:24. + " Vim is making some mess on parsing the syntax of 'end', it is being + " recognized as 'elixirString' when should be recognized as 'elixirBlock'. + " This forces vim to sync the syntax. + call synID(v:lnum, 1, 1) + syntax sync fromstart + + if synIDattr(synID(v:lnum, 1, 1), "name") !~ s:skip_syntax + + if last_line !~ s:arrow + let split_line = split(last_line, '\zs') + let opened_symbol += count(split_line, '(') - count(split_line, ')') + let opened_symbol += count(split_line, '[') - count(split_line, ']') + let opened_symbol += count(split_line, '{') - count(split_line, '}') + end + + " if start symbol is followed by a character, indent based on the + " whitespace after the symbol, otherwise use the default shiftwidth + if last_line =~ '\('.s:symbols_start.'\).' + let opened_prefix = matchlist(last_line, '\('.s:symbols_start.'\)\s*')[0] + let ind += (opened_symbol * strlen(opened_prefix)) + else + let ind += (opened_symbol * &sw) + endif + + if last_line =~ '^\s*\('.s:symbols_end.'\)' || last_line =~ s:indent_keywords + let ind += &sw + endif + + if current_line =~ '^\s*\('.s:symbols_end.'\)' + let ind -= &sw + endif + + if last_line =~ s:ending_with_assignment && opened_symbol == 0 + let b:old_ind = indent(lnum) + let ind += &sw + end + + " if line starts with pipeline + " and last line ends with a pipeline, + " align them + if last_line =~ '|>.*$' && + \ current_line =~ s:starts_with_pipeline + let ind = float2nr(match(last_line, '|>') / &sw) * &sw + + " if line starts with pipeline + " and last line is an attribution + " indents pipeline in same level as attribution + elseif current_line =~ s:starts_with_pipeline && + \ last_line =~ '^[^=]\+=.\+$' + + if !exists('b:old_ind') || b:old_ind == 0 + let b:old_ind = indent(lnum) + end + let ind = float2nr(matchend(last_line, '=\s*[^ ]') / &sw) * &sw + endif + + " if last line starts with pipeline + " and current line doesn't start with pipeline + " returns the indentation before the pipeline + if last_line =~ s:starts_with_pipeline && + \ current_line !~ s:starts_with_pipeline + let ind = b:old_ind + endif + + if current_line =~ s:deindent_keywords + let bslnum = searchpair( + \ s:pair_start, + \ s:pair_middle, + \ s:pair_end, + \ 'nbW', + \ s:block_skip + \ ) + + let ind = indent(bslnum) + endif + + " indent case statements '->' + if current_line =~ s:arrow + let ind += &sw + endif + endif + + return ind +endfunction + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/sources_non_forked/vim-elixir/spec/indent/anonymous_functions_spec.rb b/sources_non_forked/vim-elixir/spec/indent/anonymous_functions_spec.rb new file mode 100644 index 00000000..3ca558b9 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/anonymous_functions_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe "Indenting" do + context "single body functions inside do block" do + it "is declared with fn syntax" do + <<-EOF + def do + some_func = fn x -> x end + end + EOF + .should be_elixir_indentation + end + + it "is declared with function syntax" do + <<-EOF + def do + some_func = function do x -> x end + end + EOF + .should be_elixir_indentation + end + + it "spans in multiple lines" do + <<-EOF + def test do + assert_raise Queue.Empty, fn -> + Q.new |> Q.deq! + end + end + EOF + .should be_elixir_indentation + end + + it "spans in multiple lines inside parentheses" do + <<-EOF + defmodule Test do + def lol do + Enum.map([1,2,3], fn x -> + x * 3 + end) + end + end + EOF + .should be_elixir_indentation + end + end + + context "multiple body functions declaring" do + it "it with fn syntax" do + <<-EOF + fizzbuzz = fn + 0, 0, _ -> "FizzBuzz" + 0, _, _ -> "Fizz" + _, 0, _ -> "Buzz" + _, _, x -> x + end + EOF + .should be_elixir_indentation + end + + it "it with function syntax" do + <<-EOF + fizzbuzz = function do + 0, 0, _ -> "FizzBuzz" + 0, _, _ -> "Fizz" + _, 0, _ -> "Buzz" + _, _, x -> x + end + EOF + .should be_elixir_indentation + end + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/blocks_spec.rb b/sources_non_forked/vim-elixir/spec/indent/blocks_spec.rb new file mode 100644 index 00000000..d46aa7b4 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/blocks_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +describe "Indenting" do + specify "'do' indenting" do + <<-EOF + do + something + end + EOF + .should be_elixir_indentation + end + + it "does not consider :end as end" do + <<-EOF + defmodule Test do + def lol do + IO.inspect :end + end + end + EOF + .should be_elixir_indentation + end + + it "does not consider do: as the start of a block" do + <<-EOF + def f do + if true, do: 42 + end + EOF + .should be_elixir_indentation + end + + it "do not mislead atom ':do'" do + <<-EOF + def f do + x = :do + end + EOF + .should be_elixir_indentation + end + + it "multiline assignment" do + <<-EOF + defmodule Test do + def test do + one = + user + |> build_assoc(:videos) + |> Video.changeset() + + other = + user2 + |> build_assoc(:videos) + |> Video.changeset() + end + end + EOF + .should be_elixir_indentation + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/case_spec.rb b/sources_non_forked/vim-elixir/spec/indent/case_spec.rb new file mode 100644 index 00000000..e1b5a791 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/case_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "Indenting" do + specify "case statements" do + <<-EOF + case some_function do + :ok -> + :ok + { :error, :message } -> + { :error, :message } + end + EOF + .should be_elixir_indentation + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/cond_spec.rb b/sources_non_forked/vim-elixir/spec/indent/cond_spec.rb new file mode 100644 index 00000000..5d0fe8dc --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/cond_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe "Indenting" do + it "conditional" do + <<-EOF + cond do + foo -> 1 + bar -> 2 + end + EOF + .should be_elixir_indentation + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/documentation_spec.rb b/sources_non_forked/vim-elixir/spec/indent/documentation_spec.rb new file mode 100644 index 00000000..520c4af4 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/documentation_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe "Indenting" do + context "documentation" do + it "with end keyword" do + <<-EOF + defmodule Test do + @doc """ + end + """ + end + EOF + .should be_elixir_indentation + end + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/embedded_elixir_spec.rb b/sources_non_forked/vim-elixir/spec/indent/embedded_elixir_spec.rb new file mode 100644 index 00000000..ce15df03 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/embedded_elixir_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe "Indenting" do + describe "Embedded Elixir" do + it "if-clauses" do + <<-EOF + # An Example + <%= if true do %> + It is obviously true + <% end %> + --- + EOF + .should be_eelixir_indentation + end + + it "if-else-clauses" do + <<-EOF + # An Example + <%= if true do %> + It is obviously true + <% else %> + This will never appear + <% end %> + --- + EOF + .should be_eelixir_indentation + end + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/if_spec.rb b/sources_non_forked/vim-elixir/spec/indent/if_spec.rb new file mode 100644 index 00000000..0552685b --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/if_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe "Indenting" do + it "if-clauses" do + <<-EOF + if foo do + bar + end + EOF + .should be_elixir_indentation + end + + it "if-else-clauses" do + <<-EOF + if foo do + bar + else + baz + end + EOF + .should be_elixir_indentation + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/lists_spec.rb b/sources_non_forked/vim-elixir/spec/indent/lists_spec.rb new file mode 100644 index 00000000..eacede81 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/lists_spec.rb @@ -0,0 +1,131 @@ +require 'spec_helper' + +describe "Indenting" do + specify "lists" do + <<-EOF + def example do + [ :foo, + :bar, + :baz ] + end + EOF + .should be_elixir_indentation + end + + specify "nested list" do + <<-EOF + [ + [ + :foo + ] + ] + EOF + .should be_elixir_indentation + end + + specify "keyword list" do + <<-EOF + def project do + [ name: "mix", + version: "0.1.0", + deps: deps ] + end + EOF + .should be_elixir_indentation + end + + specify "keyword" do + <<-EOF + def config do + [ name: + "John" ] + end + EOF + .should be_elixir_indentation + end + + specify "list of tuples" do + <<-EOF + def test do + [ { :cowboy, github: "extend/cowboy" }, + { :dynamo, "0.1.0-dev", github: "elixir-lang/dynamo" }, + { :ecto, github: "elixir-lang/ecto" }, + { :pgsql, github: "semiocast/pgsql" } ] + end + EOF + .should be_elixir_indentation + end + + specify "list of lists" do + <<-EOF + def test do + [ [:a, :b, :c], + [:d, :e, :f] ] + end + EOF + .should be_elixir_indentation + end + + specify "complex list" do + <<-EOF + def test do + [ app: :first, + version: "0.0.1", + dynamos: [First.Dynamo], + compilers: [:elixir, :dynamo, :ecto, :app], + env: [prod: [compile_path: "ebin"]], + compile_path: "tmp/first/ebin", + deps: deps ] + end + EOF + .should be_elixir_indentation + end + + specify "lists without whitespace" do + <<-EOF + def project do + [{:bar, path: "deps/umbrella/apps/bar"}, + {:umbrella, path: "deps/umbrella"}] + end + EOF + .should be_elixir_indentation + end + + specify "lists with line break after square brackets" do + <<-EOF + def project do + [ + { :bar, path: "deps/umbrella/apps/bar" }, + { :umbrella, path: "deps/umbrella" } + ] + end + EOF + .should be_elixir_indentation + end + + specify "multiple lists with multiline elements" do + <<-EOF + def test do + a = [ + %{ + foo: 1, + bar: 2 + } + ] + + b = %{ + [ + :foo, + :bar + ] + } + + [ + a, + b + ] + end + EOF + .should be_elixir_indentation + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/pipeline_spec.rb b/sources_non_forked/vim-elixir/spec/indent/pipeline_spec.rb new file mode 100644 index 00000000..26d66129 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/pipeline_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe "Indenting" do + it "using multiline pipeline" do + <<-EOF + "a,b,c,d" + |> String.split(",") + |> Enum.reverse + EOF + .should be_elixir_indentation + end + + it "attribuition using multline pipeline operator" do + <<-EOF + [ h | t ] = "a,b,c,d" + |> String.split(",") + |> Enum.reverse + EOF + .should be_elixir_indentation + end + + it "function with pipeline operator" do + <<-EOF + def test do + [ h | t ] = "a,b,c,d" + |> String.split(",") + |> Enum.reverse + + { :ok, h } + end + EOF + .should be_elixir_indentation + end + + it "do not breaks on `==`" do + <<-EOF + def test do + my_post = Post + |> where([p], p.id == 10) + |> where([p], u.user_id == 1) + |> select([p], p) + end + EOF + .should be_elixir_indentation + end + + it "pipeline operator with block open" do + <<-EOF + def test do + "a,b,c,d" + |> String.split(",") + |> Enum.first + |> case do + "a" -> "A" + _ -> "Z" + end + end + EOF + .should be_elixir_indentation + end + + it "using a record with pipeline" do + <<-EOF + defrecord RECORD, field_a: nil, field_b: nil + + rec = RECORD.new + |> IO.inspect + EOF + .should be_elixir_indentation + end +end diff --git a/sources_non_forked/vim-elixir/spec/indent/tuples_spec.rb b/sources_non_forked/vim-elixir/spec/indent/tuples_spec.rb new file mode 100644 index 00000000..063838fb --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/indent/tuples_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe "Indenting" do + specify "multiline tuple" do + <<-EOF + def xpto do + { :a, + :b, + :c } + end + EOF + .should be_elixir_indentation + end + + specify "tuples with break line after square brackets" do + <<-EOF + def method do + { + :bar, + path: "deps/umbrella/apps/bar" + } + end + EOF + .should be_elixir_indentation + end +end diff --git a/sources_non_forked/vim-elixir/spec/spec_helper.rb b/sources_non_forked/vim-elixir/spec/spec_helper.rb new file mode 100644 index 00000000..f4d5757f --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/spec_helper.rb @@ -0,0 +1,115 @@ +require 'rspec/expectations' +require 'tmpdir' +require 'vimrunner' + +class Buffer + attr_reader :file, :vim + + def initialize(vim, type) + @file = "test.#{type}" + @vim = vim + end + + def reindent(code) + open code do + # remove all indentation + vim.normal 'ggVG999<<' + # force vim to indent the file + vim.normal 'gg=G' + end + end + + def syntax(code, pattern) + read code + # move cursor the pattern + vim.search pattern + # get a list of the syntax element + vim.echo <<-EOF + map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') + EOF + end + + private + + def open(code) + read code + # run vim commands + yield if block_given? + vim.write + IO.read(file) + end + + def read(code) + File.open(file, 'w') { |f| f.write code } + vim.edit file + end +end + +def cleanup(string) + whitespace = string.scan(/^\s*/).first + string.gsub(/^#{whitespace}/, '') +end + +{ be_elixir_indentation: :ex, + be_eelixir_indentation: :eex +}.each do |matcher, type| + RSpec::Matchers.define matcher do + buffer = Buffer.new(VIM, type) + + match do |code| + actual = cleanup(code) + buffer.reindent(actual) == actual + end + + failure_message_for_should do |code| + actual = cleanup(code) + "expected:\n\n#{actual}\n got:\n\n#{ buffer.reindent(actual) }\n after elixir indentation" + end + end +end + +{ include_elixir_syntax: :ex, + include_eelixir_syntax: :eex +}.each do |matcher, type| + RSpec::Matchers.define matcher do |syntax, pattern| + buffer = Buffer.new(VIM, type) + + match do |code| + cleanup(code) + buffer.syntax(code, pattern).include? syntax + end + + failure_message_for_should do |code| + actual = cleanup(code) + "expected #{buffer.syntax(code, pattern)} to include syntax #{syntax}\nfor pattern: /#{pattern}/\n in:\n\n#{actual}" + end + + failure_message_for_should_not do |code| + actual = cleanup(code) + "expected #{buffer.syntax(code, pattern)} not to include syntax #{syntax}\nfor pattern: /#{pattern}/\n in:\n\n#{actual}" + end + end +end + +RSpec.configure do |config| + config.before(:suite) do + VIM = Vimrunner.start_gvim + VIM.prepend_runtimepath(File.expand_path('../..', __FILE__)) + VIM.command('runtime ftdetect/elixir.vim') + VIM.command('runtime ftdetect/eelixir.vim') + end + + config.after(:suite) do + VIM.kill + end + + config.around(:each) do |example| + # cd into a temporary directory for every example. + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + VIM.command("cd #{dir}") + example.call + end + end + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/alias_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/alias_spec.rb new file mode 100644 index 00000000..3b647996 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/alias_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe "Alias syntax" do + it "colorize only module alias" do + <<-EOF + Enum.empty?(...) + EOF + .should include_elixir_syntax('elixirAlias', 'Enum') + end + + it "colorize the module alias even if it starts with `!`" do + <<-EOF + !Enum.empty?(...) + EOF + .should include_elixir_syntax('elixirAlias', 'aEnum') + end + + it "does not colorize words starting with lowercase letters" do + <<-EOF + aEnum.empty?(...) + EOF + .should_not include_elixir_syntax('elixirAlias', 'aEnum') + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/default_argument_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/default_argument_spec.rb new file mode 100644 index 00000000..ff930f0f --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/default_argument_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "Default argument syntax" do + it "default argument" do + <<-'EOF' + def foo(bar \\ :baz) + EOF + .should include_elixir_syntax('elixirOperator', '\\') + + <<-EOF + def foo(bar // :baz) + EOF + .should include_elixir_syntax('elixirOperator', '\/') + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/embedded_elixir_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/embedded_elixir_spec.rb new file mode 100644 index 00000000..9352a444 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/embedded_elixir_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe "Embedded Elixir syntax" do + it "elixir" do + '<%= if true do %>'.should include_eelixir_syntax('elixirKeyword', 'if') + '<%= if true do %>'.should include_eelixir_syntax('elixirBoolean', 'true') + end + + it "expression" do + '<%= if true do %>'.should include_eelixir_syntax('eelixirExpression', 'if') + '<% end %>'.should include_eelixir_syntax('eelixirExpression', 'end') + end + + it "quote" do + '<%% def f %>'.should include_eelixir_syntax('eelixirQuote', 'def') + end + + it "comment" do + '<%# foo bar baz %>'.should include_eelixir_syntax('eelixirComment', 'foo') + end + + it "delimiters" do + '<% end %>'.should include_eelixir_syntax('eelixirDelimiter', '<%') + '<% end %>'.should include_eelixir_syntax('eelixirDelimiter', '%>') + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/guard_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/guard_spec.rb new file mode 100644 index 00000000..58c28d98 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/guard_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe "Guard syntax" do + it "guard in function" do + <<-EOF + def fun(a) when is_atom(a) do + end + EOF + .should include_elixir_syntax('elixirKeyword', 'is_atom') + end + + it "guard in case" do + <<-EOF + case + a when is_atom(a) -> {:ok, a} + end + EOF + .should include_elixir_syntax('elixirKeyword', 'is_atom') + end + + it "does not highlight outside guards" do + <<-EOF + if is_atom(a) do + {:ok, a} + end + EOF + .should_not include_elixir_syntax('elixirKeyword', 'is_atom') + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/heredoc_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/heredoc_spec.rb new file mode 100644 index 00000000..d34e74ec --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/heredoc_spec.rb @@ -0,0 +1,70 @@ +require 'spec_helper' + +describe "Heredoc syntax" do + describe "binary" do + it "with multiline content" do + <<-EOF + @doc """ + foo + """ + EOF + .should include_elixir_syntax('elixirDocString', 'foo') + end + + it "escapes quotes unless only preceded by whitespace" do + <<-EOF + @doc """ + foo """ + """ + EOF + .should include_elixir_syntax('elixirDocString', %q(^\s*\zs""")) + end + + it "does not include content on initial line", focus: true do + <<-EOF + String.at """, 0 + foo + end + EOF + .should include_elixir_syntax('elixirNumber', '0') + end + + it "with interpolation" do + <<-EOF + @doc """ + foo \#{bar} + """ + EOF + .should include_elixir_syntax('elixirInterpolation', 'bar') + end + end + + describe "character list" do + it "with multiline content" do + <<-EOF + @doc """ + foo + """ + EOF + .should include_elixir_syntax('elixirDocString', 'foo') + end + + it "escapes quotes unless only preceded by whitespace" do + <<-EOF + @doc ''' + foo ''' + ''' + EOF + .should include_elixir_syntax('elixirDocString', %q(^\s*\zs''')) + end + + it "with interpolation" do + <<-EOF + @doc ''' + foo \#{bar} + ''' + EOF + .should include_elixir_syntax('elixirInterpolation', 'bar') + end + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/list_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/list_spec.rb new file mode 100644 index 00000000..4e650910 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/list_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe "List syntax" do + it 'should properly handle "\\\\" inside' do + syntax = <<-EOF + '"\\\\' + var = 1 + EOF + syntax.should include_elixir_syntax('elixirId', 'var') + syntax.should_not include_elixir_syntax('elixirString', 'var') + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/records_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/records_spec.rb new file mode 100644 index 00000000..6b21ef70 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/records_spec.rb @@ -0,0 +1,11 @@ +# encoding: utf-8 +require 'spec_helper' + +describe "Record syntax" do + it "private record symbol" do + <<-EOF + defrecordp :user, name: "José", age: 25 + EOF + .should include_elixir_syntax('elixirAtom', ':user') + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/sigil_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/sigil_spec.rb new file mode 100644 index 00000000..d3106f39 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/sigil_spec.rb @@ -0,0 +1,104 @@ +require 'spec_helper' + +describe "Sigil syntax" do + describe "upper case" do + it "string" do + '~S(string)'.should include_elixir_syntax('elixirSigilDelimiter', 'S') + '~S(string)'.should include_elixir_syntax('elixirSigil', 'foo') + end + + it "character list" do + '~C(charlist)'.should include_elixir_syntax('elixirSigilDelimiter', 'C') + '~C(charlist)'.should include_elixir_syntax('elixirSigil', 'charlist') + end + + it "regular expression" do + '~R(regex)'.should include_elixir_syntax('elixirSigilDelimiter', 'R') + '~R(regex)'.should include_elixir_syntax('elixirSigil', 'regex') + end + + it "list of words" do + '~W(list of words)'.should include_elixir_syntax('elixirSigilDelimiter', 'W') + '~W(list of words)'.should include_elixir_syntax('elixirSigil', 'list') + end + + it "delimited with parans" do + '~S(foo bar)'.should include_elixir_syntax('elixirSigilDelimiter', '(') + '~S(foo bar)'.should include_elixir_syntax('elixirSigilDelimiter', ')') + end + + it "delimited with braces" do + '~S{foo bar}'.should include_elixir_syntax('elixirSigilDelimiter', '{') + '~S{foo bar}'.should include_elixir_syntax('elixirSigilDelimiter', '}') + end + + it "delimited with brackets" do + '~S[foo bar]'.should include_elixir_syntax('elixirSigilDelimiter', '[') + '~S[foo bar]'.should include_elixir_syntax('elixirSigilDelimiter', ']') + end + + it "escapes double quotes unless only preceded by whitespace" do + <<-EOF + ~r""" + foo """ + """ + EOF + .should include_elixir_syntax('elixirSigilDelimiter', %q(^\s*\zs""")) + end + + it "escapes single quotes unless only preceded by whitespace" do + <<-EOF + ~r''' + foo ''' + ''' + EOF + .should include_elixir_syntax('elixirSigilDelimiter', %q(^\s*\zs''')) + end + + it "without escapes" do + '~S(foo \n bar)'.should_not include_elixir_syntax('elixirRegexEscape', '\\') + end + + it "without interpolation" do + '~S(foo #{bar})'.should_not include_elixir_syntax('elixirInterpolation', 'bar') + end + + it "without escaped parans" do + '~S(\( )'.should_not include_elixir_syntax('elixirRegexEscapePunctuation', '( ') + end + end + + describe "lower case" do + it "string" do + '~s(string)'.should include_elixir_syntax('elixirSigilDelimiter', 's') + '~s(string)'.should include_elixir_syntax('elixirSigil', 'foo') + end + + it "character list" do + '~c(charlist)'.should include_elixir_syntax('elixirSigilDelimiter', 'c') + '~c(charlist)'.should include_elixir_syntax('elixirSigil', 'charlist') + end + + it "regular expression" do + '~r(regex)'.should include_elixir_syntax('elixirSigilDelimiter', 'r') + '~r(regex)'.should include_elixir_syntax('elixirSigil', 'regex') + end + + it "list of words" do + '~w(list of words)'.should include_elixir_syntax('elixirSigilDelimiter', 'w') + '~w(list of words)'.should include_elixir_syntax('elixirSigil', 'list') + end + + it "with escapes" do + '~s(foo \n bar)'.should include_elixir_syntax('elixirRegexEscape', '\\') + end + + it "with interpolation" do + '~s(foo #{bar})'.should include_elixir_syntax('elixirInterpolation', 'bar') + end + + it "with escaped parans" do + '~s(\( )'.should include_elixir_syntax('elixirRegexEscapePunctuation', '( ') + end + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/struct_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/struct_spec.rb new file mode 100644 index 00000000..0b409788 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/struct_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe "Struct syntax" do + it "without defaults" do + <<-EOF + defstruct [:name, :age] + EOF + .should include_elixir_syntax('elixirAtom', ':name') + end + + it "with defaults" do + <<-EOF + defstruct name: "john", age: 27 + EOF + .should include_elixir_syntax('elixirAtom', 'name:') + end +end diff --git a/sources_non_forked/vim-elixir/spec/syntax/variable_spec.rb b/sources_non_forked/vim-elixir/spec/syntax/variable_spec.rb new file mode 100644 index 00000000..974053c0 --- /dev/null +++ b/sources_non_forked/vim-elixir/spec/syntax/variable_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe "Variable syntax" do + it "unused" do + <<-EOF + def handle_call(:pop, _from, [h|stack]) do + { :reply, h, stack } + end + EOF + .should include_elixir_syntax('elixirUnusedVariable', '_from') + end +end diff --git a/sources_non_forked/vim-elixir/syntax/eelixir.vim b/sources_non_forked/vim-elixir/syntax/eelixir.vim new file mode 100644 index 00000000..df31da77 --- /dev/null +++ b/sources_non_forked/vim-elixir/syntax/eelixir.vim @@ -0,0 +1,61 @@ +if exists("b:current_syntax") + finish +endif + +if !exists("main_syntax") + let main_syntax = 'eelixir' +endif + +if !exists("g:eelixir_default_subtype") + let g:eelixir_default_subtype = "html" +endif + +if !exists("b:eelixir_subtype") + let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$") + let b:eelixir_subtype = matchstr(s:lines,'eelixir_subtype=\zs\w\+') + if b:eelixir_subtype == '' + let b:eelixir_subtype = matchstr(&filetype,'^eex\.\zs\w\+') + endif + if b:eelixir_subtype == '' + let b:eelixir_subtype = matchstr(substitute(expand("%:t"),'\c\%(\.eex\|\.eelixir\)\+$','',''),'\.\zs\w\+$') + endif + if b:eelixir_subtype == 'ex' + let b:eelixir_subtype = 'elixir' + elseif b:eelixir_subtype == 'exs' + let b:eelixir_subtype = 'elixir' + elseif b:eelixir_subtype == 'yml' + let b:eelixir_subtype = 'yaml' + elseif b:eelixir_subtype == 'js' + let b:eelixir_subtype = 'javascript' + elseif b:eelixir_subtype == 'txt' + " Conventional; not a real file type + let b:eelixir_subtype = 'text' + elseif b:eelixir_subtype == '' + let b:eelixir_subtype = g:eelixir_default_subtype + endif +endif + +if exists("b:eelixir_subtype") && b:eelixir_subtype != '' + exe "runtime! syntax/".b:eelixir_subtype.".vim" + unlet! b:current_syntax +endif + +syn include @elixirTop syntax/elixir.vim + +syn cluster eelixirRegions contains=eelixirBlock,eelixirExpression,eelixirComment + +exe 'syn region eelixirExpression matchgroup=eelixirDelimiter start="<%" end="%\@" contains=@elixirTop containedin=ALLBUT,@eelixirRegions keepend' +exe 'syn region eelixirExpression matchgroup=eelixirDelimiter start="<%=" end="%\@" contains=@elixirTop containedin=ALLBUT,@eelixirRegions keepend' +exe 'syn region eelixirQuote matchgroup=eelixirDelimiter start="<%%" end="%\@" contains=@elixirTop containedin=ALLBUT,@eelixirRegions keepend' +exe 'syn region eelixirComment matchgroup=eelixirDelimiter start="<%#" end="%\@" contains=elixirTodo,@Spell containedin=ALLBUT,@eelixirRegions keepend' + +" Define the default highlighting. + +hi def link eelixirDelimiter PreProc +hi def link eelixirComment Comment + +let b:current_syntax = 'eelixir' + +if main_syntax == 'eelixir' + unlet main_syntax +endif diff --git a/sources_non_forked/vim-elixir/syntax/elixir.vim b/sources_non_forked/vim-elixir/syntax/elixir.vim new file mode 100644 index 00000000..f383f806 --- /dev/null +++ b/sources_non_forked/vim-elixir/syntax/elixir.vim @@ -0,0 +1,188 @@ +if exists("b:current_syntax") + finish +endif + +" syncing starts 2000 lines before top line so docstrings don't screw things up +syn sync minlines=2000 + +syn cluster elixirNotTop contains=@elixirRegexSpecial,@elixirStringContained,@elixirDeclaration,elixirTodo,elixirArguments,elixirBlockDefinition + +syn match elixirComment '#.*' contains=elixirTodo,@Spell +syn keyword elixirTodo FIXME NOTE TODO OPTIMIZE XXX HACK contained + +syn keyword elixirKeyword case when with cond for if unless try receive send +syn keyword elixirKeyword exit raise throw after rescue catch else +syn keyword elixirKeyword quote unquote super spawn spawn_link spawn_monitor + +" Functions used on guards +syn keyword elixirKeyword contained is_atom is_binary is_bitstring is_boolean +syn keyword elixirKeyword contained is_float is_function is_integer is_list +syn keyword elixirKeyword contained is_map is_nil is_number is_pid is_port +syn keyword elixirKeyword contained is_record is_reference is_tuple is_exception +syn keyword elixirKeyword contained abs bit_size byte_size div elem hd length +syn keyword elixirKeyword contained map_size node rem round tl trunc tuple_size + +syn match elixirGuard '.*when.*' contains=ALLBUT,@elixirNotTop + +syn keyword elixirInclude import require alias use + +syn keyword elixirSelf self + +syn match elixirId '\<[_a-zA-Z]\w*[!?]\?\>' + +" This unfortunately also matches function names in function calls +syn match elixirUnusedVariable '\(([^)]*\)\@<=\<_\w*\>' + +syn keyword elixirOperator and not or when xor in +syn match elixirOperator '!==\|!=\|!' +syn match elixirOperator '=\~\|===\|==\|=' +syn match elixirOperator '<<<\|<<\|<=\|<-\|<' +syn match elixirOperator '>>>\|>>\|>=\|>' +syn match elixirOperator '->\|--\|-' +syn match elixirOperator '++\|+' +syn match elixirOperator '&&&\|&&\|&' +syn match elixirOperator '|||\|||\||>\||' +syn match elixirOperator '\.\.\|\.' +syn match elixirOperator "\^\^\^\|\^" +syn match elixirOperator '\\\\\|::\|\*\|/\|\~\~\~\|@' + +syn match elixirAtom '\(:\)\@=]\@!\)\?\|<>\|===\?\|>=\?\|<=\?\)' +syn match elixirAtom '\(:\)\@\|&&\?\|%\(()\|\[\]\|{}\)\|++\?\|--\?\|||\?\|!\|//\|[%&`/|]\)' +syn match elixirAtom "\%([a-zA-Z_]\w*[?!]\?\):\(:\)\@!" + +syn match elixirAlias '\<[!]\?[A-Z]\w*\(\.[A-Z]\w*\)*\>' + +syn keyword elixirBoolean true false nil + +syn match elixirVariable '@[a-z]\w*' +syn match elixirVariable '&\d\+' + +syn keyword elixirPseudoVariable __FILE__ __DIR__ __MODULE__ __ENV__ __CALLER__ + +syn match elixirNumber '\<\d\(_\?\d\)*\(\.[^[:space:][:digit:]]\@!\(_\?\d\)*\)\?\([eE][-+]\?\d\(_\?\d\)*\)\?\>' +syn match elixirNumber '\<0[xX][0-9A-Fa-f]\+\>' +syn match elixirNumber '\<0[bB][01]\+\>' + +syn match elixirRegexEscape "\\\\\|\\[aAbBcdDefGhHnrsStvVwW]\|\\\d\{3}\|\\x[0-9a-fA-F]\{2}" contained +syn match elixirRegexEscapePunctuation "?\|\\.\|*\|\\\[\|\\\]\|+\|\\^\|\\\$\|\\|\|\\(\|\\)\|\\{\|\\}" contained +syn match elixirRegexQuantifier "[*?+][?+]\=" contained display +syn match elixirRegexQuantifier "{\d\+\%(,\d*\)\=}?\=" contained display +syn match elixirRegexCharClass "\[:\(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]" contained display + +syn region elixirRegex matchgroup=elixirRegexDelimiter start="%r/" end="/[uiomxfr]*" skip="\\\\" contains=@elixirRegexSpecial + +syn cluster elixirRegexSpecial contains=elixirRegexEscape,elixirRegexCharClass,elixirRegexQuantifier,elixirRegexEscapePunctuation +syn cluster elixirStringContained contains=elixirInterpolation,elixirRegexEscape,elixirRegexCharClass + +syn region elixirString matchgroup=elixirStringDelimiter start="'" end="'" skip="\\'\|\\\\" +syn region elixirString matchgroup=elixirStringDelimiter start='"' end='"' skip='\\"' contains=@elixirStringContained +syn region elixirInterpolation matchgroup=elixirInterpolationDelimiter start="#{" end="}" contained contains=ALLBUT,elixirComment,@elixirNotTop + +syn region elixirDocStringStart matchgroup=elixirDocString start=+"""+ end=+$+ oneline contains=ALLBUT,@elixirNotTop +syn region elixirDocStringStart matchgroup=elixirDocString start=+'''+ end=+$+ oneline contains=ALLBUT,@elixirNotTop +syn region elixirDocString start=+\z("""\)+ end=+^\s*\zs\z1+ contains=elixirDocStringStart,elixirTodo,elixirInterpolation,@Spell keepend fold +syn region elixirDocString start=+\z('''\)+ end=+^\s*\zs\z1+ contains=elixirDocStringStart,elixirTodo,elixirInterpolation,@Spell keepend fold + +syn match elixirAtomInterpolated ':\("\)\@=' contains=elixirString +syn match elixirString "\(\w\)\@\|0[0-7]{0,2}[0-7]\@!\>\|[^x0MC]\)\|(\\[MC]-)+\w\|[^\s\\]\)" + +syn region elixirBlock matchgroup=elixirBlockDefinition start="\:\@!" end="\" contains=ALLBUT,@elixirNotTop fold +syn region elixirAnonymousFunction matchgroup=elixirBlockDefinition start="\" end="\" contains=ALLBUT,@elixirNotTop fold + +syn region elixirArguments start="(" end=")" contained contains=elixirOperator,elixirAtom,elixirPseudoVariable,elixirAlias,elixirBoolean,elixirVariable,elixirUnusedVariable,elixirNumber,elixirDocString,elixirAtomInterpolated,elixirRegex,elixirString,elixirStringDelimiter,elixirRegexDelimiter,elixirInterpolationDelimiter,elixirSigilDelimiter + +syn match elixirDelimEscape "\\[(<{\[)>}\]/\"'|]" transparent display contained contains=NONE + +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\u\z(/\|\"\|'\||\)" end="\z1" skip="\\\\\|\\\z1" contains=elixirDelimEscape fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\u{" end="}" skip="\\\\\|\\}" contains=elixirDelimEscape fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\u<" end=">" skip="\\\\\|\\>" contains=elixirDelimEscape fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\u\[" end="\]" skip="\\\\\|\\\]" contains=elixirDelimEscape fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\u(" end=")" skip="\\\\\|\\)" contains=elixirDelimEscape fold + +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\l\z(/\|\"\|'\||\)" end="\z1" skip="\\\\\|\\\z1" fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\l{" end="}" skip="\\\\\|\\}" contains=@elixirStringContained,elixirRegexEscapePunctuation fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\l<" end=">" skip="\\\\\|\\>" contains=@elixirStringContained,elixirRegexEscapePunctuation fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\l\[" end="\]" skip="\\\\\|\\\]" contains=@elixirStringContained,elixirRegexEscapePunctuation fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start="\~\l(" end=")" skip="\\\\\|\\)" contains=@elixirStringContained,elixirRegexEscapePunctuation fold + +" Sigils surrounded with docString +syn region elixirSigil matchgroup=elixirSigilDelimiter start=+\~\a\z("""\)+ end=+^\s*\zs\z1+ skip=+\\"+ fold +syn region elixirSigil matchgroup=elixirSigilDelimiter start=+\~\a\z('''\)+ end=+^\s*\zs\z1+ skip=+\\'+ fold + +" Defines +syn keyword elixirDefine def nextgroup=elixirFunctionDeclaration skipwhite skipnl +syn keyword elixirPrivateDefine defp nextgroup=elixirFunctionDeclaration skipwhite skipnl +syn keyword elixirModuleDefine defmodule nextgroup=elixirModuleDeclaration skipwhite skipnl +syn keyword elixirProtocolDefine defprotocol nextgroup=elixirProtocolDeclaration skipwhite skipnl +syn keyword elixirImplDefine defimpl nextgroup=elixirImplDeclaration skipwhite skipnl +syn keyword elixirRecordDefine defrecord nextgroup=elixirRecordDeclaration skipwhite skipnl +syn keyword elixirPrivateRecordDefine defrecordp nextgroup=elixirRecordDeclaration skipwhite skipnl +syn keyword elixirMacroDefine defmacro nextgroup=elixirMacroDeclaration skipwhite skipnl +syn keyword elixirPrivateMacroDefine defmacrop nextgroup=elixirMacroDeclaration skipwhite skipnl +syn keyword elixirDelegateDefine defdelegate nextgroup=elixirDelegateDeclaration skipwhite skipnl +syn keyword elixirOverridableDefine defoverridable nextgroup=elixirOverridableDeclaration skipwhite skipnl +syn keyword elixirExceptionDefine defexception nextgroup=elixirExceptionDeclaration skipwhite skipnl +syn keyword elixirCallbackDefine defcallback nextgroup=elixirCallbackDeclaration skipwhite skipnl +syn keyword elixirStructDefine defstruct skipwhite skipnl + +" Declarations +syn match elixirModuleDeclaration "[^[:space:];#<]\+" contained contains=elixirAlias nextgroup=elixirBlock skipwhite skipnl +syn match elixirFunctionDeclaration "[^[:space:];#<,()\[\]]\+" contained nextgroup=elixirArguments skipwhite skipnl +syn match elixirProtocolDeclaration "[^[:space:];#<]\+" contained contains=elixirAlias skipwhite skipnl +syn match elixirImplDeclaration "[^[:space:];#<]\+" contained contains=elixirAlias skipwhite skipnl +syn match elixirRecordDeclaration "[^[:space:];#<]\+" contained contains=elixirAlias,elixirAtom skipwhite skipnl +syn match elixirMacroDeclaration "[^[:space:];#<,()\[\]]\+" contained nextgroup=elixirArguments skipwhite skipnl +syn match elixirDelegateDeclaration "[^[:space:];#<,()\[\]]\+" contained contains=elixirFunctionDeclaration skipwhite skipnl +syn region elixirDelegateDeclaration start='\[' end='\]' contained contains=elixirFunctionDeclaration skipwhite skipnl +syn match elixirOverridableDeclaration "[^[:space:];#<]\+" contained contains=elixirAlias skipwhite skipnl +syn match elixirExceptionDeclaration "[^[:space:];#<]\+" contained contains=elixirAlias skipwhite skipnl +syn match elixirCallbackDeclaration "[^[:space:];#<,()\[\]]\+" contained contains=elixirFunctionDeclaration skipwhite skipnl + +syn cluster elixirDeclaration contains=elixirFunctionDeclaration,elixirModuleDeclaration,elixirProtocolDeclaration,elixirImplDeclaration,elixirRecordDeclaration,elixirMacroDeclaration,elixirDelegateDeclaration,elixirOverridableDeclaration,elixirExceptionDeclaration,elixirCallbackDeclaration,elixirStructDeclaration + +hi def link elixirBlockDefinition Keyword +hi def link elixirDefine Define +hi def link elixirPrivateDefine Define +hi def link elixirModuleDefine Define +hi def link elixirProtocolDefine Define +hi def link elixirImplDefine Define +hi def link elixirRecordDefine Define +hi def link elixirPrivateRecordDefine Define +hi def link elixirMacroDefine Define +hi def link elixirPrivateMacroDefine Define +hi def link elixirDelegateDefine Define +hi def link elixirOverridableDefine Define +hi def link elixirExceptionDefine Define +hi def link elixirCallbackDefine Define +hi def link elixirStructDefine Define +hi def link elixirFunctionDeclaration Function +hi def link elixirMacroDeclaration Macro +hi def link elixirInclude Include +hi def link elixirComment Comment +hi def link elixirTodo Todo +hi def link elixirKeyword Keyword +hi def link elixirOperator Operator +hi def link elixirAtom Constant +hi def link elixirPseudoVariable Constant +hi def link elixirAlias Type +hi def link elixirBoolean Boolean +hi def link elixirVariable Identifier +hi def link elixirSelf Identifier +hi def link elixirUnusedVariable Comment +hi def link elixirNumber Number +hi def link elixirDocString String +hi def link elixirAtomInterpolated elixirAtom +hi def link elixirRegex elixirString +hi def link elixirRegexEscape elixirSpecial +hi def link elixirRegexEscapePunctuation elixirSpecial +hi def link elixirRegexCharClass elixirSpecial +hi def link elixirRegexQuantifier elixirSpecial +hi def link elixirSpecial Special +hi def link elixirString String +hi def link elixirSigil String +hi def link elixirStringDelimiter Delimiter +hi def link elixirRegexDelimiter Delimiter +hi def link elixirInterpolationDelimiter Delimiter +hi def link elixirSigilDelimiter Delimiter + +let b:current_syntax = "elixir"