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