├── README.md └── ftdetect ├── elixir.vim └── projections.json /README.md: -------------------------------------------------------------------------------- 1 | # vim-projectionist-elixir 2 | 3 | Vim file navigation for Elixir projects 4 | 5 | This plugin supplies quick-nav links for Elixir projects. **Alternate File 6 | Navigation** gives commands to jump between an Elixir source file and it's 7 | associated test. **Related File Navigation** gives commands to jump between 8 | Phoenix controllers, views and templates. 9 | 10 | Install using `Plug` in your `.vimrc`: 11 | 12 | Plug 'tpope/vim-projectionist' 13 | Plug 'c-brenn/fuzzy-projectionist.vim' 14 | Plug 'andyl/vim-projectionist-elixir' 15 | 16 | See also: 17 | - Tim Pope's [vim-projectionist][l2] plugin. 18 | - Conor Brennan's [fuzzy-projectionist.vim][l3] plugin. 19 | 20 | ## Alternate File Navigation 21 | 22 | 'Alternates' are the source code and test file - a one-to-one relationship. 23 | 24 | `:A` - open the 'alternate' file 25 | 26 | `:AS` - open the 'alternate' file in a split window 27 | 28 | `:AV` - open the 'alternate' file in a vertical split window 29 | 30 | `:AT` - open the 'alternate' file in another tab 31 | 32 | ## Related File Navigation 33 | 34 | In Phoenix projects, you can jump between 'related' files (controllers / 35 | templates / views). 36 | 37 | There are two types of relations: 38 | 1) one-to-one relationship, eg `controller -> view` 39 | 2) one-to-many relationship, eg `controller => template` 40 | 41 | For one-to-one relationships, use the Projectionist `E` commands: 42 | 43 | - `:Econtroller` 44 | - `:Eview` 45 | 46 | For one-to-many relationships, use the Fuzzy-Projectionist `F` commands: 47 | 48 | - `:Ftemplate` 49 | 50 | ## Working with Umbrella Projects 51 | 52 | This plugin is going to work with `mix` projects where source 53 | files are stored under the `lib` directory and corresponding test 54 | files are stored under `test`. 55 | 56 | To work with umbrella projects, you'll need to put a custom 57 | `.projections.json` file in the root directory of your umbrella 58 | project. 59 | 60 | To quickly generate a `.projections.json` file for an umbrella 61 | project, see the [ex_projections][l1] project. 62 | 63 | [l1]: https://github.com/andyl/ex_projections 64 | [l2]: https://github.com/tpope/vim-projectionist 65 | [l3]: https://github.com/c-brenn/fuzzy-projectionist.vim 66 | -------------------------------------------------------------------------------- /ftdetect/elixir.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_vim_projectionist_elixir') 2 | finish 3 | endif 4 | let g:loaded_vim_projectionist_elixir = 1 5 | 6 | let s:base_dir = resolve(expand(":p:h")) 7 | let s:proj_jsn = s:base_dir . "/projections.json" 8 | 9 | function! s:setProjections() 10 | let l:json = readfile(s:proj_jsn) 11 | let l:dict = projectionist#json_parse(l:json) 12 | call projectionist#append(getcwd(), l:dict) 13 | endfunction 14 | 15 | augroup elixir 16 | autocmd! 17 | autocmd User ProjectionistDetect :call s:setProjections() 18 | augroup end 19 | 20 | -------------------------------------------------------------------------------- /ftdetect/projections.json: -------------------------------------------------------------------------------- 1 | { 2 | "lib/*.ex": { 3 | "type": "src", 4 | "alternate": "test/{}_test.exs", 5 | "template": [ 6 | "# lib/{}.ex", 7 | "defmodule XXX do", 8 | "end" 9 | ] 10 | }, 11 | "test/*_test.exs": { 12 | "type": "test", 13 | "alternate": "lib/{}.ex", 14 | "template": [ 15 | "# test/{}_test.exs", 16 | "defmodule XXX do", 17 | " ", 18 | " use ExUnit.Case", 19 | " ", 20 | " alias XXX", 21 | " ", 22 | " describe \"#myfunc/1\" do", 23 | " test \"description\" do", 24 | " assert true", 25 | " end", 26 | " end", 27 | " ", 28 | "end" 29 | ] 30 | }, 31 | "*_controller.ex": { 32 | "type": "controller", 33 | "related": [ 34 | "{dirname|dirname}/views/{basename}_view.ex" 35 | ], 36 | "template": [ 37 | "# {basename}_controller.ex", 38 | "defmodule XXX do", 39 | "end" 40 | ] 41 | }, 42 | "*_live.ex": { 43 | "type": "live", 44 | "related": [ 45 | "{dirname|dirname}/views/{basename}_view.ex" 46 | ], 47 | "template": [ 48 | "# {basename}_live.ex", 49 | "defmodule XXX do", 50 | "end" 51 | ] 52 | }, 53 | "*_view.ex": { 54 | "type": "view", 55 | "related": [ 56 | "{dirname|dirname}/controllers/{basename}_controller.ex", 57 | "{dirname|dirname}/live/{basename}_live.ex" 58 | ], 59 | "template": [ 60 | "# {basename}_view.ex", 61 | "defmodule XXX do", 62 | "end" 63 | ] 64 | }, 65 | "*eex": { 66 | "type": "template", 67 | "related": [ 68 | "{dirname|dirname|dirname}/controllers/{dirname|basename}_controller.ex", 69 | "{dirname|dirname|dirname}/live/{dirname|basename}_live.ex", 70 | "{dirname|dirname|dirname}/views/{dirname|basename}_view.ex" 71 | ], 72 | "template": [ 73 | "<%# {basename} eex template %>" 74 | ] 75 | } 76 | } 77 | --------------------------------------------------------------------------------