├── LICENSE ├── ultisnips └── elixir.snippets ├── README.md ├── plugin └── phoenix.vim ├── autoload └── phoenix.vim └── doc └── phoenix.txt /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015 by Arjan van der Gaag 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /ultisnips/elixir.snippets: -------------------------------------------------------------------------------- 1 | extends elixir 2 | 3 | snippet pipe "pipeline" wb 4 | pipeline :${1:browser} do 5 | $0 6 | end 7 | endsnippet 8 | 9 | snippet pipe "pipe_through" wb 10 | pipe_through :${1:browser} 11 | endsnippet 12 | 13 | snippet get "GET route" wb 14 | get "${1:/}", ${2:Project}Controller, :${3:index} 15 | endsnippet 16 | 17 | snippet post "POST route" wb 18 | post "${1:/}", ${2:Project}Controller, :${3:create} 19 | endsnippet 20 | 21 | snippet put "PUT route" wb 22 | put "${1:/}", ${2:Project}Controller, :${3:update} 23 | endsnippet 24 | 25 | snippet delete "DELETE route" wb 26 | delete "${1:/}", ${2:Project}Controller, :${3:destroy} 27 | endsnippet 28 | 29 | snippet res "resources route" wb 30 | resources "/${1:projects}", ${2:Project}Controller 31 | endsnippet 32 | 33 | snippet res "resource route" wb 34 | resource "/${1:project}", ${2:Project}Controller 35 | endsnippet 36 | 37 | snippet scope "routing scope" wb 38 | scope "${1:/}", ${2:MyApp} do 39 | $0 40 | end 41 | endsnippet 42 | 43 | snippet socket "socket route" wb 44 | socket "/${1:ws}", ${2:MyApp} do 45 | $0 46 | end 47 | endsnippet 48 | 49 | snippet channel "socket channel route" wb 50 | channel "${1:notifications}", ${2:Notification}Channel 51 | endsnippet 52 | 53 | snippet redirect "redirect(conn, to: ...)" b 54 | redirect(${1:${2:conn}, }to: ${3:${4:project}_path(${5:conn}, :${6:index})}) 55 | endsnippet 56 | 57 | snippet render "render(conn, view, assigns)" b 58 | render(${1:${2:conn}, }, "${3:view}"${4:, $5}) 59 | endsnippet 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-phoenix 2 | 3 | This plugin helps you navigate and develop projects using the [Phoenix web 4 | framework][phoenix]. A Phoenix project is detected by looking for a `mix.exs` 5 | file along with `web` directory. When you edit a file in a Phoenix project, this 6 | plugin will be activated. This sets various options and defines some commands. 7 | It also integrates with other Vim plugins. 8 | 9 | ## Features 10 | 11 | * Integrates with [vim-projectionist][] for navigating project files according 12 | to Phoenix conventions. 13 | * Comes with extra mappings for [vim-surround][]. 14 | * Comes with extra snippets for [UltiSnips][]. 15 | * Provides `:Mix` command that delegates to `mix`. 16 | * Provides project-specific Vim navigation settings for `path` and 17 | `suffixesadd`. 18 | 19 | See the documentation (`:help phoenix`) for more information. 20 | 21 | ## Installation 22 | 23 | Use your favourite Vim plugin manager to install this plugin. I use 24 | [pathogen][]. Otherwise, download this plugin and put the files in its 25 | subdirectories to the corresponding subdirectories in your `~/.vim` directory. 26 | 27 | ## About 28 | 29 | To find our more about the Phoenix framework, see: 30 | https://github.com/phoenixframework/phoenix 31 | 32 | To get the latest updates or report bugs, see this plugin's Github repository: 33 | https://github.com/avdgaag/vim-phoenix 34 | 35 | ## Credits 36 | 37 | Author: Arjan van der Gaag 38 | URL: http://arjanvandergaag.nl 39 | 40 | This plugin is based on earlier work by Tim Pope, who has released many 41 | incredible Vim plugins. 42 | 43 | ## License 44 | 45 | See LICENSE. 46 | 47 | [vim-projectionist]: https://github.com/tpope/vim-projectionist 48 | [vim-surround]: https://github.com/tpope/vim-surround 49 | [UltiSnips]: https://github.com/SirVer/UltiSnips 50 | [pathogen]: https://github.com/tpope/vim-pathogen 51 | [phoenix]: https://github.com/phoenixframework/phoenix 52 | -------------------------------------------------------------------------------- /plugin/phoenix.vim: -------------------------------------------------------------------------------- 1 | " phoenix.vim - Shortcuts and settings for project with the Phoenix framework 2 | " Maintainer: Arjan van der Gaag 3 | " Version: 0.1 4 | 5 | if exists('g:loaded_phoenix') || &cp 6 | finish 7 | endif 8 | let g:loaded_phoenix = 1 9 | 10 | augroup phoenix 11 | autocmd! 12 | 13 | " Setup when openening a file without a filetype 14 | autocmd BufNewFile,BufReadPost * 15 | \ if empty(&filetype) | 16 | \ call phoenix#Setup(expand(':p')) | 17 | \ endif 18 | 19 | " Setup when launching Vim for a file with any filetype 20 | autocmd FileType * call phoenix#Setup(expand('%:p')) 21 | 22 | " Setup when launching Vim without a buffer 23 | autocmd VimEnter * 24 | \ if expand('') == '' | 25 | \ call phoenix#Setup(getcwd()) | 26 | \ endif 27 | augroup end 28 | 29 | let s:projections = { 30 | \ "web/channels/*_channel.ex": { 31 | \ "type": "channel", 32 | \ "alternate": "test/channels/{}_channel_test.exs" 33 | \ }, 34 | \ "web/controllers/*_controller.ex": { 35 | \ "type": "controller", 36 | \ "alternate": "test/controllers/{}_controller_test.exs" 37 | \ }, 38 | \ "web/views/*_view.ex": { 39 | \ "type": "view", 40 | \ "alternate": "test/views/{}_view_test.exs" 41 | \ }, 42 | \ "web/models/*.ex": { 43 | \ "type": "model", 44 | \ "alternate": "test/models/{}_test.exs" 45 | \ }, 46 | \ "test/channels/*_channel_test.exs": { 47 | \ "alternate": "web/channels/{}_channel.ex" 48 | \ }, 49 | \ "test/controllers/*_controller_test.exs": { 50 | \ "alternate": "web/controllers/{}_controller.ex" 51 | \ }, 52 | \ "test/views/*_view_test.exs": { 53 | \ "alternate": "web/views/{}_view.ex" 54 | \ }, 55 | \ "test/models/*_test.exs": { 56 | \ "alternate": "web/models/{}.ex" 57 | \ }, 58 | \ "web/templates/*.html.exs": { 59 | \ "type": "template" 60 | \ }, 61 | \ "web/router.ex": { 62 | \ "type": "router" 63 | \ }, 64 | \ "web/static/css/*": { 65 | \ "type": "stylesheet" 66 | \ }, 67 | \ "web/static/js/*": { 68 | \ "type": "javascript" 69 | \ }, 70 | \ "config/*.exs": { 71 | \ "type": "config" 72 | \ }, 73 | \ "lib/*": { 74 | \ "type": "lib" 75 | \ }, 76 | \ "priv/repo/migrations/*.exs": { 77 | \ "type": "migration" 78 | \ } 79 | \ } 80 | 81 | augroup phoenix_projections 82 | autocmd! 83 | autocmd User ProjectionistDetect call phoenix#ProjectionistDetect(s:projections) 84 | augroup END 85 | 86 | augroup phoenix_path 87 | autocmd! 88 | autocmd User Phoenix call phoenix#SetupSnippets() 89 | autocmd User Phoenix call phoenix#DefineMixCommand() 90 | autocmd User Phoenix call phoenix#SetupSurround() 91 | autocmd User Phoenix 92 | \ let &l:path = 'lib/**,web/**,test/**,config/**' . &path | 93 | \ let &l:suffixesadd = '.ex,.exs,.html.eex' . &suffixesadd 94 | augroup END 95 | -------------------------------------------------------------------------------- /autoload/phoenix.vim: -------------------------------------------------------------------------------- 1 | " phoenix.vim - Shortcuts and settings for project with the Phoenix framework 2 | " Maintainer: Arjan van der Gaag 3 | " Version: 0.1 4 | 5 | function! s:shellslash(path) abort 6 | if exists('+shellslash') && !&shellslash 7 | return substitute(a:path, '\\', '/', 'g') 8 | else 9 | return a:path 10 | endif 11 | endfunction 12 | 13 | function! s:find_root(path) abort 14 | let root = s:shellslash(simplify(fnamemodify(a:path, ':p:s?[\/]$??'))) 15 | let previous = '' 16 | while root !=# previous && root !=# '/' 17 | if filereadable(root . '/mix.exs') && isdirectory(root . '/web') 18 | return root 19 | end 20 | let previous = root 21 | let root = fnamemodify(root, ':h') 22 | endwhile 23 | return '' 24 | endfunction 25 | 26 | function! s:Detect(path) abort 27 | if !exists('b:phoenix_root') 28 | let dir = s:find_root(a:path) 29 | if dir !=# '' 30 | let b:phoenix_root = dir 31 | endif 32 | endif 33 | endfunction 34 | 35 | function! phoenix#Setup(path) abort 36 | call s:Detect(a:path) 37 | if exists('b:phoenix_root') 38 | doautocmd User Phoenix 39 | endif 40 | endfunction 41 | 42 | " Hook function that gets run when vim-projectionist looks up available 43 | " projections. This allows us to inject our own, custom projections. 44 | " 45 | " This function handles inserting our projections for buffers in a Phoenix 46 | " project. 47 | function! phoenix#ProjectionistDetect(projections) abort 48 | if exists('b:phoenix_root') 49 | call projectionist#append(b:phoenix_root, a:projections) 50 | endif 51 | endfunction 52 | 53 | function! phoenix#SetupSnippets() abort 54 | let snippetsDir = expand('', ':h') . '/ultisnips' 55 | if exists('g:UltiSnipsSnippetsDir') 56 | call add(g:UltiSnipsSnippetsDir, snippetsDir) 57 | else 58 | let g:UltiSnipsSnippetsDir = [snippetsDir] 59 | endif 60 | endfunction 61 | 62 | function! phoenix#SetupSurround() abort 63 | if exists('g:loaded_surround') 64 | if !exists('b:surround_45') 65 | let b:surround_45 = "<% \r %>" 66 | endif 67 | if !exists('b:surround_61') 68 | let b:surround_61 = "<%= \r %>" 69 | endif 70 | if !exists('b:surround_35') 71 | let b:surround_35 = "<%# \r %>" 72 | endif 73 | if !exists('b:surround_5') 74 | let b:surround_5 = "<% \r %>\n<% end %>" 75 | endif 76 | endif 77 | endfunction 78 | 79 | function! s:Mix(...) abort 80 | exe '!mix ' . join(copy(a:000), ' ') 81 | endfunction 82 | 83 | function! s:MixComplete(ArgLead, CmdLine, CursorPos, ...) abort 84 | if !exists('g:mix_tasks') 85 | let g:mix_tasks = system("mix -h | awk '!/-S/ && $2 != \"#\" { print $2 }'") 86 | endif 87 | return g:mix_tasks 88 | endfunction 89 | 90 | function! phoenix#DefineMixCommand() abort 91 | command! -buffer -bar -nargs=? -complete=custom,s:MixComplete Mix 92 | \ execute s:Mix() 93 | endfunction 94 | 95 | -------------------------------------------------------------------------------- /doc/phoenix.txt: -------------------------------------------------------------------------------- 1 | *phoenix.vim* Plugin for working with the Phoenix framework 2 | 3 | Author: Arjan van der Gaag 4 | License: Same terms as Vim itself (see |license|) 5 | 6 | This plugin is only available if 'compatible' is not set. 7 | 8 | ============================================================================= 9 | INTRODUCTION *phoenix* 10 | 11 | This plugin helps you navigate and develop projects using the Phoenix web 12 | framework. A Phoenix project is detected by ascending up the directory 13 | hierarchy until both a `Mix.exs` file and `web` directory are found. When you 14 | edit a file in a Phoenix project, this plugin will be activated. This sets 15 | various options and defines some commands. It also integrates with other Vim 16 | plugins. 17 | 18 | ============================================================================= 19 | NAVIGATION *phoenix-navigation* 20 | 21 | Navigating a phoenix project's many files is what this project is mostly about. 22 | You should first and foremost try to use Vim's own navigation features to get 23 | around your project. To that end, this plugin will tweak a few settings. 24 | 25 | First, all common Phoenix code locations are prepended to 'path', enabling you 26 | to use |:find|: 27 | > 28 | :find page_controller.ex 29 | < 30 | Second, 'suffixesadd' has common Elixir file extensions prependend to it, 31 | allowing you to use |:find| and |gf| to jump to files. 32 | 33 | ============================================================================= 34 | COMMANDS *phoenix-commands* 35 | 36 | :Mix [subcommand] Invoke Mix with the given subcommand. 37 | 38 | ============================================================================= 39 | INTEGRATIONS *phoenix-integrations* 40 | 41 | *phoenix-projections* 42 | The |projections| plugin can be used to define navigation commands. This 43 | plugin provides several projections based on Phoenix project layout conventions. 44 | These include: 45 | 46 | :Echannel [name] Edit a file in {web/channels} 47 | 48 | :Econtroller [name] Edit a file in {web/controllers} 49 | 50 | :Eview [name] Edit a file in {web/views} 51 | 52 | :Emodel [name] Edit a file in {web/models} 53 | 54 | :Etemplate [name] Edit a file in {web/templates} 55 | 56 | :Erouter Edit {web/router.ex} 57 | 58 | :Estylesheet [name] Edit a file in {web/static/css} 59 | 60 | :Ejavascript [name] Edit a file in {web/static/js} 61 | 62 | :Econfig [name] Edit a file in {config/} 63 | 64 | :Elib [name] Edit a file in {lib/} 65 | 66 | :Emigration [name] Edit a file in {priv/repo/mgirations} 67 | 68 | *phoenix-snippets* 69 | The |UltiSnips| plugin can help you to quickly inserts commonly used snippets 70 | of code. This plugin adds several Phoenix and Elixir-related snippets, that 71 | will automatically become available in phoenix projects. 72 | 73 | See {ultisnips/elixir.snippets} to see what's available. 74 | 75 | *phoenix-surround* 76 | The |surround| plugin allows adding and removing "surrounding" characters, 77 | such as parantheses, quotes and HTML tags. This plugin provides a few helpful 78 | additional surroundings that come in handy when editing `.eex` files: 79 | 80 | Key Surrounding ~ 81 | = <%= ^ %> 82 | - <% ^ %> 83 | # <%# ^ %> 84 | <% ^ %>\n<% end -%> 85 | 86 | ============================================================================= 87 | ABOUT *phoenix-about* 88 | 89 | To find our more about the Phoenix framework, see: 90 | 91 | https://github.com/phoenixframework/phoenix 92 | 93 | To get the latest updates or report bugs, see this plugin's Github repository: 94 | 95 | https://github.com/avdgaag/vim-phoenix 96 | 97 | vim:tw=78:ts=8:ft=help:norl: 98 | --------------------------------------------------------------------------------