github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/misc/vim/ftplugin/go/import.vim (about) 1 " Copyright 2011 The Go Authors. All rights reserved. 2 " Use of this source code is governed by a BSD-style 3 " license that can be found in the LICENSE file. 4 " 5 " import.vim: Vim commands to import/drop Go packages. 6 " 7 " This filetype plugin adds three new commands for go buffers: 8 " 9 " :Import {path} 10 " 11 " Import ensures that the provided package {path} is imported 12 " in the current Go buffer, using proper style and ordering. 13 " If {path} is already being imported, an error will be 14 " displayed and the buffer will be untouched. 15 " 16 " :ImportAs {localname} {path} 17 " 18 " Same as Import, but uses a custom local name for the package. 19 " 20 " :Drop {path} 21 " 22 " Remove the import line for the provided package {path}, if 23 " present in the current Go buffer. If {path} is not being 24 " imported, an error will be displayed and the buffer will be 25 " untouched. 26 " 27 " If you would like to add shortcuts, you can do so by doing the following: 28 " 29 " Import fmt 30 " au Filetype go nnoremap <buffer> <LocalLeader>f :Import fmt<CR> 31 " 32 " Drop fmt 33 " au Filetype go nnoremap <buffer> <LocalLeader>F :Drop fmt<CR> 34 " 35 " Import the word under your cursor 36 " au Filetype go nnoremap <buffer> <LocalLeader>k 37 " \ :exe 'Import ' . expand('<cword>')<CR> 38 " 39 " The backslash '\' is the default maplocalleader, so it is possible that 40 " your vim is set to use a different character (:help maplocalleader). 41 " 42 " Options: 43 " 44 " g:go_import_commands [default=1] 45 " 46 " Flag to indicate whether to enable the commands listed above. 47 " 48 if exists("b:did_ftplugin_go_import") 49 finish 50 endif 51 52 if !exists("g:go_import_commands") 53 let g:go_import_commands = 1 54 endif 55 56 if g:go_import_commands 57 command! -buffer -nargs=? -complete=customlist,go#complete#Package Drop call s:SwitchImport(0, '', <f-args>) 58 command! -buffer -nargs=1 -complete=customlist,go#complete#Package Import call s:SwitchImport(1, '', <f-args>) 59 command! -buffer -nargs=* -complete=customlist,go#complete#Package ImportAs call s:SwitchImport(1, <f-args>) 60 endif 61 62 function! s:SwitchImport(enabled, localname, path) 63 let view = winsaveview() 64 let path = a:path 65 66 " Quotes are not necessary, so remove them if provided. 67 if path[0] == '"' 68 let path = strpart(path, 1) 69 endif 70 if path[len(path)-1] == '"' 71 let path = strpart(path, 0, len(path) - 1) 72 endif 73 if path == '' 74 call s:Error('Import path not provided') 75 return 76 endif 77 78 " Extract any site prefix (e.g. github.com/). 79 " If other imports with the same prefix are grouped separately, 80 " we will add this new import with them. 81 " Only up to and including the first slash is used. 82 let siteprefix = matchstr(path, "^[^/]*/") 83 84 let qpath = '"' . path . '"' 85 if a:localname != '' 86 let qlocalpath = a:localname . ' ' . qpath 87 else 88 let qlocalpath = qpath 89 endif 90 let indentstr = 0 91 let packageline = -1 " Position of package name statement 92 let appendline = -1 " Position to introduce new import 93 let deleteline = -1 " Position of line with existing import 94 let linesdelta = 0 " Lines added/removed 95 96 " Find proper place to add/remove import. 97 let line = 0 98 while line <= line('$') 99 let linestr = getline(line) 100 101 if linestr =~# '^package\s' 102 let packageline = line 103 let appendline = line 104 105 elseif linestr =~# '^import\s\+(' 106 let appendstr = qlocalpath 107 let indentstr = 1 108 let appendline = line 109 let firstblank = -1 110 let lastprefix = "" 111 while line <= line("$") 112 let line = line + 1 113 let linestr = getline(line) 114 let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)') 115 if empty(m) 116 if siteprefix == "" && a:enabled 117 " must be in the first group 118 break 119 endif 120 " record this position, but keep looking 121 if firstblank < 0 122 let firstblank = line 123 endif 124 continue 125 endif 126 if m[1] == ')' 127 " if there's no match, add it to the first group 128 if appendline < 0 && firstblank >= 0 129 let appendline = firstblank 130 endif 131 break 132 endif 133 let lastprefix = matchstr(m[4], "^[^/]*/") 134 if a:localname != '' && m[3] != '' 135 let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath) 136 endif 137 let appendstr = m[2] . qlocalpath 138 let indentstr = 0 139 if m[4] == path 140 let appendline = -1 141 let deleteline = line 142 break 143 elseif m[4] < path 144 " don't set candidate position if we have a site prefix, 145 " we've passed a blank line, and this doesn't share the same 146 " site prefix. 147 if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0 148 let appendline = line 149 endif 150 elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0 151 " first entry of site group 152 let appendline = line - 1 153 break 154 endif 155 endwhile 156 break 157 158 elseif linestr =~# '^import ' 159 if appendline == packageline 160 let appendstr = 'import ' . qlocalpath 161 let appendline = line - 1 162 endif 163 let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"') 164 if !empty(m) 165 if m[3] == path 166 let appendline = -1 167 let deleteline = line 168 break 169 endif 170 if m[3] < path 171 let appendline = line 172 endif 173 if a:localname != '' && m[2] != '' 174 let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath) 175 endif 176 let appendstr = 'import' . m[1] . qlocalpath 177 endif 178 179 elseif linestr =~# '^\(var\|const\|type\|func\)\>' 180 break 181 182 endif 183 let line = line + 1 184 endwhile 185 186 " Append or remove the package import, as requested. 187 if a:enabled 188 if deleteline != -1 189 call s:Error(qpath . ' already being imported') 190 elseif appendline == -1 191 call s:Error('No package line found') 192 else 193 if appendline == packageline 194 call append(appendline + 0, '') 195 call append(appendline + 1, 'import (') 196 call append(appendline + 2, ')') 197 let appendline += 2 198 let linesdelta += 3 199 let appendstr = qlocalpath 200 let indentstr = 1 201 endif 202 call append(appendline, appendstr) 203 execute appendline + 1 204 if indentstr 205 execute 'normal >>' 206 endif 207 let linesdelta += 1 208 endif 209 else 210 if deleteline == -1 211 call s:Error(qpath . ' not being imported') 212 else 213 execute deleteline . 'd' 214 let linesdelta -= 1 215 216 if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)' 217 " Delete empty import block 218 let deleteline -= 1 219 execute deleteline . "d" 220 execute deleteline . "d" 221 let linesdelta -= 2 222 endif 223 224 if getline(deleteline) == '' && getline(deleteline - 1) == '' 225 " Delete spacing for removed line too. 226 execute deleteline . "d" 227 let linesdelta -= 1 228 endif 229 endif 230 endif 231 232 " Adjust view for any changes. 233 let view.lnum += linesdelta 234 let view.topline += linesdelta 235 if view.topline < 0 236 let view.topline = 0 237 endif 238 239 " Put buffer back where it was. 240 call winrestview(view) 241 242 endfunction 243 244 function! s:Error(s) 245 echohl Error | echo a:s | echohl None 246 endfunction 247 248 let b:did_ftplugin_go_import = 1 249 250 " vim:ts=4:sw=4:et