1
0
Fork 0
mirror of synced 2024-11-22 08:45:34 -05:00

Replace YanRing with yank-stack and update plugins

This commit is contained in:
amix 2017-12-13 15:05:24 +01:00
parent 2ca843a22a
commit 53894de44b
72 changed files with 1663 additions and 5015 deletions

View file

@ -1,127 +0,0 @@
This is a mirror of http://www.vim.org/scripts/script.php?script_id=1234
Vim already maintains a list of numbered registers containing the last 9 deletes. These previous deletes can be referenced using [register]p, so "1p will paste the last delete, "2p the 2nd last delete. For more information see |quote_number|.
Vim does not provide any mechanism to reference previous yanked, deleted or changed text. In Emacs this feature is called the "kill ring".
The YankRing plugin allows the user to configure the number of yanked, deleted and changed text. A split window can be used to choose which element(s) from the yankring you wish to paste. Alternately after text has been pasted (using p), it can be replaced with a previous value from the yankring with a single key stroke.
The captured text is stored in a file (location configurable) and is instantly available (also configurable) to any other instance of Vim also running on the same machine. This can especially be useful on *nix machines when you are sshed in running Vim in multiple terminals.
Storing the capture text in a file allows the text to be shared easily between multiple instances of Vim running in X, Windows, SSH or Screen.
A tutorial is included to take you through the various features of the plugin. After you have installed the plugin just run:
:h yankring.txt
:h yankring-tutorial
The yankring can be interacted with in two ways: a GUI or via maps.
The yankring supports all of Vim motions and text-objects. There are very few new keystrokes the user must learn. One keystroke to open the yankring to choose which item to paste is all that is required. It has been designed work seamlessly with Vim
All the mappings and behaviours are configurable via global variables you can optionally specify in your vimrc.
The plugin can be toggled on and off, and supports:
Ranges
Registers
Counts
All visual modes (characterwise, linewise and blockwise)
All motions
All text-objects
Examples:
yy - Adds the current line to the yankring.
dd - Adds the current line to the yankring and deletes it.
5yw - Adds 5 words to the yankring.
"ade - Deletes the word, and puts it into both the yankring and the "a register.
cw - Changes the word and stores the previous value in the yankring.
10"zyy - Places 10 lines into both the yankring and the "z register.
:1,4YRYankRange - Similar to 1,4y
:3,$YRDeleteRange - Similar to 3,$d
If you wish to paste previous values from the yankring and do not want to use the GUI, there are only two additional maps you must learn (these are configurable via your vimrc if needed). The purpose of the yankring is to gain access to previously yanked (or deleted) elements. The YRReplace command will replace the previously pasted text with a different entry from the yankring. By default, I choose <C-P> (P for previous) to replace the text last pasted while moving backwards through your previous text from the yankring and <C-N> (N for next) to replace the previous paste while moving forward through the yankring.
A separate buffer window to allow you to easily interact with the contents of the yankring. The window is similar to many other plugins: TagList, SelectBuf and so on. You can use the mouse or standard Vim keys (p, gp, P, ...). Visual mode is used to support counts, pasting multiple times and reversing the order of pasted elements.
The GUI significantly simplifies your interaction with the yankring for basic functions. But often it useful to take advantage of the more powerful features of the yankring.
Here is a small section from the tutorial (using maps) so you have some idea of how you interact with the plugin gaining access to previous yanks. Using the GUI for basic operations is self explanatory.
:h yankring-tutorial
---- Partial Tutorial ----
To understand how to use the yankring, the following example should demonstrate the various features.
Assume we have this buffer:
one
two
three
four
five
Now yank (yy) each line separately starting at line 1. Display the
contents of the yankring.
:YRShow
--- YankRing ---
Elem Content
5 five^@
4 four^@
3 three^@
2 two^@
1 one^@
Since we yanked the text starting at line 1 and finishing at line 5, the most current yankring element is the last one, the contents of line 5.
"five^@" is displayed, the "^@" is a newline character (since we issued a "yy").
Now, go to the end of the file and press p. The resulting buffer appears as:
one
two
three
four
five
five
Now press <C-P> to move backwards through the yankring, this results in:
one
two
three
four
five
four
Now press 2<C-P>. This would be the same as pressing <C-P> two times in a row. This results in:
one
two
three
four
five
two
Now press <C-N> to move forwards through the yankring, this results in:
one
two
three
four
five
three
You can create a map to display a buffer displaying the yankring's contents:
nnoremap <silent> <F11> :YRShow<CR>
YRShow creates a new split buffer (you can configure where it should be and it's size)
:YRShow
AutoClose=1;Cmds:<enter>,[g]p,[p]P,d,r,a,u,q,<space>;Help=?
--- YankRing ---
Elem Content
3 three^@
2 two^@
1 one^@
5 five^@
4 four^@
You can simply hit "p", <enter>, double click on an item and it will be pasted into your document. The window will automatically close (by default) after you have made a choice. The element will be pasted into the correct buffer if you have multiple split windows.
You can paste multiple items using visual mode.
You can also remove items from the yankring.
---- Partial Tutorial ----
Concentrating on the last line of the buffer you could see how we were able to replace our pasted text with lines yanked previously. This is a feature Vim only has for deletes, and is limited to 9. This plugin enables the same features for both yanks, deletes and changes, the size of the history is configurable.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
" Filename: autoload/lightline/colorscheme.vim " Filename: autoload/lightline/colorscheme.vim
" Author: itchyny " Author: itchyny
" License: MIT License " License: MIT License
" Last Change: 2015/03/18 08:37:17. " Last Change: 2017/11/29 12:54:05.
" ============================================================================= " =============================================================================
let s:save_cpo = &cpo let s:save_cpo = &cpo
@ -224,5 +224,34 @@ function! lightline#colorscheme#flatten(p) abort
return a:p return a:p
endfunction endfunction
if has('gui_running')
function! lightline#colorscheme#background() abort
return &background
endfunction
else
" &background is set inappropriately when the colorscheme sets ctermbg of the Normal group
function! lightline#colorscheme#background() abort
let bg_color = synIDattr(synIDtrans(hlID('Normal')), 'bg', 'cterm')
if bg_color !=# ''
if bg_color < 16
return &background
elseif 232 <= bg_color && bg_color < 244
return 'dark'
elseif 244 <= bg_color
return 'light'
endif
endif
let fg_color = synIDattr(synIDtrans(hlID('Normal')), 'fg', 'cterm')
if fg_color !=# ''
if fg_color < 8 || 232 <= fg_color && fg_color < 244
return 'light'
elseif 8 <= fg_color && fg_color < 16 || 244 <= fg_color
return 'dark'
endif
endif
return &background
endfunction
endif
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View file

@ -2,8 +2,9 @@
" Filename: autoload/lightline/colorscheme/16color.vim " Filename: autoload/lightline/colorscheme/16color.vim
" Author: itchyny " Author: itchyny
" License: MIT License " License: MIT License
" Last Change: 2014/01/02 10:04:03. " Last Change: 2017/11/25 11:14:04.
" ============================================================================= " =============================================================================
let s:base03 = [ '#808080', 8 ] let s:base03 = [ '#808080', 8 ]
let s:base02 = [ '#000000', 0 ] let s:base02 = [ '#000000', 0 ]
let s:base01 = [ '#00ff00', 10 ] let s:base01 = [ '#00ff00', 10 ]
@ -20,12 +21,14 @@ let s:violet = [ '#ff00ff', 13 ]
let s:blue = [ '#000080', 4 ] let s:blue = [ '#000080', 4 ]
let s:cyan = [ '#008080', 6 ] let s:cyan = [ '#008080', 6 ]
let s:green = [ '#008000', 2 ] let s:green = [ '#008000', 2 ]
if &background ==# 'light'
if lightline#colorscheme#background() ==# 'light'
let [s:base03, s:base3] = [s:base3, s:base03] let [s:base03, s:base3] = [s:base3, s:base03]
let [s:base02, s:base2] = [s:base2, s:base02] let [s:base02, s:base2] = [s:base2, s:base02]
let [s:base01, s:base1] = [s:base1, s:base01] let [s:base01, s:base1] = [s:base1, s:base01]
let [s:base00, s:base0] = [s:base0, s:base00] let [s:base00, s:base0] = [s:base0, s:base00]
endif endif
let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}} let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
let s:p.normal.left = [ [ s:base3, s:blue ], [ s:base3, s:base01 ] ] let s:p.normal.left = [ [ s:base3, s:blue ], [ s:base3, s:base01 ] ]
let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ] let s:p.normal.right = [ [ s:base02, s:base0 ], [ s:base1, s:base01 ] ]

View file

@ -2,10 +2,10 @@
" Filename: autoload/lightline/colorscheme/PaperColor.vim " Filename: autoload/lightline/colorscheme/PaperColor.vim
" Author: TKNGUE " Author: TKNGUE
" License: MIT License " License: MIT License
" Last Change: 2015/07/28 07:35:00. " Last Change: 2017/11/25 11:13:35.
" ============================================================================= " =============================================================================
if &background ==# 'light' if lightline#colorscheme#background() ==# 'light'
let g:lightline#colorscheme#PaperColor#palette = g:lightline#colorscheme#PaperColor_light#palette let g:lightline#colorscheme#PaperColor#palette = g:lightline#colorscheme#PaperColor_light#palette
else else
let g:lightline#colorscheme#PaperColor#palette = g:lightline#colorscheme#PaperColor_dark#palette let g:lightline#colorscheme#PaperColor#palette = g:lightline#colorscheme#PaperColor_dark#palette

View file

@ -2,7 +2,7 @@
" Filename: autoload/lightline/colorscheme/materia.vim " Filename: autoload/lightline/colorscheme/materia.vim
" Author: Lokesh Krishna " Author: Lokesh Krishna
" License: MIT License " License: MIT License
" Last Change: 2017/10/21 11:32:27. " Last Change: 2017/11/25 11:13:40.
" ============================================================================= " =============================================================================
" Common colors " Common colors
@ -16,7 +16,7 @@ let s:yellow = '#ffcc00'
let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}} let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
if &background ==# 'light' if lightline#colorscheme#background() ==# 'light'
" Light variant " Light variant
let s:bg = '#ffffff' let s:bg = '#ffffff'
let s:gray1 = '#2c393f' let s:gray1 = '#2c393f'

View file

@ -2,7 +2,7 @@
" Filename: autoload/lightline/colorscheme/material.vim " Filename: autoload/lightline/colorscheme/material.vim
" Author: Lokesh Krishna " Author: Lokesh Krishna
" License: MIT License " License: MIT License
" Last Change: 2017/10/30 16:35:27. " Last Change: 2017/11/25 11:13:42.
" ============================================================================= " =============================================================================
" Common colors " Common colors
@ -16,7 +16,7 @@ let s:yellow = '#ffcb6b'
let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}} let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
if &background ==# 'light' if lightline#colorscheme#background() ==# 'light'
" Light variant " Light variant
let s:bg = '#ffffff' let s:bg = '#ffffff'
let s:gray1 = '#2e3c43' let s:gray1 = '#2e3c43'

View file

@ -31,7 +31,7 @@ let s:p.normal.warning = [ [ s:nord1, s:nord13 ] ]
let s:p.normal.error = [ [ s:nord1, s:nord11 ] ] let s:p.normal.error = [ [ s:nord1, s:nord11 ] ]
let s:p.inactive.left = [ [ s:nord1, s:nord8 ], [ s:nord5, s:nord1 ] ] let s:p.inactive.left = [ [ s:nord1, s:nord8 ], [ s:nord5, s:nord1 ] ]
let s:p.inactive.middle = [ [ s:nord5, s:nord0 ] ] let s:p.inactive.middle = [ [ s:nord5, s:nord1 ] ]
let s:p.inactive.right = [ [ s:nord5, s:nord1 ], [ s:nord5, s:nord1 ] ] let s:p.inactive.right = [ [ s:nord5, s:nord1 ], [ s:nord5, s:nord1 ] ]
let s:p.insert.left = [ [ s:nord1, s:nord6 ], [ s:nord5, s:nord1 ] ] let s:p.insert.left = [ [ s:nord1, s:nord6 ], [ s:nord5, s:nord1 ] ]

View file

@ -2,26 +2,27 @@
" Filename: autoload/lightline/colorscheme/one.vim " Filename: autoload/lightline/colorscheme/one.vim
" Author: Zoltan Dalmadi " Author: Zoltan Dalmadi
" License: MIT License " License: MIT License
" Last Change: 2016/11/2 17:34:27. " Last Change: 2017/11/28 21:53:01.
" ============================================================================= " =============================================================================
" Common colors " Common colors
let s:fg = '#abb2bf' let s:fg = [ '#abb2bf', 145 ]
let s:blue = '#61afef' let s:blue = [ '#61afef', 75 ]
let s:green = '#98c379' let s:green = [ '#98c379', 76 ]
let s:purple = '#c678dd' let s:purple = [ '#c678dd', 176 ]
let s:red1 = '#e06c75' let s:red1 = [ '#e06c75', 168 ]
let s:red2 = '#be5046' let s:red2 = [ '#be5046', 168 ]
let s:yellow = '#e5c07b' let s:yellow = [ '#e5c07b', 180 ]
let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}} let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
if &background ==# 'light' if lightline#colorscheme#background() ==# 'light'
" Light variant " Light variant
let s:bg = '#fafafa' let s:bg = [ '#fafafa', 255 ]
let s:gray1 = '#494b53' let s:gray1 = [ '#494b53', 238 ]
let s:gray2 = '#f0f0f0' let s:gray2 = [ '#f0f0f0', 255 ]
let s:gray3 = '#d0d0d0' let s:gray3 = [ '#d0d0d0', 250 ]
let s:green = [ '#98c379', 35 ]
let s:p.normal.left = [ [ s:bg, s:green, 'bold' ], [ s:gray1, s:gray3 ] ] let s:p.normal.left = [ [ s:bg, s:green, 'bold' ], [ s:gray1, s:gray3 ] ]
let s:p.normal.middle = [ [ s:gray1, s:gray2 ] ] let s:p.normal.middle = [ [ s:gray1, s:gray2 ] ]
@ -33,10 +34,10 @@ if &background ==# 'light'
let s:p.visual.left = [ [ s:bg, s:purple, 'bold' ], [ s:gray1, s:gray3 ] ] let s:p.visual.left = [ [ s:bg, s:purple, 'bold' ], [ s:gray1, s:gray3 ] ]
else else
" Dark variant " Dark variant
let s:bg = '#282c34' let s:bg = [ '#282c34', 235 ]
let s:gray1 = '#5c6370' let s:gray1 = [ '#5c6370', 241 ]
let s:gray2 = '#2c323d' let s:gray2 = [ '#2c323d', 235 ]
let s:gray3 = '#3e4452' let s:gray3 = [ '#3e4452', 240 ]
let s:p.normal.left = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ] let s:p.normal.left = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.normal.middle = [ [ s:fg, s:gray2 ] ] let s:p.normal.middle = [ [ s:fg, s:gray2 ] ]
@ -60,4 +61,4 @@ let s:p.tabline.tabsel = [ [ s:bg, s:purple, 'bold' ] ]
let s:p.tabline.middle = [ [ s:gray3, s:gray2 ] ] let s:p.tabline.middle = [ [ s:gray3, s:gray2 ] ]
let s:p.tabline.right = copy(s:p.normal.right) let s:p.tabline.right = copy(s:p.normal.right)
let g:lightline#colorscheme#one#palette = lightline#colorscheme#fill(s:p) let g:lightline#colorscheme#one#palette = lightline#colorscheme#flatten(s:p)

View file

@ -2,7 +2,7 @@
" Filename: autoload/lightline/colorscheme/solarized.vim " Filename: autoload/lightline/colorscheme/solarized.vim
" Author: itchyny " Author: itchyny
" License: MIT License " License: MIT License
" Last Change: 2016/08/08 10:31:00. " Last Change: 2017/11/25 11:13:46.
" ============================================================================= " =============================================================================
let s:cuicolors = { let s:cuicolors = {
@ -53,7 +53,7 @@ let s:blue = [ '#268bd2', s:cuicolors.blue[s:cuiindex] ]
let s:cyan = [ '#2aa198', s:cuicolors.cyan[s:cuiindex] ] let s:cyan = [ '#2aa198', s:cuicolors.cyan[s:cuiindex] ]
let s:green = [ '#859900', s:cuicolors.green[s:cuiindex] ] let s:green = [ '#859900', s:cuicolors.green[s:cuiindex] ]
if &background ==# 'light' if lightline#colorscheme#background() ==# 'light'
let [ s:base03, s:base3 ] = [ s:base3, s:base03 ] let [ s:base03, s:base3 ] = [ s:base3, s:base03 ]
let [ s:base02, s:base2 ] = [ s:base2, s:base02 ] let [ s:base02, s:base2 ] = [ s:base2, s:base02 ]
let [ s:base01, s:base1 ] = [ s:base1, s:base01 ] let [ s:base01, s:base1 ] = [ s:base1, s:base01 ]

View file

@ -227,24 +227,30 @@ function! s:closeTreeWindow()
endif endif
endfunction endfunction
" FUNCTION: s:deleteBookmark(bm) {{{1 " FUNCTION: s:deleteBookmark(bookmark) {{{1
" if the cursor is on a bookmark, prompt to delete " Prompt the user to confirm the deletion of the selected bookmark.
function! s:deleteBookmark(bm) function! s:deleteBookmark(bookmark)
echo "Are you sure you wish to delete the bookmark:\n\"" . a:bm.name . "\" (yN):" let l:message = "Delete the bookmark \"" . a:bookmark.name
\ . "\" from the bookmark list?"
if nr2char(getchar()) ==# 'y' let l:choices = "&Yes\n&No"
try
call a:bm.delete() echo | redraw
call b:NERDTree.root.refresh() let l:selection = confirm(l:message, l:choices, 1, 'Warning')
call b:NERDTree.render()
redraw if l:selection != 1
catch /^NERDTree/ call nerdtree#echo('bookmark not deleted')
call nerdtree#echoWarning("Could not remove bookmark") return
endtry
else
call nerdtree#echo("delete aborted" )
endif endif
try
call a:bookmark.delete()
silent call b:NERDTree.root.refresh()
call b:NERDTree.render()
echo | redraw
catch /^NERDTree/
call nerdtree#echoWarning('could not remove bookmark')
endtry
endfunction endfunction
" FUNCTION: s:displayHelp() {{{1 " FUNCTION: s:displayHelp() {{{1
@ -255,10 +261,16 @@ function! s:displayHelp()
call b:NERDTree.ui.centerView() call b:NERDTree.ui.centerView()
endfunction endfunction
" FUNCTION: s:findAndRevealPath() {{{1 " FUNCTION: s:findAndRevealPath(path) {{{1
function! s:findAndRevealPath() function! s:findAndRevealPath(path)
let l:path = a:path
if empty(l:path)
let l:path = expand('%:p')
endif
try try
let p = g:NERDTreePath.New(expand("%:p")) let p = g:NERDTreePath.New(l:path)
catch /^NERDTree.InvalidArgumentsError/ catch /^NERDTree.InvalidArgumentsError/
call nerdtree#echo("no file for the current buffer") call nerdtree#echo("no file for the current buffer")
return return
@ -581,7 +593,7 @@ function! nerdtree#ui_glue#setupCommands()
command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close() command! -n=0 -bar NERDTreeClose :call g:NERDTree.Close()
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('<args>') command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('<args>')
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror() command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
command! -n=0 -bar NERDTreeFind call s:findAndRevealPath() command! -n=? -complete=file -bar NERDTreeFind call s:findAndRevealPath('<args>')
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus() command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
command! -n=0 -bar NERDTreeCWD call NERDTreeCWD() command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
endfunction endfunction

View file

@ -164,20 +164,14 @@ function! s:UI.getPath(ln)
let indent = self._indentLevelFor(line) let indent = self._indentLevelFor(line)
"remove the tree parts and the leading space "remove the tree parts and the leading space
let curFile = self._stripMarkup(line, 0) let curFile = self._stripMarkup(line)
let wasdir = 0
if curFile =~# '/$'
let wasdir = 1
let curFile = substitute(curFile, '/\?$', '/', "")
endif
let dir = "" let dir = ""
let lnum = a:ln let lnum = a:ln
while lnum > 0 while lnum > 0
let lnum = lnum - 1 let lnum = lnum - 1
let curLine = getline(lnum) let curLine = getline(lnum)
let curLineStripped = self._stripMarkup(curLine, 1) let curLineStripped = self._stripMarkup(curLine)
"have we reached the top of the tree? "have we reached the top of the tree?
if lnum == rootLine if lnum == rootLine
@ -228,7 +222,7 @@ function! s:UI.getLineNum(file_node)
let indent = self._indentLevelFor(curLine) let indent = self._indentLevelFor(curLine)
if indent ==# curPathComponent if indent ==# curPathComponent
let curLine = self._stripMarkup(curLine, 1) let curLine = self._stripMarkup(curLine)
let curPath = join(pathcomponents, '/') . '/' . curLine let curPath = join(pathcomponents, '/') . '/' . curLine
if stridx(fullpath, curPath, 0) ==# 0 if stridx(fullpath, curPath, 0) ==# 0
@ -366,14 +360,12 @@ function! s:UI.setShowHidden(val)
let self._showHidden = a:val let self._showHidden = a:val
endfunction endfunction
"FUNCTION: s:UI._stripMarkup(line, removeLeadingSpaces){{{1 "FUNCTION: s:UI._stripMarkup(line){{{1
"returns the given line with all the tree parts stripped off "returns the given line with all the tree parts stripped off
" "
"Args: "Args:
"line: the subject line "line: the subject line
"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces = function! s:UI._stripMarkup(line)
"any spaces before the actual text of the node)
function! s:UI._stripMarkup(line, removeLeadingSpaces)
let line = a:line let line = a:line
"remove the tree parts and the leading space "remove the tree parts and the leading space
let line = substitute (line, g:NERDTreeUI.MarkupReg(),"","") let line = substitute (line, g:NERDTreeUI.MarkupReg(),"","")
@ -390,18 +382,7 @@ function! s:UI._stripMarkup(line, removeLeadingSpaces)
"strip off any generic flags "strip off any generic flags
let line = substitute (line, '\[[^]]*\]', "","") let line = substitute (line, '\[[^]]*\]', "","")
let wasdir = 0
if line =~# '/$'
let wasdir = 1
endif
let line = substitute (line,' -> .*',"","") " remove link to let line = substitute (line,' -> .*',"","") " remove link to
if wasdir ==# 1
let line = substitute (line, '/\?$', '/', "")
endif
if a:removeLeadingSpaces
let line = substitute (line, '^ *', '', '')
endif
return line return line
endfunction endfunction

View file

@ -32,7 +32,7 @@ hi def link coffeeConditional Conditional
syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display
hi def link coffeeException Exception hi def link coffeeException Exception
syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\|yield\|debugger\|import\|export\|await\)\>/ syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\|yield\|debugger\|import\|export\|default\|await\)\>/
\ display \ display
" The `own` keyword is only a keyword after `for`. " The `own` keyword is only a keyword after `for`.
syn match coffeeKeyword /\<for\s\+own\>/ contained containedin=coffeeRepeat syn match coffeeKeyword /\<for\s\+own\>/ contained containedin=coffeeRepeat
@ -107,7 +107,7 @@ hi def link coffeeFloat Float
" An error for reserved keywords, taken from the RESERVED array: " An error for reserved keywords, taken from the RESERVED array:
" http://coffeescript.org/documentation/docs/lexer.html#section-67 " http://coffeescript.org/documentation/docs/lexer.html#section-67
syn match coffeeReservedError /\<\%(case\|default\|function\|var\|void\|with\|const\|let\|enum\|native\|implements\|interface\|package\|private\|protected\|public\|static\)\>/ syn match coffeeReservedError /\<\%(case\|function\|var\|void\|with\|const\|let\|enum\|native\|implements\|interface\|package\|private\|protected\|public\|static\)\>/
\ display \ display
hi def link coffeeReservedError Error hi def link coffeeReservedError Error

View file

@ -241,7 +241,7 @@ augroup fugitive
autocmd! autocmd!
autocmd BufNewFile,BufReadPost * call fugitive#detect(expand('%:p')) autocmd BufNewFile,BufReadPost * call fugitive#detect(expand('%:p'))
autocmd FileType netrw call fugitive#detect(expand('%:p')) autocmd FileType netrw call fugitive#detect(expand('%:p'))
autocmd User NERDTreeInit,NERDTreeNewRoot call fugitive#detect(b:NERDTreeRoot.path.str()) autocmd User NERDTreeInit,NERDTreeNewRoot call fugitive#detect(b:NERDTree.root.path.str())
autocmd VimEnter * if expand('<amatch>')==''|call fugitive#detect(getcwd())|endif autocmd VimEnter * if expand('<amatch>')==''|call fugitive#detect(getcwd())|endif
autocmd CmdWinEnter * call fugitive#detect(expand('#:p')) autocmd CmdWinEnter * call fugitive#detect(expand('#:p'))
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave') autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
@ -661,7 +661,9 @@ function! s:buffer_expand(rev) dict abort
else else
let file = a:rev let file = a:rev
endif endif
return s:sub(s:sub(file,'\%$',self.path()),'\.\@<=/$','') return s:sub(substitute(file,
\ '%$\|\\\([[:punct:]]\)','\=len(submatch(1)) ? submatch(1) : self.path()','g'),
\ '\.\@<=/$','')
endfunction endfunction
function! s:buffer_containing_commit() dict abort function! s:buffer_containing_commit() dict abort

View file

@ -0,0 +1,3 @@
[run]
plugins = covimerage
data_file = .coverage.covimerage

View file

@ -1,2 +1,5 @@
doc/tags
.DS_Store .DS_Store
/doc/tags
/.coverage.covimerage
/coverage.xml
*.pyc

View file

@ -3,12 +3,12 @@ notifications:
email: false email: false
matrix: matrix:
include: include:
- env: SCRIPT=test VIM_VERSION=vim-7.4 - env: SCRIPT="test -c" VIM_VERSION=vim-7.4
- env: SCRIPT=test VIM_VERSION=vim-8.0 - env: SCRIPT="test -c" VIM_VERSION=vim-8.0
- env: SCRIPT=test VIM_VERSION=nvim - env: SCRIPT="test -c" VIM_VERSION=nvim
- env: SCRIPT=lint VIM_VERSION=vim-8.0 - env: SCRIPT=lint VIM_VERSION=vim-8.0
install: install:
- ./scripts/install-vim $VIM_VERSION - ./scripts/install-vim $VIM_VERSION
- pip install --user vim-vint - pip install --user vim-vint covimerage codecov
script: script:
- ./scripts/$SCRIPT $VIM_VERSION - ./scripts/$SCRIPT $VIM_VERSION

View file

@ -1,11 +1,43 @@
## unplanned ## unplanned
BACKWARDS INCOMPATIBILITIES: FEATURES:
* Display a warning for Vim versions older than 7.4.1689. Older versions may * Add `g:go_doc_url` to change the `godoc` server from `godoc.org` to a custom
still work, but are not supported. You can use `let g:go_version_warning = 0` private instance. Currently only `godoc -http` instances are supported.
to disable the warning. [[GH-1957]](https://github.com/fatih/vim-go/pull/1957).
[[GH-1524]](https://github.com/fatih/vim-go/pull/1524). * New setting `g:go_test_prepend_name` (off by default) to add the failing test
name to the output of `:GoTest`
[[GH-1578]](https://github.com/fatih/vim-go/pull/1578).
* Support [denite.vim](https://github.com/Shougo/denite.nvim) for `:GoDecls[Dir]`
[[GH-1604]](https://github.com/fatih/vim-go/pull/1604).
IMPROVEMENTS:
* `:GoRename` is a bit smarter when automatically pre-filling values, and what
gets pre-filled can be configured with `g:go_gorename_prefill` option.
In addition `:GoRename <Tab>` now lists some common options.
[[GH-1465]](https://github.com/fatih/vim-go/pull/1465).
* Add support for `g:go_build_tags` to the `:GoTest` family of functions.
[[GH-1562]](https://github.com/fatih/vim-go/pull/1562).
* Pass `--tests` to gometalinter when autosaving and when a custom gometalinter
command has not been set.
[[GH-1563]](https://github.com/fatih/vim-go/pull/1563).
* Do not spam messages when command is run in a directory that does not exist.
[[GH-1527]](https://github.com/fatih/vim-go/pull/1527).
* Run `syntax sync fromstart` after `:GoFmt`; this should make syntax
highlighting break slightly less often after formatting code
[[GH-1582]](https://github.com/fatih/vim-go/pull/1582).
* `:GoDescribe` doesn't require a scope anymore
[[GH-1596]](https://github.com/fatih/vim-go/pull/1596).
* Add some standard snippets for
[vim-minisnip](https://github.com/joereynolds/vim-minisnip)
[[GH-1589]](https://github.com/fatih/vim-go/pull/1589).
* `g:go_snippet_engine` now defaults to `automatic` to use the first installed
snippet engine it can find.
[[GH-1589]](https://github.com/fatih/vim-go/pull/1589).
* Make sure temporary files created for `:GoFmt` end with `.go` suffix as this
is required by some Go formatting tools
[[GH-1601]](https://github.com/fatih/vim-go/pull/1601).
BUG FIXES: BUG FIXES:
@ -23,24 +55,27 @@ BUG FIXES:
[[GH-1535]](https://github.com/fatih/vim-go/pull/1535) [[GH-1535]](https://github.com/fatih/vim-go/pull/1535)
* Fix test output processing to correctly handle panics and log statements. * Fix test output processing to correctly handle panics and log statements.
[[GH-1513]](https://github.com/fatih/vim-go/pull/1513) [[GH-1513]](https://github.com/fatih/vim-go/pull/1513)
* `:GoImpl` tab-completion would sometimes stop working
[[GH-1581]](https://github.com/fatih/vim-go/pull/1581).
* Add `g:go_highlight_function_arguments` to highlight function arguments.
[[GH-1587]](https://github.com/fatih/vim-go/pull/1587).
* Fix installation of `gocode` on MS-Windows.
[[GH-1606]](https://github.com/fatih/vim-go/pull/1606).
IMPROVEMENTS: BACKWARDS INCOMPATIBILITIES:
* `:GoRename` is a bit smarter when automatically pre-filling values, and what * Display a warning for Vim versions older than 7.4.1689. Older versions may
gets pre-filled can be configured with `g:go_gorename_prefill` option. still work, but are not supported. You can use `let g:go_version_warning = 0`
In addition `:GoRename <Tab>` now lists some common options. to disable the warning.
[[GH-1465]](https://github.com/fatih/vim-go/pull/1465). [[GH-1524]](https://github.com/fatih/vim-go/pull/1524).
* Disable `g:go_autodetect_gopath` by default. [[GH-1461]](https://github.com/fatih/vim-go/pull/1461). * `g:go_autodetect_gopath` is *disabled* by default, as support for `vendor` has
* Add support for `g:go_build_tags` to the `:GoTest` family of functions. been in Go for a while.<br>
[[GH-1562]](https://github.com/fatih/vim-go/pull/1562). Also change the implementation for `g:go_autodetect_gopath`; instead of manually
* Pass `--tests` to gometalinter when autosaving and when a custom gometalinter setting it before every command it will now be set with the `BufEnter` event,
command has not been set. and reset with the `BufLeave` event. This means that `$GOPATH` will be
[[GH-1563]](https://github.com/fatih/vim-go/pull/1563). changed for all commands run from Vim.
* Do not spam messages when command is run in a directory that does not exist. [[GH-1461]](https://github.com/fatih/vim-go/pull/1461) and
[[GH-1527]](https://github.com/fatih/vim-go/pull/1527). [[GH-1525]](https://github.com/fatih/vim-go/pull/1525).
* New setting `g:go_test_prepend_name` (off by default) to add the failing test
name to the output of `:GoTest`
[[GH-1578]](https://github.com/fatih/vim-go/pull/1578).
## 1.15 - (October 3, 2017) ## 1.15 - (October 3, 2017)
@ -191,8 +226,6 @@ BACKWARDS INCOMPATIBILITIES:
here](https://github.com/fatih/vim-go/issues/1375#issuecomment-317535953) here](https://github.com/fatih/vim-go/issues/1375#issuecomment-317535953)
[[GH-1382]](https://github.com/fatih/vim-go/pull/1382) [[GH-1382]](https://github.com/fatih/vim-go/pull/1382)
## 1.13 - (June 6, 2017) ## 1.13 - (June 6, 2017)
FEATURES: FEATURES:

View file

@ -1,10 +1,12 @@
FROM golang:1.9.1 FROM golang:1.9.2
RUN apt-get update -y && \ RUN apt-get update -y && \
apt-get install -y build-essential curl git libncurses5-dev python3-pip && \ apt-get install -y build-essential curl git libncurses5-dev python3-pip && \
apt-get clean && \ apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN pip3 install vim-vint
RUN useradd -ms /bin/bash -d /vim-go vim-go RUN useradd -ms /bin/bash -d /vim-go vim-go
USER vim-go USER vim-go
@ -14,6 +16,5 @@ WORKDIR /vim-go
RUN scripts/install-vim vim-7.4 RUN scripts/install-vim vim-7.4
RUN scripts/install-vim vim-8.0 RUN scripts/install-vim vim-8.0
RUN scripts/install-vim nvim RUN scripts/install-vim nvim
RUN pip3 install vim-vint
ENTRYPOINT ["make"] ENTRYPOINT ["make"]

View file

@ -1,16 +1,18 @@
VIMS ?= vim-7.4 vim-8.0 nvim
all: install test lint all: install test lint
install: install:
@echo "==> Installing Vims" @echo "==> Installing Vims: $(VIMS)"
@./scripts/install-vim vim-7.4 @for vim in $(VIMS); do \
@./scripts/install-vim vim-8.0 ./scripts/install-vim $$vim; \
@./scripts/install-vim nvim done
test: test:
@echo "==> Running tests" @echo "==> Running tests for $(VIMS)"
@./scripts/test vim-7.4 @for vim in $(VIMS); do \
@./scripts/test vim-8.0 ./scripts/test $$vim; \
@./scripts/test nvim done
lint: lint:
@echo "==> Running linting tools" @echo "==> Running linting tools"
@ -24,5 +26,4 @@ clean:
@echo "==> Cleaning /tmp/vim-go-test" @echo "==> Cleaning /tmp/vim-go-test"
@rm -rf /tmp/vim-go-test @rm -rf /tmp/vim-go-test
.PHONY: all test install clean lint docker .PHONY: all test install clean lint docker

View file

@ -41,8 +41,6 @@ function! go#cmd#Build(bang, ...) abort
" Vim 7.4 without async " Vim 7.4 without async
else else
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let default_makeprg = &makeprg let default_makeprg = &makeprg
let &makeprg = "go " . join(go#util#Shelllist(args), ' ') let &makeprg = "go " . join(go#util#Shelllist(args), ' ')
@ -72,7 +70,6 @@ function! go#cmd#Build(bang, ...) abort
endif endif
let &makeprg = default_makeprg let &makeprg = default_makeprg
let $GOPATH = old_gopath
endif endif
endfunction endfunction
@ -125,9 +122,6 @@ function! go#cmd#Run(bang, ...) abort
" anything. Once this is implemented we're going to make :GoRun async " anything. Once this is implemented we're going to make :GoRun async
endif endif
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
if go#util#IsWin() if go#util#IsWin()
exec '!go run ' . go#util#Shelljoin(go#tool#Files()) exec '!go run ' . go#util#Shelljoin(go#tool#Files())
if v:shell_error if v:shell_error
@ -136,7 +130,6 @@ function! go#cmd#Run(bang, ...) abort
redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None
endif endif
let $GOPATH = old_gopath
return return
endif endif
@ -165,7 +158,6 @@ function! go#cmd#Run(bang, ...) abort
call go#list#JumpToFirst(l:listtype) call go#list#JumpToFirst(l:listtype)
endif endif
let $GOPATH = old_gopath
let &makeprg = default_makeprg let &makeprg = default_makeprg
endfunction endfunction
@ -190,8 +182,6 @@ function! go#cmd#Install(bang, ...) abort
return return
endif endif
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let default_makeprg = &makeprg let default_makeprg = &makeprg
" :make expands '%' and '#' wildcards, so they must also be escaped " :make expands '%' and '#' wildcards, so they must also be escaped
@ -220,10 +210,9 @@ function! go#cmd#Install(bang, ...) abort
if !empty(errors) && !a:bang if !empty(errors) && !a:bang
call go#list#JumpToFirst(l:listtype) call go#list#JumpToFirst(l:listtype)
else else
call go#util#EchoSuccess("installed to ". go#path#Detect()) call go#util#EchoSuccess("installed to ". go#path#Default())
endif endif
let $GOPATH = old_gopath
let &makeprg = default_makeprg let &makeprg = default_makeprg
endfunction endfunction
@ -231,9 +220,6 @@ endfunction
function! go#cmd#Generate(bang, ...) abort function! go#cmd#Generate(bang, ...) abort
let default_makeprg = &makeprg let default_makeprg = &makeprg
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
" :make expands '%' and '#' wildcards, so they must also be escaped " :make expands '%' and '#' wildcards, so they must also be escaped
let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1) let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
if go#util#ShellError() != 0 if go#util#ShellError() != 0
@ -264,7 +250,6 @@ function! go#cmd#Generate(bang, ...) abort
endif endif
let &makeprg = default_makeprg let &makeprg = default_makeprg
let $GOPATH = old_gopath
endfunction endfunction
" --------------------- " ---------------------
@ -311,10 +296,6 @@ function s:cmd_job(args) abort
\ 'exit_cb': callbacks.exit_cb, \ 'exit_cb': callbacks.exit_cb,
\ } \ }
" modify GOPATH if needed
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
" pre start " pre start
let dir = getcwd() let dir = getcwd()
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
@ -325,7 +306,6 @@ function s:cmd_job(args) abort
" post start " post start
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
let $GOPATH = old_gopath
endfunction endfunction
" vim: sw=2 ts=2 et " vim: sw=2 ts=2 et

View file

@ -19,25 +19,25 @@ function! s:gocodeCommand(cmd, preargs, args) abort
return return
endif endif
" we might hit cache problems, as gocode doesn't handle well different " We might hit cache problems, as gocode doesn't handle different GOPATHs
" GOPATHS: https://github.com/nsf/gocode/issues/239 " well. See: https://github.com/nsf/gocode/issues/239
let old_gopath = $GOPATH
let old_goroot = $GOROOT let old_goroot = $GOROOT
let $GOPATH = go#path#Detect()
let $GOROOT = go#util#env("goroot") let $GOROOT = go#util#env("goroot")
let socket_type = get(g:, 'go_gocode_socket_type', s:sock_type) try
let cmd = printf('%s -sock %s %s %s %s', let socket_type = get(g:, 'go_gocode_socket_type', s:sock_type)
\ go#util#Shellescape(bin_path), let cmd = printf('%s -sock %s %s %s %s',
\ socket_type, \ go#util#Shellescape(bin_path),
\ join(a:preargs), \ socket_type,
\ go#util#Shellescape(a:cmd), \ join(a:preargs),
\ join(a:args) \ go#util#Shellescape(a:cmd),
\ ) \ join(a:args)
\ )
let result = go#util#System(cmd) let result = go#util#System(cmd)
let $GOPATH = old_gopath finally
let $GOROOT = old_goroot let $GOROOT = old_goroot
endtry
if go#util#ShellError() != 0 if go#util#ShellError() != 0
return "[\"0\", []]" return "[\"0\", []]"

View file

@ -300,10 +300,6 @@ function s:coverage_job(args)
\ 'exit_cb': callbacks.exit_cb, \ 'exit_cb': callbacks.exit_cb,
\ } \ }
" modify GOPATH if needed
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
" pre start " pre start
let dir = getcwd() let dir = getcwd()
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
@ -320,7 +316,6 @@ function s:coverage_job(args)
" post start " post start
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
let $GOPATH = old_gopath
endfunction endfunction
" coverage_callback is called when the coverage execution is finished " coverage_callback is called when the coverage execution is finished

View file

@ -2,9 +2,6 @@ let s:go_stack = []
let s:go_stack_level = 0 let s:go_stack_level = 0
function! go#def#Jump(mode) abort function! go#def#Jump(mode) abort
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
" so guru right now is slow for some people. previously we were using " so guru right now is slow for some people. previously we were using
@ -22,7 +19,6 @@ function! go#def#Jump(mode) abort
let bin_path = go#path#CheckBinPath("godef") let bin_path = go#path#CheckBinPath("godef")
if empty(bin_path) if empty(bin_path)
let $GOPATH = old_gopath
return return
endif endif
let command = printf("%s -f=%s -o=%s -t", go#util#Shellescape(bin_path), let command = printf("%s -f=%s -o=%s -t", go#util#Shellescape(bin_path),
@ -34,7 +30,6 @@ function! go#def#Jump(mode) abort
elseif bin_name == 'guru' elseif bin_name == 'guru'
let bin_path = go#path#CheckBinPath("guru") let bin_path = go#path#CheckBinPath("guru")
if empty(bin_path) if empty(bin_path)
let $GOPATH = old_gopath
return return
endif endif
@ -88,7 +83,6 @@ function! go#def#Jump(mode) abort
endif endif
call go#def#jump_to_declaration(out, a:mode, bin_name) call go#def#jump_to_declaration(out, a:mode, bin_name)
let $GOPATH = old_gopath
endfunction endfunction
function! s:jump_to_declaration_cb(mode, bin_name, job, exit_status, data) abort function! s:jump_to_declaration_cb(mode, bin_name, job, exit_status, data) abort

View file

@ -29,7 +29,19 @@ function! go#doc#OpenBrowser(...) abort
let name = out["name"] let name = out["name"]
let decl = out["decl"] let decl = out["decl"]
let godoc_url = "https://godoc.org/" . import let godoc_url = get(g:, 'go_doc_url', 'https://godoc.org')
if godoc_url isnot 'https://godoc.org'
" strip last '/' character if available
let last_char = strlen(godoc_url) - 1
if godoc_url[last_char] == '/'
let godoc_url = strpart(godoc_url, 0, last_char)
endif
" custom godoc installations expects it
let godoc_url .= "/pkg"
endif
let godoc_url .= "/" . import
if decl !~ "^package" if decl !~ "^package"
let godoc_url .= "#" . name let godoc_url .= "#" . name
endif endif

View file

@ -58,7 +58,7 @@ function! go#fmt#Format(withGoimport) abort
endif endif
" Write current unsaved buffer to a temp file " Write current unsaved buffer to a temp file
let l:tmpname = tempname() let l:tmpname = tempname() . '.go'
call writefile(go#util#GetLines(), l:tmpname) call writefile(go#util#GetLines(), l:tmpname)
if go#util#IsWin() if go#util#IsWin()
let l:tmpname = tr(l:tmpname, '\', '/') let l:tmpname = tr(l:tmpname, '\', '/')
@ -101,6 +101,9 @@ function! go#fmt#Format(withGoimport) abort
" be smart and jump to the line the new statement was added/removed " be smart and jump to the line the new statement was added/removed
call cursor(line('.') + diff_offset, current_col) call cursor(line('.') + diff_offset, current_col)
" Syntax highlighting breaks less often.
syntax sync fromstart
endfunction endfunction
" update_file updates the target file with the given formatted source " update_file updates the target file with the given formatted source
@ -158,21 +161,11 @@ function! go#fmt#run(bin_name, source, target)
return return
endif endif
if cmd[0] == "goimports"
" change GOPATH too, so goimports can pick up the correct library
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
endif
let command = join(cmd, " ") let command = join(cmd, " ")
" execute our command... " execute our command...
let out = go#util#System(command) let out = go#util#System(command)
if cmd[0] == "goimports"
let $GOPATH = old_gopath
endif
return out return out
endfunction endfunction

View file

@ -212,16 +212,12 @@ endfunc
" run_guru runs the given guru argument " run_guru runs the given guru argument
function! s:run_guru(args) abort function! s:run_guru(args) abort
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
if go#util#has_job() if go#util#has_job()
let res = s:async_guru(a:args) let res = s:async_guru(a:args)
else else
let res = s:sync_guru(a:args) let res = s:sync_guru(a:args)
endif endif
let $GOPATH = old_gopath
return res return res
endfunction endfunction
@ -366,7 +362,7 @@ function! go#guru#DescribeInfo() abort
\ 'mode': 'describe', \ 'mode': 'describe',
\ 'format': 'json', \ 'format': 'json',
\ 'selected': -1, \ 'selected': -1,
\ 'needs_scope': 1, \ 'needs_scope': 0,
\ 'custom_parse': function('s:info'), \ 'custom_parse': function('s:info'),
\ 'disable_progress': 1, \ 'disable_progress': 1,
\ } \ }

View file

@ -1,16 +1,11 @@
function! go#impl#Impl(...) abort function! go#impl#Impl(...) abort
let binpath = go#path#CheckBinPath('impl')
if empty(binpath)
return
endif
let recv = "" let recv = ""
let iface = "" let iface = ""
let interactive = 0 let interactive = 0
let pos = getpos('.') let pos = getpos('.')
if a:0 == 0 if a:0 is 0
" Interactive mode if user didn't pass any arguments. " Interactive mode if user didn't pass any arguments.
let recv = s:getReceiver() let recv = s:getReceiver()
let iface = input("vim-go: generating method stubs for interface: ") let iface = input("vim-go: generating method stubs for interface: ")
@ -19,7 +14,7 @@ function! go#impl#Impl(...) abort
call go#util#EchoError('usage: interface type is not provided') call go#util#EchoError('usage: interface type is not provided')
return return
endif endif
elseif a:0 == 1 elseif a:0 is 1
" we assume the user only passed the interface type, " we assume the user only passed the interface type,
" i.e: ':GoImpl io.Writer' " i.e: ':GoImpl io.Writer'
let recv = s:getReceiver() let recv = s:getReceiver()
@ -41,19 +36,19 @@ function! go#impl#Impl(...) abort
try try
let dirname = fnameescape(expand('%:p:h')) let dirname = fnameescape(expand('%:p:h'))
let result = go#util#System(join(go#util#Shelllist([binpath, '-dir', dirname, recv, iface], ' '))) let [result, err] = go#util#Exec(['impl', '-dir', dirname, recv, iface])
let result = substitute(result, "\n*$", "", "") let result = substitute(result, "\n*$", "", "")
if go#util#ShellError() != 0 if err
call go#util#EchoError(result) call go#util#EchoError(result)
return return
endif endif
if result ==# '' if result is# ''
return return
end end
put ='' put =''
put =result silent put =result
finally finally
call setpos('.', pos) call setpos('.', pos)
endtry endtry
@ -99,10 +94,6 @@ function! s:root_dirs() abort
endif endif
let paths = map(split(go#util#env("gopath"), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')") let paths = map(split(go#util#env("gopath"), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')")
if go#util#ShellError()
return []
endif
if !empty(filter(paths, 'isdirectory(v:val)')) if !empty(filter(paths, 'isdirectory(v:val)'))
call extend(dirs, paths) call extend(dirs, paths)
endif endif
@ -120,11 +111,12 @@ function! s:go_packages(dirs) abort
endfunction endfunction
function! s:interface_list(pkg) abort function! s:interface_list(pkg) abort
let contents = split(go#util#System('go doc ' . a:pkg), "\n") let [contents, err] = go#util#Exec(['go', 'doc', a:pkg])
if go#util#ShellError() if err
return [] return []
endif endif
let contents = split(contents, "\n")
call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''') call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''')
return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')') return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')')
endfunction endfunction

View file

@ -0,0 +1,37 @@
func! Test_impl() abort
try
let l:tmp = gotest#write_file('a/a.go', [
\ 'package a',
\ '',
\ ''])
call go#impl#Impl('r', 'reader', 'io.Reader')
call gotest#assert_buffer(1, [
\ 'func (r reader) Read(p []byte) (n int, err error) {',
\ ' panic("not implemented")',
\ '}'])
finally
call delete(l:tmp, 'rf')
endtry
endfunc
func! Test_impl_get() abort
try
let l:tmp = gotest#write_file('a/a.go', [
\ 'package a',
\ '',
\ 'type reader struct {}'])
call go#impl#Impl('io.Reader')
call gotest#assert_buffer(0, [
\ 'package a',
\ '',
\ 'type reader struct {}',
\ '',
\ 'func (r *reader) Read(p []byte) (n int, err error) {',
\ ' panic("not implemented")',
\ '}'])
finally
call delete(l:tmp, 'rf')
endtry
endfunc

View file

@ -33,10 +33,9 @@ function! go#jobcontrol#RemoveHandler(id) abort
unlet s:handlers[a:id] unlet s:handlers[a:id]
endfunction endfunction
" spawn spawns a go subcommand with the name and arguments with jobstart. Once " spawn spawns a go subcommand with the name and arguments with jobstart. Once a
" a job is started a reference will be stored inside s:jobs. spawn changes the " job is started a reference will be stored inside s:jobs. The job is started
" GOPATH when g:go_autodetect_gopath is enabled. The job is started inside the " inside the current files folder.
" current files folder.
function! s:spawn(bang, desc, for, args) abort function! s:spawn(bang, desc, for, args) abort
let status_type = a:args[0] let status_type = a:args[0]
let status_dir = expand('%:p:h') let status_dir = expand('%:p:h')
@ -65,10 +64,6 @@ function! s:spawn(bang, desc, for, args) abort
\ 'for' : a:for, \ 'for' : a:for,
\ } \ }
" modify GOPATH if needed
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
" execute go build in the files directory " execute go build in the files directory
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
@ -94,9 +89,6 @@ function! s:spawn(bang, desc, for, args) abort
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
" restore back GOPATH
let $GOPATH = old_gopath
return job return job
endfunction endfunction

View file

@ -1,11 +1,8 @@
function! go#keyify#Keyify() function! go#keyify#Keyify()
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let bin_path = go#path#CheckBinPath("keyify") let bin_path = go#path#CheckBinPath("keyify")
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
if empty(bin_path) || !exists('*json_decode') if empty(bin_path) || !exists('*json_decode')
let $GOPATH = old_gopath
return return
endif endif
@ -18,7 +15,6 @@ function! go#keyify#Keyify()
" We want to output the error message in case the result isn't a JSON " We want to output the error message in case the result isn't a JSON
if type(result) != type({}) if type(result) != type({})
call go#util#EchoError(s:chomp(output)) call go#util#EchoError(s:chomp(output))
let $GOPATH = old_gopath
return return
endif endif
@ -51,7 +47,6 @@ function! go#keyify#Keyify()
call setpos("'<", vis_start) call setpos("'<", vis_start)
call setpos("'>", vis_end) call setpos("'>", vis_end)
let $GOPATH = old_gopath
endfunction endfunction
function! s:chomp(string) function! s:chomp(string)

View file

@ -46,7 +46,7 @@ function! go#package#Paths() abort
let dirs += [s:goroot] let dirs += [s:goroot]
endif endif
let workspaces = split(go#path#Detect(), go#util#PathListSep()) let workspaces = split(go#path#Default(), go#util#PathListSep())
if workspaces != [] if workspaces != []
let dirs += workspaces let dirs += workspaces
endif endif

View file

@ -4,14 +4,14 @@
" :GoPath is used " :GoPath is used
let s:initial_go_path = "" let s:initial_go_path = ""
" GoPath sets or returns the current GOPATH. If no arguments are passed it " GoPath sets or echos the current GOPATH. If no arguments are passed it
" echoes the current GOPATH, if an argument is passed it replaces the current " echoes the current GOPATH, if an argument is passed it replaces the current
" GOPATH with it. If two double quotes are passed (the empty string in go), " GOPATH with it. If two double quotes are passed (the empty string in go),
" it'll clear the GOPATH and will restore to the initial GOPATH. " it'll clear the GOPATH and will restore to the initial GOPATH.
function! go#path#GoPath(...) abort function! go#path#GoPath(...) abort
" no argument, show GOPATH " no argument, show GOPATH
if len(a:000) == 0 if len(a:000) == 0
echo go#path#Detect() echo go#path#Default()
return return
endif endif
@ -72,11 +72,6 @@ endfunction
function! go#path#Detect() abort function! go#path#Detect() abort
let gopath = go#path#Default() let gopath = go#path#Default()
" don't lookup for godeps if autodetect is disabled.
if !get(g:, "go_autodetect_gopath", 0)
return gopath
endif
let current_dir = fnameescape(expand('%:p:h')) let current_dir = fnameescape(expand('%:p:h'))
" TODO(arslan): this should be changed so folders or files should be " TODO(arslan): this should be changed so folders or files should be
@ -124,7 +119,6 @@ function! go#path#Detect() abort
return gopath return gopath
endfunction endfunction
" BinPath returns the binary path of installed go tools. " BinPath returns the binary path of installed go tools.
function! go#path#BinPath() abort function! go#path#BinPath() abort
let bin_path = "" let bin_path = ""

View file

@ -100,10 +100,6 @@ function s:rename_job(args)
\ 'exit_cb': funcref("s:exit_cb"), \ 'exit_cb': funcref("s:exit_cb"),
\ } \ }
" modify GOPATH if needed
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
call go#statusline#Update(status_dir, { call go#statusline#Update(status_dir, {
\ 'desc': "current status", \ 'desc': "current status",
\ 'type': "gorename", \ 'type': "gorename",
@ -111,8 +107,6 @@ function s:rename_job(args)
\}) \})
call job_start(a:args.cmd, start_options) call job_start(a:args.cmd, start_options)
let $GOPATH = old_gopath
endfunction endfunction
function s:parse_errors(exit_val, bang, out) function s:parse_errors(exit_val, bang, out)

View file

@ -18,10 +18,6 @@ function! go#term#newmode(bang, cmd, mode) abort
let mode = g:go_term_mode let mode = g:go_term_mode
endif endif
" modify GOPATH if needed
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
" execute go build in the files directory " execute go build in the files directory
let l:winnr = winnr() let l:winnr = winnr()
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
@ -54,9 +50,6 @@ function! go#term#newmode(bang, cmd, mode) abort
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
" restore back GOPATH
let $GOPATH = old_gopath
let job.id = id let job.id = id
let job.cmd = a:cmd let job.cmd = a:cmd
startinsert startinsert

View file

@ -207,10 +207,6 @@ function s:test_job(args) abort
\ 'exit_cb': funcref("s:exit_cb"), \ 'exit_cb': funcref("s:exit_cb"),
\ } \ }
" modify GOPATH if needed
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
" pre start " pre start
let dir = getcwd() let dir = getcwd()
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
@ -221,7 +217,6 @@ function s:test_job(args) abort
" post start " post start
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
let $GOPATH = old_gopath
endfunction endfunction
" show_errors parses the given list of lines of a 'go test' output and returns " show_errors parses the given list of lines of a 'go test' output and returns
@ -295,20 +290,27 @@ function! s:parse_errors(lines) abort
" '\t/usr/local/go/src/time.go:1313 +0x5d' " '\t/usr/local/go/src/time.go:1313 +0x5d'
let tokens = matchlist(line, '^\t\+\(.\{-}\.go\):\(\d\+\) \(+0x.*\)') let tokens = matchlist(line, '^\t\+\(.\{-}\.go\):\(\d\+\) \(+0x.*\)')
else else
" matches lines produced by `go test`. All lines produced by `go test` " Matches lines produced by `go test`. When the test binary cannot be
" that we're interested in start with zero or more spaces (increasing " compiled, the errors will be a filename, followed by a colon, followed
" depth of subtests is represented by a similar increase in the number " by the line number, followed by another colon, a space, and then the
" of spaces at the start of output lines. Top level tests start with " compiler error.
" zero leading spaces). Lines that indicate test status (e.g. RUN, FAIL, " e.g.:
" PASS) start after the spaces. Lines that indicate test failure " 'quux.go:123: undefined: foo'
" location or test log message location (e.g. "testing.T".Log) begin "
" with the appropriate number of spaces for the current test level, " When the test binary can be successfully compiled, but tests fail, all
" followed by a tab, a filename , a colon, the line number, another " lines produced by `go test` that we're interested in start with zero
" colon, a space, and the failure or log message. " or more spaces (increasing depth of subtests is represented by a
" similar increase in the number of spaces at the start of output lines.
" Top level tests start with zero leading spaces). Lines that indicate
" test status (e.g. RUN, FAIL, PASS) start after the spaces. Lines that
" indicate test failure location or test log message location (e.g.
" "testing.T".Log) begin with the appropriate number of spaces for the
" current test level, followed by a tab, a filename , a colon, the line
" number, another colon, a space, and the failure or log message.
" "
" e.g.: " e.g.:
" '\ttime_test.go:30: Likely problem: the time zone files have not been installed.' " '\ttime_test.go:30: Likely problem: the time zone files have not been installed.'
let tokens = matchlist(line, '^ *\t\+\(.\{-}\.go\):\(\d\+\):\s*\(.*\)') let tokens = matchlist(line, '^\%( *\t\+\)\?\(.\{-}\.go\):\(\d\+\):\s*\(.*\)')
endif endif
if !empty(tokens) " Check whether the line may refer to a file. if !empty(tokens) " Check whether the line may refer to a file.

View file

@ -174,11 +174,6 @@ function! go#tool#ExecuteInDir(cmd) abort
return '' return ''
endif endif
let old_gopath = $GOPATH
let old_goroot = $GOROOT
let $GOPATH = go#path#Detect()
let $GOROOT = go#util#env("goroot")
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd() let dir = getcwd()
try try
@ -187,9 +182,6 @@ function! go#tool#ExecuteInDir(cmd) abort
finally finally
execute cd . fnameescape(dir) execute cd . fnameescape(dir)
endtry endtry
let $GOROOT = old_goroot
let $GOPATH = old_gopath
return out return out
endfunction endfunction

View file

@ -15,7 +15,7 @@ fun! gotest#write_file(path, contents) abort
call mkdir(fnamemodify(l:full_path, ':h'), 'p') call mkdir(fnamemodify(l:full_path, ':h'), 'p')
call writefile(a:contents, l:full_path) call writefile(a:contents, l:full_path)
exe 'cd ' . l:dir . '/src' exe 'cd ' . l:dir . '/src'
silent exe 'e ' . a:path silent exe 'e! ' . a:path
" Set cursor. " Set cursor.
let l:lnum = 1 let l:lnum = 1

View file

@ -57,7 +57,8 @@ tools developed by the Go community to provide a seamless Vim experience.
* Advanced source analysis tools utilizing `guru`, such as |:GoImplements|, * Advanced source analysis tools utilizing `guru`, such as |:GoImplements|,
|:GoCallees|, and |:GoReferrers|. |:GoCallees|, and |:GoReferrers|.
* Precise type-safe renaming of identifiers with |:GoRename|. * Precise type-safe renaming of identifiers with |:GoRename|.
* Integrated and improved snippets, supporting `ultisnips` or `neosnippet`. * Integrated and improved snippets, supporting `ultisnips`, `neosnippet`,
and `vim-minisnip`.
* Share your current code to play.golang.org with |:GoPlay|. * Share your current code to play.golang.org with |:GoPlay|.
* On-the-fly information about the word under the cursor. Plug it into your * On-the-fly information about the word under the cursor. Plug it into your
custom Vim function. custom Vim function.
@ -136,7 +137,8 @@ The following plugins are supported for use with vim-go:
* Snippets: * Snippets:
https://github.com/Shougo/neosnippet.vim or https://github.com/Shougo/neosnippet.vim or
https://github.com/SirVer/ultisnips https://github.com/SirVer/ultisnips or
https://github.com/joereynolds/vim-minisnip
* For a better documentation viewer check out: * For a better documentation viewer check out:
https://github.com/garyburd/go-explorer https://github.com/garyburd/go-explorer
@ -147,7 +149,8 @@ The following plugins are supported for use with vim-go:
* Interactive |:GoDecls| and |:GoDeclsDir|: * Interactive |:GoDecls| and |:GoDeclsDir|:
https://github.com/ctrlpvim/ctrlp.vim or https://github.com/ctrlpvim/ctrlp.vim or
https://github.com/junegunn/fzf.vim or https://github.com/junegunn/fzf.vim or
https://github.com/Shougo/unite.vim https://github.com/Shougo/unite.vim or
https://github.com/Shougo/denite.nvim
============================================================================== ==============================================================================
COMMANDS *go-commands* COMMANDS *go-commands*
@ -197,7 +200,8 @@ COMMANDS *go-commands*
:GoDocBrowser [word] :GoDocBrowser [word]
Open the relevant GoDoc in browser for either the word[s] passed to the Open the relevant GoDoc in browser for either the word[s] passed to the
command or by default, the word under the cursor. command or by default, the word under the cursor. By default it opens the
documentation in 'https://godoc.org'. To change it see |'g:go_doc_url'|.
*:GoFmt* *:GoFmt*
:GoFmt :GoFmt
@ -684,7 +688,7 @@ CTRL-t
Requires `ctrlp.vim` or `fzf`; it will autodetect the plugin if installed, Requires `ctrlp.vim` or `fzf`; it will autodetect the plugin if installed,
but you can use |'g:go_decls_mode'| to force using one or the other. but you can use |'g:go_decls_mode'| to force using one or the other.
By default `type` and `func` declarations are shown. This can be changed By default `type` and `func` declarations are shown. This can be changed
via |'g:go_decls_includes'|. Also see |unite-decls|. via |'g:go_decls_includes'|. Also see |unite-decls|, |denite-decls|.
*:GoDeclsDir* *:GoDeclsDir*
:GoDeclsDir [dir] :GoDeclsDir [dir]
@ -693,20 +697,27 @@ CTRL-t
[dir] is given it parses the given directory. [dir] is given it parses the given directory.
*unite-decls* *unite-decls*
:Unite decls[:file or dir] *denite-decls*
:Unite decls[:path]
:Denite decls[:path]
Only enabled if `unite.vim` is installed. Show declarations for all Only enabled if `unite.vim` or `denite.nvim` is installed. Show
functions and types on the current file or directory. If [:file or dir] declarations for all functions and types on the current file or directory
is non empty, it parses the given one. or for [path] if given.
Note: `denite.nvim` requires NeoVim or Vim 8 with |:python3| enabled.
> >
" show declarations on the parent directory of the current file " show declarations on the parent directory of the current file
:Unite decls :Unite decls
:Denite decls
" show declarations on the file " show declarations in the file.
:Unite decls:foo/bar.go :Unite decls:foo/bar.go
:Denite decls:foo/bar.go
" show declarations on the directory " show declarations in the directory "foo".
:Unite decls:foo :Unite decls:foo
:Denite decls:foo
< <
*:GoImpl* *:GoImpl*
:GoImpl [receiver] [interface] :GoImpl [receiver] [interface]
@ -1094,9 +1105,9 @@ SETTINGS *go-settings*
*'g:go_test_prepend_name'* *'g:go_test_prepend_name'*
Prepend the name of the failed test to each test message generated by a failed Prepend the name of the failed test to each test message generated by a failed
test. By default it is disabled. test. By default it is disabled.
> >
let g:go_test_prepend_name = 0 let g:go_test_prepend_name = 0
< <
*'g:go_test_timeout'* *'g:go_test_timeout'*
@ -1236,6 +1247,14 @@ Maximum height for the GoDoc window created with |:GoDoc|. Default is 20. >
let g:go_doc_max_height = 20 let g:go_doc_max_height = 20
< <
*'g:go_doc_url'*
godoc server URL used when |:GoDocBrowser| is used. Change if you want to use
a private internal service. Default is 'https://godoc.org'.
>
let g:go_doc_url = 'https://godoc.org'
<
*'g:go_def_mode'* *'g:go_def_mode'*
Use this option to define the command to be used for |:GoDef|. By default Use this option to define the command to be used for |:GoDef|. By default
@ -1278,10 +1297,16 @@ Use this option to change default path for vim-go tools when using
< <
*'g:go_snippet_engine'* *'g:go_snippet_engine'*
Use this option to define the default snippet engine. By default "ultisnips" Define the snippet engine to use. The default is to auto-detect one. Valid
is used. Use "neosnippet" for neosnippet.vim: > values are:
let g:go_snippet_engine = "ultisnips" automatic Automatically detect a snippet engine.
ultisnips https://github.com/SirVer/ultisnips
neosnippet https://github.com/Shougo/neosnippet.vim
minisnip https://github.com/joereynolds/vim-minisnip
Note: the original at KeyboardFire/vim-minisnip won't work.
>
let g:go_snippet_engine = "automatic"
< <
*'g:go_get_update'* *'g:go_get_update'*
@ -1315,13 +1340,12 @@ remove build tags. By default it's not set.
< <
*'g:go_autodetect_gopath'* *'g:go_autodetect_gopath'*
Automatically modifies GOPATH for certain directory structures, such as for Automatically modify GOPATH for certain directory structures, such as for
the tool `godep` which has his own dependencies via the `Godeps` folder. What the `godep` tool which stores dependencies in the `Godeps` folder. What this
this means is that all tools are now working with the newly modified GOPATH. means is that all tools are now working with the newly modified GOPATH. So
So |:GoDef| for example jumps to the source inside the `Godeps` (vendored) |:GoDef| for example jumps to the source inside the `Godeps` (vendored)
source. Currently `godep` and `gb` is supported, in the near future more tool source. Currently `godep` and `gb` are supported. By default it's disabled.
supports will be added. By default it's disabled. > >
let g:go_autodetect_gopath = 0 let g:go_autodetect_gopath = 0
< <
*'g:go_textobj_enabled'* *'g:go_textobj_enabled'*
@ -1565,10 +1589,10 @@ By default the template file specified by |'g:go_template_file'| is used.
< <
*'g:go_decls_includes'* *'g:go_decls_includes'*
Only useful if `ctrlp.vim`, `unite.vim` or `fzf` are installed. This sets Only useful if `ctrlp.vim`, `unite.vim`, `denite.nvim` or `fzf` are installed.
which declarations to show for |:GoDecls| (`ctrp.vim`) and |unite-decls| This sets which declarations to show for |:GoDecls| (`ctrp.vim`),
(`unite.vim`). It is a Comma delimited list Possible options are: |unite-decls| (`unite.vim`) and |denite-decls| (`denite.nvim`). It is a Comma
{func,type}. The default is: > delimited list. Possible options are: {func,type}. The default is: >
let g:go_decls_includes = 'func,type' let g:go_decls_includes = 'func,type'
< <
@ -1704,6 +1728,14 @@ Highlight operators such as `:=` , `==`, `-=`, etc.
Highlight function names. Highlight function names.
> >
let g:go_highlight_functions = 0 let g:go_highlight_functions = 0
<
*'g:go_highlight_function_arguments'*
Highlight the variable names in arguments and return values in function
declarations. Setting this implies the functionality from
|'g:go_highlight_functions'|.
>
let g:go_highlight_function_arguments = 0
< <
*'g:go_highlight_methods'* *'g:go_highlight_methods'*

View file

@ -87,7 +87,7 @@ command! -nargs=? -complete=file GoDecls call go#decls#Decls(0, <q-args>)
command! -nargs=? -complete=dir GoDeclsDir call go#decls#Decls(1, <q-args>) command! -nargs=? -complete=dir GoDeclsDir call go#decls#Decls(1, <q-args>)
" -- impl " -- impl
command! -nargs=* -buffer -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl(<f-args>) command! -nargs=* -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl(<f-args>)
" -- template " -- template
command! -nargs=0 GoTemplateAutoCreateToggle call go#template#ToggleAutoCreate() command! -nargs=0 GoTemplateAutoCreateToggle call go#template#ToggleAutoCreate()

View file

@ -3,13 +3,8 @@ if exists("g:go_loaded_gosnippets")
endif endif
let g:go_loaded_gosnippets = 1 let g:go_loaded_gosnippets = 1
" by default UltiSnips function! s:GoUltiSnips() abort
if !exists("g:go_snippet_engine") if get(g:, 'did_plugin_ultisnips') isnot 1
let g:go_snippet_engine = "ultisnips"
endif
function! s:GoUltiSnips()
if globpath(&rtp, 'plugin/UltiSnips.vim') == ""
return return
endif endif
@ -20,29 +15,53 @@ function! s:GoUltiSnips()
endif endif
endfunction endfunction
function! s:GoNeosnippet() function! s:GoNeosnippet() abort
if globpath(&rtp, 'plugin/neosnippet.vim') == "" if get(g:, 'loaded_neosnippet') isnot 1
return return
endif endif
let g:neosnippet#enable_snipmate_compatibility = 1 let g:neosnippet#enable_snipmate_compatibility = 1
let gosnippets_dir = globpath(&rtp, 'gosnippets/snippets') let l:gosnippets_dir = globpath(&rtp, 'gosnippets/snippets')
if type(g:neosnippet#snippets_directory) == type([]) if type(g:neosnippet#snippets_directory) == type([])
let g:neosnippet#snippets_directory += [gosnippets_dir] let g:neosnippet#snippets_directory += [l:gosnippets_dir]
elseif type(g:neosnippet#snippets_directory) == type("") elseif type(g:neosnippet#snippets_directory) == type("")
if strlen(g:neosnippet#snippets_directory) > 0 if strlen(g:neosnippet#snippets_directory) > 0
let g:neosnippet#snippets_directory = g:neosnippet#snippets_directory . "," . gosnippets_dir let g:neosnippet#snippets_directory = g:neosnippet#snippets_directory . "," . l:gosnippets_dir
else else
let g:neosnippet#snippets_directory = gosnippets_dir let g:neosnippet#snippets_directory = l:gosnippets_dir
endif endif
endif endif
endfunction endfunction
if g:go_snippet_engine == "ultisnips" function! s:GoMinisnip() abort
if get(g:, 'loaded_minisnip') isnot 1
return
endif
if exists('g:minisnip_dir')
let g:minisnip_dir .= ':' . globpath(&rtp, 'gosnippets/minisnip')
else
let g:minisnip_dir = globpath(&rtp, 'gosnippets/minisnip')
endif
endfunction
let s:engine = get(g:, 'go_snippet_engine', 'automatic')
if s:engine is? "automatic"
if get(g:, 'did_plugin_ultisnips') is 1
call s:GoUltiSnips()
elseif get(g:, 'loaded_neosnippet') is 1
call s:GoNeosnippet()
elseif get(g:, 'loaded_minisnip') is 1
call s:GoMinisnip()
endif
elseif s:engine is? "ultisnips"
call s:GoUltiSnips() call s:GoUltiSnips()
elseif g:go_snippet_engine == "neosnippet" elseif s:engine is? "neosnippet"
call s:GoNeosnippet() call s:GoNeosnippet()
elseif s:engine is? "minisnip"
call s:GoMinisnip()
endif endif
" vim: sw=2 ts=2 et " vim: sw=2 ts=2 et

View file

@ -0,0 +1,3 @@
if !reflect.DeepEqual({{+got+}}, {{+want+}}) {
t.Errorf("\ngot: %#v\nwant: %#v\n", {{+~\~2+}}, {{+~\~2+}})
}

View file

@ -0,0 +1,3 @@
if err != nil {
return {{+err+}}
}

View file

@ -0,0 +1,4 @@
if err != nil {
t.Fatal(err)
}
{{++}}

View file

@ -0,0 +1,3 @@
if err != nil {
return errors.Wrap(err, "{{++}}")
}

View file

@ -0,0 +1,3 @@
// {{++}}
func {{+~\~1+}}() {
}

View file

@ -0,0 +1 @@
fmt.Printf("%#v\n", {{++}})

View file

@ -0,0 +1,3 @@
for i := 0; i < {{++}}; i++ {
{{++}}
}

View file

@ -0,0 +1,2 @@
// Package {{+~expand('%:p:h:t')+}} {{++}}
package {{+~\~2+}}

View file

@ -0,0 +1,2 @@
fmt.Sprintf("{{++}}", {{++}})

View file

@ -146,7 +146,7 @@ function! s:GoInstallBinaries(updateBinaries, ...)
echo "vim-go: ". binary ." not found. Installing ". importPath . " to folder " . go_bin_path echo "vim-go: ". binary ." not found. Installing ". importPath . " to folder " . go_bin_path
endif endif
let out = go#util#System(cmd . l:goGetFlags . shellescape(importPath)) let out = go#util#System(printf('%s %s %s', cmd, l:goGetFlags, shellescape(importPath)))
if go#util#ShellError() != 0 if go#util#ShellError() != 0
echom "Error installing " . importPath . ": " . out echom "Error installing " . importPath . ": " . out
endif endif
@ -260,6 +260,19 @@ augroup vim-go
" in the same window doesn't highlight the most recently matched " in the same window doesn't highlight the most recently matched
" identifier's positions. " identifier's positions.
autocmd BufWinEnter *.go call go#guru#ClearSameIds() autocmd BufWinEnter *.go call go#guru#ClearSameIds()
augroup END
autocmd BufEnter *.go
\ if get(g:, 'go_autodetect_gopath', 0) && !exists('b:old_gopath')
\| let b:old_gopath = exists('$GOPATH') ? $GOPATH : -1
\| let $GOPATH = go#path#Detect()
\| endif
autocmd BufLeave *.go
\ if exists('b:old_gopath')
\| if b:old_gopath isnot -1
\| let $GOPATH = b:old_gopath
\| endif
\| unlet b:old_gopath
\| endif
augroup end
" vim: sw=2 ts=2 et " vim: sw=2 ts=2 et

View file

@ -0,0 +1,93 @@
# ============================================================================
# FILE: decls.py
# AUTHOR: delphinus <delphinus@remora.cx>
# License: MIT license
# ============================================================================
import os
import subprocess
import json
import denite.util
from .base import Base
DECLS_SYNTAX_HIGHLIGHT = [
{'name': 'FilePath', 're': r'[^:]*\ze:', 'link': 'Comment'},
{'name': 'Line', 're': r'\d\+\ze :', 'link': 'LineNr'},
{'name': 'WholeFunction', 're': r'\vfunc %(\([^)]+\) )?[^(]+'},
{'name': 'Function', 'parent': 'WholeFunction',
're': r'\S\+\ze(', 'link': 'Function'},
{'name': 'WholeType', 're': r'type \S\+'},
{'name': 'Type', 'parent': 'WholeType',
're': r'\v( )@<=\S+', 'link': 'Type'},
{'name': 'Separator', 're': r':', 'conceal': True},
{'name': 'SeparatorFunction', 'parent': 'WholeFunction',
're': r'func ', 'conceal': True},
{'name': 'SeparatorType', 'parent': 'WholeType',
're': r'type ', 'conceal': True},
]
class Source(Base):
def __init__(self, vim):
super().__init__(vim)
self.name = 'decls'
self.kind = 'file'
def gather_candidates(self, context):
bin_path = self.vim.call('go#path#CheckBinPath', 'motion')
if bin_path == '':
return []
expand = context['args'][0] if context['args'] else '%:p:h'
target = self.vim.funcs.expand(expand)
if os.path.isdir(target):
mode = 'dir'
elif os.path.isfile(target):
mode = 'file'
else:
return []
if self.vim.funcs.exists('g:go_decls_includes'):
include = self.vim.eval('g:go_decls_includes')
else:
include = 'func,type'
command = [bin_path, '-mode', 'decls', '-include', include,
'-' + mode, target]
try:
cmd = subprocess.run(command, stdout=subprocess.PIPE, check=True)
except subprocess.CalledProcessError as err:
denite.util.error(self.vim,
'command returned invalid response: ' + str(err))
return []
txt = cmd.stdout.decode('utf-8')
output = json.loads(txt, encoding='utf-8')
def make_candidates(row):
name = self.vim.funcs.fnamemodify(row['filename'], ':~:.')
return {
'word': '{0} :{1} :{2}'.format(name, row['line'], row['full']),
'action__path': row['filename'],
'action__line': row['line'],
'action__col': row['col'],
}
return list(map(make_candidates, output['decls']))
def highlight(self):
for syn in DECLS_SYNTAX_HIGHLIGHT:
containedin = self.syntax_name
containedin += '_' + syn['parent'] if 'parent' in syn else ''
conceal = ' conceal' if 'conceal' in syn else ''
self.vim.command(
'syntax match {0}_{1} /{2}/ contained containedin={3}{4}'
.format(self.syntax_name, syn['name'], syn['re'],
containedin, conceal))
if 'link' in syn:
self.vim.command('highlight default link {0}_{1} {2}'.format(
self.syntax_name, syn['name'], syn['link']))

View file

@ -7,6 +7,14 @@ set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd) vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir" cd "$vimgodir"
coverage=0
while getopts "c" option; do
case "$option" in
c) coverage=1; ;;
esac
done
shift $((OPTIND - 1))
if [ -z "${1:-}" ]; then if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'" echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-7.4', 'vim-8.0', or 'nvim'." echo "First argument must be 'vim-7.4', 'vim-8.0', or 'nvim'."
@ -23,11 +31,20 @@ if [ ! -f "$dir/bin/vim" ]; then
exit 1 exit 1
fi fi
$dir/bin/vim --noplugin -u NONE -N \ if [ $coverage -eq 1 ]; then
+"set shm+=WAFI rtp=$dir/share/vim/vimgo packpath=$dir/share/vim/vimgo,$vimgodir" \ covimerage -q run --report-file /tmp/vim-go-test/cov-profile.txt --append \
+'filetype plugin indent on' \ $dir/bin/vim --noplugin -u NONE -N \
+'packloadall!' \ +"set shm+=WAFI rtp=$dir/share/vim/vimgo packpath=$dir/share/vim/vimgo,$vimgodir" \
"$@" +'filetype plugin indent on' \
+'packloadall!' \
"$@"
else
$dir/bin/vim --noplugin -u NONE -N \
+"set shm+=WAFI rtp=$dir/share/vim/vimgo packpath=$dir/share/vim/vimgo,$vimgodir" \
+'filetype plugin indent on' \
+'packloadall!' \
"$@"
fi
# vim:ts=2:sts=2:sw=2:et # vim:ts=2:sts=2:sw=2:et

View file

@ -11,6 +11,9 @@ let s:fail = 0
let s:done = 0 let s:done = 0
let s:logs = [] let s:logs = []
let s:gopath = $GOPATH let s:gopath = $GOPATH
if !exists('g:test_verbose')
let g:test_verbose = 0
endif
" Source the passed test file. " Source the passed test file.
source % source %
@ -38,8 +41,14 @@ for s:test in sort(s:tests)
endif endif
let s:started = reltime() let s:started = reltime()
call add(s:logs, printf("=== RUN %s", s:test[:-3])) if g:test_verbose is 1
exe 'call ' . s:test call add(s:logs, printf("=== RUN %s", s:test[:-3]))
endif
try
exe 'call ' . s:test
catch
let v:errors += [v:exception]
endtry
" Restore GOPATH after each test. " Restore GOPATH after each test.
let $GOPATH = s:gopath let $GOPATH = s:gopath
@ -55,7 +64,9 @@ for s:test in sort(s:tests)
" Reset so we can capture failures of the next test. " Reset so we can capture failures of the next test.
let v:errors = [] let v:errors = []
else else
call add(s:logs, printf("--- PASS %s (%ss)", s:test[:-3], s:elapsed_time)) if g:test_verbose is 1
call add(s:logs, printf("--- PASS %s (%ss)", s:test[:-3], s:elapsed_time))
endif
endif endif
endfor endfor
@ -76,9 +87,14 @@ let s:logs = s:logs + filter(split(s:mess, "\n"), 'v:val !~ "^Messages maintaine
" Also store all internal messages from s:logs as well. " Also store all internal messages from s:logs as well.
silent! split /tmp/vim-go-test/test.tmp silent! split /tmp/vim-go-test/test.tmp
call append(line('$'), s:logs) call append(line('$'), s:logs)
call append(line('$'), printf("%s%s %s / %s tests", call append(line('$'), printf("%s %s %s %ss / %s tests",
\ (s:fail > 0 ? 'FAIL ' : 'ok '), \ (s:fail > 0 ? 'FAIL' : 'ok '),
\ s:testfile, s:total_elapsed_time, s:done)) \ s:testfile,
\ repeat(' ', 25 - len(s:testfile)),
\ s:total_elapsed_time, s:done))
if g:test_verbose is 0
silent :g/^$/d
endif
silent! write silent! write
" Our work here is done. " Our work here is done.

View file

@ -7,6 +7,35 @@ set -euC
vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd) vimgodir=$(cd -P "$(dirname "$0")/.." > /dev/null && pwd)
cd "$vimgodir" cd "$vimgodir"
_usage() {
echo "Usage: ${0##*/} [-hvc] [-r file] vim_version"
echo
echo "Options:"
echo " -h Show this help"
echo " -v Enable verbose output"
echo " -r Run only the tests from this file"
echo " -c Generate and submit code coverage reports"
echo
}
verbose=0
run=""
coverage=""
while getopts "hvcr:" option; do
case "$option" in
h) _usage; exit 0 ;;
v) verbose=1; ;;
r) run=$OPTARG ;;
c) coverage="-c" ;;
*)
echo "error: unknown option '$option'"
_usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
### Setup Vim and other dependencies. ### Setup Vim and other dependencies.
##################################### #####################################
if [ -z "${1:-}" ]; then if [ -z "${1:-}" ]; then
@ -21,20 +50,33 @@ export GOPATH=$vimdir
export PATH=${GOPATH}/bin:$PATH export PATH=${GOPATH}/bin:$PATH
if [ ! -f "$vimdir/bin/vim" ]; then if [ ! -f "$vimdir/bin/vim" ]; then
echo "$vimdir/bin/vim doesn't exist; did you install it with the install-vim script?" echo "$vimdir/bin/vim doesn't exist; did you install it with the install-vim script?"
exit 1 exit 1
fi fi
### Run tests. ### Run tests.
############## ##############
# Clean stale log file. # Clean stale log file.
[ -f '/tmp/vim-go-test/test.log' ] && rm '/tmp/vim-go-test/test.log' [ -f '/tmp/vim-go-test/test.log' ] && rm '/tmp/vim-go-test/test.log'
[ -f '/tmp/vim-go-test/FAILED' ] && rm '/tmp/vim-go-test/FAILED' [ -f '/tmp/vim-go-test/FAILED' ] && rm '/tmp/vim-go-test/FAILED'
[ -f '/tmp/vim-go-test/cov-profile.txt' ] && rm '/tmp/vim-go-test/cov-profile.txt'
[ -f '/tmp/vim-go-test/cov-report.txt' ] && rm '/tmp/vim-go-test/cov-report.txt'
# Run the actual tests. # Run the actual tests.
fail=0 find "$vimgodir" -name '*_test.vim' | while read test_file; do
for test_file in "$vimgodir"/autoload/go/*_test.vim; do [ -n "$run" -a "$(basename "$test_file")" != "$run" ] && continue
"$vimgodir/scripts/run-vim" $vim -e +"silent e $test_file" -S ./scripts/runtest.vim
"$vimgodir/scripts/run-vim" $coverage $vim -e \
+"silent e $test_file" \
+"let g:test_verbose=$verbose" \
-S ./scripts/runtest.vim || (
# If Vim exits with non-0 it's almost certainly a bug in the test runner;
# should very rarely happen in normal usage.
echo 'test runner failure'
cat '/tmp/vim-go-test/test.tmp'
rm '/tmp/vim-go-test/test.tmp'
exit 5
)
# Append logs # Append logs
cat '/tmp/vim-go-test/test.tmp' | tee '/tmp/vim-go-test/test.log' cat '/tmp/vim-go-test/test.tmp' | tee '/tmp/vim-go-test/test.log'
@ -43,9 +85,17 @@ done
echo echo
if [ -f "/tmp/vim-go-test/FAILED" ]; then if [ -f "/tmp/vim-go-test/FAILED" ]; then
echo 2>&1 "Some tests FAILED" echo 2>&1 "Some ($vim) tests FAILED"
exit 1 exit 1
fi fi
echo 2>&1 "All tests PASSED" echo 2>&1 "All ($vim) tests PASSED"
# Submit coverage reports
if [ -n "$coverage" ]; then
coverage xml --omit '*_test.vim'
codecov -X search gcov pycov -f coverage.xml --required \
--flags "$(echo "$vim" | sed -s 's/[-.]//g')"
rm coverage.xml
fi
# vim:ts=2:sts=2:sw=2:et # vim:ts=2:sts=2:sw=2:et

View file

@ -38,6 +38,10 @@ if !exists("g:go_highlight_functions")
let g:go_highlight_functions = 0 let g:go_highlight_functions = 0
endif endif
if !exists("g:go_highlight_function_arguments")
let g:go_highlight_function_arguments = 0
endif
if !exists("g:go_highlight_methods") if !exists("g:go_highlight_methods")
let g:go_highlight_methods = 0 let g:go_highlight_methods = 0
endif endif
@ -94,7 +98,7 @@ if exists("g:go_fold_enable")
if index(g:go_fold_enable, 'package_comment') == -1 if index(g:go_fold_enable, 'package_comment') == -1
let s:fold_package_comment = 0 let s:fold_package_comment = 0
endif endif
" Disabled by default. " Disabled by default.
if index(g:go_fold_enable, 'comment') > -1 if index(g:go_fold_enable, 'comment') > -1
let s:fold_comment = 1 let s:fold_comment = 1
@ -229,14 +233,14 @@ endif
" var, const " var, const
if s:fold_varconst if s:fold_varconst
syn region goVar start='var (' end='^\s*)$' transparent fold syn region goVar start='var (' end='^\s*)$' transparent fold
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar \ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
syn region goConst start='const (' end='^\s*)$' transparent fold syn region goConst start='const (' end='^\s*)$' transparent fold
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar \ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
else else
syn region goVar start='var (' end='^\s*)$' transparent syn region goVar start='var (' end='^\s*)$' transparent
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar \ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
syn region goConst start='const (' end='^\s*)$' transparent syn region goConst start='const (' end='^\s*)$' transparent
\ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar \ contains=ALLBUT,goParen,goBlock,goFunction,goTypeName,goReceiverType,goReceiverVar,goArgumentName,goArgumentType,goSimpleArguments
endif endif
" Single-line var, const, and import. " Single-line var, const, and import.
@ -343,14 +347,22 @@ endif
hi def link goOperator Operator hi def link goOperator Operator
" Functions; " Functions;
if g:go_highlight_functions != 0 if g:go_highlight_functions isnot 0 || g:go_highlight_function_arguments isnot 0
syn match goDeclaration /\<func\>/ nextgroup=goReceiver,goFunction skipwhite skipnl syn match goFunctionCall /\w\+\ze(/ contains=goBuiltins,goDeclaration
syn match goReceiver /(\(\w\|[ *]\)\+)/ contained nextgroup=goFunction contains=goReceiverVar skipwhite skipnl syn match goDeclaration /\<func\>/ nextgroup=goReceiver,goFunction,goSimpleArguments skipwhite skipnl
syn match goReceiverVar /\w\+/ nextgroup=goPointerOperator,goReceiverType skipwhite skipnl contained syn match goReceiverVar /\w\+\ze\s\+\(\w\|\*\)/ nextgroup=goPointerOperator,goReceiverType skipwhite skipnl contained
syn match goPointerOperator /\*/ nextgroup=goReceiverType contained skipwhite skipnl syn match goPointerOperator /\*/ nextgroup=goReceiverType contained skipwhite skipnl
syn match goFunction /\w\+/ nextgroup=goSimpleArguments contained skipwhite skipnl
syn match goReceiverType /\w\+/ contained syn match goReceiverType /\w\+/ contained
syn match goFunction /\w\+/ contained if g:go_highlight_function_arguments isnot 0
syn match goFunctionCall /\w\+\ze(/ contains=GoBuiltins,goDeclaration syn match goSimpleArguments /(\(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goArgumentName nextgroup=goSimpleArguments skipwhite skipnl
syn match goArgumentName /\w\+\(\s*,\s*\w\+\)*\ze\s\+\(\w\|\.\|\*\|\[\)/ contained nextgroup=goArgumentType skipwhite skipnl
syn match goArgumentType /\([^,)]\|\_s\)\+,\?/ contained nextgroup=goArgumentName skipwhite skipnl
\ contains=goVarArgs,goType,goSignedInts,goUnsignedInts,goFloats,goComplexes,goDeclType,goBlock
hi def link goReceiverVar goArgumentName
hi def link goArgumentName Identifier
endif
syn match goReceiver /(\s*\w\+\(\s\+\*\?\s*\w\+\)\?\s*)\ze\s*\w/ contained nextgroup=goFunction contains=goReceiverVar skipwhite skipnl
else else
syn keyword goDeclaration func syn keyword goDeclaration func
endif endif

View file

@ -0,0 +1,55 @@
fun! Test_Detect_Gopath() abort
let l:gopath = $GOPATH
try
let g:go_autodetect_gopath = 1
let l:tmp = go#util#tempdir("pathdetect")
let l:tmp2 = go#util#tempdir("pathdetect-nogodep")
call mkdir(l:tmp . '/subdir', 'p')
call mkdir(l:tmp . '/Godeps/_workspace', 'p')
exe ':e ' . l:tmp . '/a.go'
call assert_equal(l:tmp . '/Godeps/_workspace:' . l:gopath, $GOPATH)
exe ':e ' . l:tmp . '/not-a-go-file'
call assert_equal(l:gopath, $GOPATH)
exe ':e ' . l:tmp . '/subdir/a.go'
call assert_equal(l:tmp . '/Godeps/_workspace:' . l:gopath, $GOPATH)
exec ':e ' . l:tmp2 . '/a.go'
call assert_equal(l:gopath, $GOPATH)
finally
let g:go_autodetect_gopath = 0
call delete(l:tmp, 'rf')
call delete(l:tmp2, 'rf')
endtry
endfun
fun! Test_Detect_Gopath_disabled() abort
let l:gopath = $GOPATH
try
let g:go_autodetect_gopath = 0
let l:tmp = go#util#tempdir("pathdetect")
let l:tmp2 = go#util#tempdir("pathdetect-nogodep")
call mkdir(l:tmp . '/subdir', 'p')
call mkdir(l:tmp . '/Godeps/_workspace', 'p')
exe ':e ' . l:tmp . '/a.go'
call assert_equal(l:gopath, $GOPATH)
exe ':e ' . l:tmp . '/not-a-go-file'
call assert_equal(l:gopath, $GOPATH)
exe ':e ' . l:tmp . '/subdir/a.go'
call assert_equal(l:gopath, $GOPATH)
exec ':e ' . l:tmp2 . '/a.go'
call assert_equal(l:gopath, $GOPATH)
finally
let g:go_autodetect_gopath = 0
call delete(l:tmp, 'rf')
call delete(l:tmp2, 'rf')
endtry
endfun

View file

@ -216,7 +216,9 @@ def write_init_body(args, parents, snip):
def write_slots_args(args, snip): def write_slots_args(args, snip):
args = ['"_%s"' % arg for arg in args] quote = get_quoting_style(snip)
arg_format = quote + '_%s' + quote
args = [arg_format % arg for arg in args]
snip += '__slots__ = (%s,)' % ', '.join(args) snip += '__slots__ = (%s,)' % ', '.join(args)

View file

@ -103,6 +103,8 @@ snippet cascii
# Lambda # Lambda
snippet ld snippet ld
${1:var} = lambda ${2:vars} : ${0:action} ${1:var} = lambda ${2:vars} : ${0:action}
snippet ret
return ${0}
snippet . snippet .
self. self.
snippet try Try/Except snippet try Try/Except

View file

@ -58,6 +58,10 @@ snippet try
${0} ${0}
} }
#match #match
snippet mat
${1:${VISUAL}} match {
case ${2} => ${0}
}
snippet match snippet match
${1: obj} match { ${1: obj} match {
case ${2:e} => ${3} case ${2:e} => ${3}
@ -65,7 +69,7 @@ snippet match
} }
#case #case
snippet case snippet case
case ${1:value} => ${0} case ${1:${VISUAL}} => ${0}
############################ ############################
# methods and arguments # methods and arguments
# #

View file

@ -0,0 +1,2 @@
.rvmrc
doc/tags

View file

@ -0,0 +1,4 @@
source 'https://rubygems.org'
gem "vimbot", :git => "git@github.com:maxbrunsfeld/vimbot.git"
gem "rspec"

View file

@ -0,0 +1,25 @@
GIT
remote: git@github.com:maxbrunsfeld/vimbot.git
revision: 489cb3283a89d3e7891d9d9765188179c764317b
specs:
vimbot (0.0.1)
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.1.3)
rspec (2.8.0)
rspec-core (~> 2.8.0)
rspec-expectations (~> 2.8.0)
rspec-mocks (~> 2.8.0)
rspec-core (2.8.0)
rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.8.0)
PLATFORMS
ruby
DEPENDENCIES
rspec
vimbot!

View file

@ -0,0 +1,134 @@
yankstack.vim
=============
Author: Max Brunsfeld <http://www.github.com/maxbrunsfeld>
[Yankstack.vim](https://github.com/maxbrunsfeld/vim-yankstack) is a
lightweight implementation of the Emacs 'kill ring' for Vim. It allows you to
yank and delete things without worrying about losing the text that you yanked
previously. It effectively turns your default register into a stack, and lets
you cycle through the items in the stack after doing a paste.
This plugin is intended to be a simpler alternative to the
[yankring](https://github.com/chrismetcalf/vim-yankring) plugin. It has a fairly
complete [test suite](https://github.com/maxbrunsfeld/vim-yankstack/blob/master/spec/yankstack/yankstack_spec.rb)
based on [rspec](https://www.relishapp.com/rspec)
and [vimbot](https://github.com/maxbrunsfeld/vimbot).
## Installation ##
I recommend loading your plugins with
[vundle](https://github.com/gmarik/vundle) or
[pathogen](https://github.com/tpope/vim-pathogen).
## Key Mappings ##
By default, yankstack adds only 2 key bindings, in normal and visual modes:
- ```meta-p``` - cycle *backward* through your history of yanks
- ```meta-shift-p``` - cycle *forwards* through your history of yanks
After pasting some text using ```p``` or ```P```, you can cycle through your
yank history using these commands. Typing either of these keys *without* pasting first
will do a normal paste (the same as typing `p`). This also works in insert mode.
### the 'meta' key
If you're using MacVim, and you want to use
this plugin's default key bindings (or any bindings involving the `option`
key), you must ```:set macmeta```. On Linux, you may have issues with the meta key if your terminal is running in 7bit mode.
Instructions for dealing with this can be found on the [wiki](https://github.com/maxbrunsfeld/vim-yankstack/wiki/Linux-terminal-configurations-for-correct-meta-key-handling)
## Commands ##
You can see the contents of the yank-stack using the ```:Yanks``` command.
Its output is similar to the ```:registers``` command.
## Configuration ##
Yankstack defines two plugin mappings that you can map to keys of your choosing.
The same mappings work in normal and insert modes.
- ```<Plug>yankstack_substitute_older_paste``` - cycle backwards through your history of yanks
- ```<Plug>yankstack_substitute_newer_paste``` - cycle forwards through your history of yanks
For example, if you wanted to define some mappings based on your 'leader' key,
you could do this:
```
nmap <leader>p <Plug>yankstack_substitute_older_paste
nmap <leader>P <Plug>yankstack_substitute_newer_paste
```
Also, if you want to load yankstack without the default key mappings, just
``` let g:yankstack_map_keys = 0 ```
in your .vimrc file.
## Compatibility ##
Yankstack works by mapping the yank and paste keys to functions that do some
book-keeping before calling through to the normal yank/paste keys. You may want
to define your own mappings of the yank and paste keys. For example, I like to
map the ```Y``` key to ```y$```, so that it behaves the same as ```D``` and
```C```. The yankstack mappings need to happen **before** you define any such
mappings of your own. To achieve this, just call ```yankstack#setup()``` in
your vimrc, before defining your mappings:
```
call yankstack#setup()
nmap Y y$
" other mappings involving y, d, c, etc
```
You can also prevent certain keys from being remapped by setting the `g:yankstack_yank_keys`
to the keys of your choosing. For example, if you only want Yankstack to remap `y` and `d`:
```
let g:yankstack_yank_keys = ['y', 'd']
```
## Contributing, Feedback ##
I'd enjoy hearing anybody's feedback on yankstack, and welcome any contribution.
Check it out on [github](https://github.com/maxbrunsfeld/vim-yankstack)!
## Changelog ##
### 1.0.6 (2014-08-04)
- Allow customization of the list of keys to be remapped.
### 1.0.5 (2012-07-19)
- Fix bug where on certain versions of vim, the first time you tried
to cycle through your yanks after doing a normal paste, an extra
paste was created.
### 1.0.4 (2012-07-01)
- Make it so that yankstack-cycling keys cause a normal paste if they are
used without pasting first. Fix stack-cycling in insert-mode.
### 1.0.3 (2012-05-04):
- Fix bug when overwriting text in select mode. This was causing
problems for snipMate users.
### 1.0.2 (2012-4-20):
- Add test coverage using rspec and [vimbot](https://github.com/maxbrunsfeld/vimbot)!
- Perfect the behavior of the yankstack when pasting over text in visual
mode
- Fix bug where 's' and 'S' didn't push to the yankstack
### 1.0.1 (2012-2-11):
- Change default key bindings, update readme, add link to github page.
### 1.0.1 (2011-12-08):
- Fix bug when displaying empty yanks.
### 1.0.0 (2011-12-04):
- Remove unnecessary dependency on the undotree() function. Plugin should
now work on any recent version of vim.
## License ##
Copyright (c) Max Brunsfeld. Distributed under the same terms as Vim itself.
See the vim license.
vim:tw=78:ts=8:ft=help:norl:

View file

@ -0,0 +1,197 @@
" yankstack.vim - keep track of your history of yanked/killed text
"
" Maintainer: Max Brunsfeld <https://github.com/maxbrunsfeld>
" Version: 1.0.6
" Todo:
"
let s:yankstack_tail = []
let g:yankstack_size = 30
let s:last_paste = { 'changedtick': -1, 'key': '', 'mode': 'n', 'count': 1, 'register': '' }
if !exists('g:yankstack_yank_keys')
let g:yankstack_yank_keys = ['c', 'C', 'd', 'D', 's', 'S', 'x', 'X', 'y', 'Y']
endif
function! s:yank_with_key(key)
call s:before_yank()
return a:key
endfunction
function! s:paste_with_key(key, mode, register, count)
return s:paste_from_yankstack(a:key, a:mode, a:register, a:count, 1)
endfunction
function! s:paste_from_yankstack(key, mode, register, count, is_new)
let keys = a:count . a:key
let keys = (a:register == s:default_register()) ? keys : ('"' . a:register . keys)
let s:last_paste = { 'key': a:key, 'mode': a:mode, 'register': a:register, 'count': a:count, 'changedtick': -1 }
call feedkeys("\<Plug>yankstack_after_paste", "m")
if a:mode == 'n'
exec 'normal!' keys
elseif a:mode == 'v'
if a:is_new
call s:before_yank()
call feedkeys("\<Plug>yankstack_substitute_older_paste", "t")
exec 'normal! gv' . keys
else
let head = s:get_yankstack_head()
exec 'normal! gv' . keys
call s:set_yankstack_head(head)
endif
" In insert mode, this function's return value is used in an
" expression mapping. In other modes, it is called for its
" side effects only.
elseif a:mode == 'i'
return keys
endif
silent! call repeat#setreg(a:register)
silent! call repeat#set(a:key, a:count)
endfunction
function! s:substitute_paste(offset, current_mode)
if s:last_change_was_paste()
silent undo
call s:yankstack_rotate(a:offset)
return s:paste_from_yankstack(s:last_paste.key, s:last_paste.mode, s:last_paste.register, s:last_paste.count, 0)
else
return s:paste_from_yankstack(s:default_paste_key(a:current_mode), a:current_mode, v:register, '', 1)
endif
endfunction
function! s:before_yank()
let head = s:get_yankstack_head()
if !empty(head.text) && (empty(s:yankstack_tail) || (head != s:yankstack_tail[0]))
call insert(s:yankstack_tail, head)
let s:yankstack_tail = s:yankstack_tail[: g:yankstack_size-1]
endif
endfunction
function! s:yankstack_rotate(offset)
if empty(s:yankstack_tail) | return | endif
let offset_left = a:offset
while offset_left != 0
let head = s:get_yankstack_head()
if offset_left > 0
let entry = remove(s:yankstack_tail, 0)
call add(s:yankstack_tail, head)
let offset_left -= 1
elseif offset_left < 0
let entry = remove(s:yankstack_tail, -1)
call insert(s:yankstack_tail, head)
let offset_left += 1
endif
call s:set_yankstack_head(entry)
endwhile
endfunction
function! s:get_yankstack_head()
let reg = s:default_register()
return { 'text': getreg(reg), 'type': getregtype(reg) }
endfunction
function! s:set_yankstack_head(entry)
let reg = s:default_register()
call setreg(reg, a:entry.text, a:entry.type)
endfunction
function! s:after_paste()
let s:last_paste.changedtick = b:changedtick
endfunction
function! s:last_change_was_paste()
return b:changedtick == s:last_paste.changedtick
endfunction
function! s:default_register()
let clipboard_flags = split(&clipboard, ',')
if index(clipboard_flags, 'unnamedplus') >= 0
return "+"
elseif index(clipboard_flags, 'unnamed') >= 0
return "*"
else
return "\""
endif
endfunction
function! s:default_paste_key(mode)
if a:mode == 'i'
return "\<C-g>u\<C-r>" . s:default_register()
else
return "p"
endif
endfunction
function! g:Yankstack()
return [s:get_yankstack_head()] + s:yankstack_tail
endfunction
command! -nargs=0 Yanks call s:show_yanks()
function! s:show_yanks()
echohl WarningMsg | echo "--- Yanks ---" | echohl None
let i = 0
for yank in g:Yankstack()
call s:show_yank(yank, i)
let i += 1
endfor
endfunction
function! s:show_yank(yank, index)
let index = printf("%-4d", a:index)
let lines = split(a:yank.text, '\n')
let line = empty(lines) ? '' : lines[0]
let line = substitute(line, '\t', repeat(' ', &tabstop), 'g')
if len(line) > 80 || len(lines) > 1
let line = line[: 80] . '…'
endif
echohl Directory | echo index
echohl None | echon line
echohl None
endfunction
function! yankstack#setup()
if exists('g:yankstack_did_setup') | return | endif
let g:yankstack_did_setup = 1
let paste_keys = ['p', 'P', 'gp', 'gP']
let word_characters = split("qwertyuiopasdfghjklzxcvbnm1234567890_", '\zs')
for key in g:yankstack_yank_keys
exec 'nnoremap <silent> <expr>' key '<SID>yank_with_key("' . key . '")'
exec 'xnoremap <silent> <expr>' key '<SID>yank_with_key("' . key . '")'
endfor
for key in paste_keys
exec 'nnoremap <silent>' key ':<C-u>call <SID>paste_with_key("' . key . '", "n", v:register, v:count1)<CR>'
exec 'xnoremap <silent>' key ':<C-u>call <SID>paste_with_key("' . key . '", "v", v:register, v:count1)<CR>'
endfor
for key in word_characters
exec 'smap <expr>' key '<SID>yank_with_key("' . key . '")'
endfor
endfunction
nnoremap <silent> <Plug>yankstack_substitute_older_paste :<C-u>call <SID>substitute_paste(v:count1, 'n')<CR>
nnoremap <silent> <Plug>yankstack_substitute_newer_paste :<C-u>call <SID>substitute_paste(-v:count1, 'n')<CR>
xnoremap <silent> <Plug>yankstack_substitute_older_paste :<C-u>call <SID>substitute_paste(v:count1, 'v')<CR>
xnoremap <silent> <Plug>yankstack_substitute_newer_paste :<C-u>call <SID>substitute_paste(-v:count1, 'v')<CR>
inoremap <silent> <Plug>yankstack_substitute_older_paste <C-r>=<SID>substitute_paste(v:count1, 'i')<CR>
inoremap <silent> <Plug>yankstack_substitute_newer_paste <C-r>=<SID>substitute_paste(-v:count1, 'i')<CR>
nnoremap <silent> <Plug>yankstack_after_paste :call <SID>after_paste()<CR>
xnoremap <silent> <Plug>yankstack_after_paste :<C-u>call <SID>after_paste()<CR>
inoremap <silent> <Plug>yankstack_after_paste <C-o>:call <SID>after_paste()<CR>
if !exists('g:yankstack_map_keys') || g:yankstack_map_keys
nmap <M-p> <Plug>yankstack_substitute_older_paste
xmap <M-p> <Plug>yankstack_substitute_older_paste
imap <M-p> <Plug>yankstack_substitute_older_paste
nmap <M-P> <Plug>yankstack_substitute_newer_paste
xmap <M-P> <Plug>yankstack_substitute_newer_paste
imap <M-P> <Plug>yankstack_substitute_newer_paste
endif

View file

@ -0,0 +1,124 @@
*yankstack.txt* Plugin for storing and cycling through yanked text strings.
Author: Max Brunsfeld <http://www.github.com/maxbrunsfeld>
|yankstack-introduction| Introduction
|yankstack-installation| Installation
|yankstack-initialization| Initialization
|yankstack-commands| Commands
|yankstack-configuration| Configuration
|yankstack-changelog| Changelog
INTRODUCTION *yankstack-introduction*
[Yankstack.vim](https://github.com/maxbrunsfeld/vim-yankstack) is a
lightweight implementation of the Emacs 'kill ring' for Vim. It allows you to
yank and delete things without worrying about losing the text that you yanked
previously. It effectively turns your default register into a stack, and lets
you cycle through the items in the stack after doing a paste.
This plugin is intended to be a simpler alternative to the {Yankring} plugin
(https://github.com/chrismetcalf/vim-yankring).
INSTALLATION *yankstack-installation*
I recommend loading your plugins with {Pathogen}
(https://github.com/tpope/vim-pathogen), so you can just clone this repo into
your "bundle" directory.
KEY MAPPINGS *yankstack-mappings*
By default, yankstack adds only 2 key mappings, in normal and visual modes:
Mapping Action ~
meta-p cycle backward through your history of yanks
meta-shift-p cycle forwards through your history of yanks
After pasting some text using |p| or |P|, you can cycle through your
yank history using these commands.
Typing either of these keys without pasting first will do a normal paste
(the same as typing `p`). This also works in insert mode.
A note about the meta key - if you're using MacVim, and you want to use
this plugin's default key bindings (or any bindings involving the `option`
key), you must :set |macmeta|.
COMMANDS *yankstack-commands*
You can see the contents of the yank-stack using the :Yanks command.
Its output is similar to the |registers| command. >
:Yanks (lists the contents of the yank-stack)
CONFIGURATION *yankstack-configuration*
If you want to load yankstack without defining any of the default key
mappings, just add >
let g:yankstack_map_keys = 0
to your |.vimrc| file.
Yankstack defines three plugin mappings that you can map to keys of your
choosing. The same mappings work in normal and insert modes.
Mapping Name Action ~
<Plug>yankstack_substitute_older_paste cycle BACKWARDs through your history of yanks
<Plug>yankstack_substitute_newer_paste cycle FORWARDS through your history of yanks
For example, if you wanted to define some mappings based on your |leader| key, you could do this: >
nmap <leader>p <Plug>yankstack_substitute_older_paste
nmap <leader>P <Plug>yankstack_substitute_newer_paste
COMPATIBILITY *yankstack-compatibility*
Yankstack works by mapping the yank and paste keys to functions that do some
book-keeping before calling through to the normal yank/paste keys. You may
want to define your own mappings of the yank and paste keys. For example, I
like to map the |Y| key to "y$", so that it behaves the same as |D| and |C|.
The yankstack mappings need to happen **BEFORE** you define any such
mappings of your own. To achieve this, just call 'yankstack#setup()'in your
|vimrc|, before defining your mappings: >
call yankstack#setup()
nmap Y y$
CHANGELOG *yankstack-changelog*
1.0.5 (2012-07-19)
- Fix bug where on certain versions of vim, the first time you tried
to cycle through your yanks after doing a normal paste, an extra
paste was created.
1.0.4 (2012-07-01)
- Make it so that yankstack-cycling keys cause a normal paste if they are
used without pasting first. Fix stack-cycling in insert-mode.
1.0.3 (2012-05-04):
- Fix bug when overwriting text in select mode. This was causing
problems for snipMate users.
1.0.2 (2012-4-20):
- Add test coverage using rspec and [vimbot](https://github.com/maxbrunsfeld/vimbot)!
- Perfect the behavior of the yankstack when pasting over text in visual
mode
- Fix bug where 's' and 'S' didn't push to the yankstack
1.0.1 (2012-02-11):
- Change default key bindings, update readme, add link to github page.
1.0.1 (2011-12-08):
- Fix bug when displaying empty yanks.
1.0 (2011-12-04):
- Remove unnecessary dependency on the undotree() function. Plugin should
now work on any recent version of vim.
*yankstack-license*
Copyright (c) Max Brunsfeld. Distributed under the same terms as Vim itself.
See |license|.
vim:tw=78:ts=8:ft=help:norl:

View file

@ -0,0 +1 @@
call yankstack#setup()

View file

@ -0,0 +1,115 @@
" repeat.vim - Let the repeat command repeat plugin maps
" Maintainer: Tim Pope
" Version: 1.1
" GetLatestVimScripts: 2136 1 :AutoInstall: repeat.vim
" Installation:
" Place in either ~/.vim/plugin/repeat.vim (to load at start up) or
" ~/.vim/autoload/repeat.vim (to load automatically as needed).
"
" License:
" Copyright (c) Tim Pope. Distributed under the same terms as Vim itself.
" See :help license
"
" Developers:
" Basic usage is as follows:
"
" silent! call repeat#set("\<Plug>MappingToRepeatCommand",3)
"
" The first argument is the mapping that will be invoked when the |.| key is
" pressed. Typically, it will be the same as the mapping the user invoked.
" This sequence will be stuffed into the input queue literally. Thus you must
" encode special keys by prefixing them with a backslash inside double quotes.
"
" The second argument is the default count. This is the number that will be
" prefixed to the mapping if no explicit numeric argument was given. The
" value of the v:count variable is usually correct and it will be used if the
" second parameter is omitted. If your mapping doesn't accept a numeric
" argument and you never want to receive one, pass a value of -1.
"
" Make sure to call the repeat#set function _after_ making changes to the
" file.
"
" For mappings that use a register and want the same register used on
" repetition, use:
"
" silent! call repeat#setreg("\<Plug>MappingToRepeatCommand", v:register)
"
" This function can (and probably needs to be) called before making changes to
" the file (as those typically clear v:register). Therefore, the call sequence
" in your mapping will look like this:
"
" nnoremap <silent> <Plug>MyMap
" \ :<C-U>execute 'silent! call repeat#setreg("\<lt>Plug>MyMap", v:register)'<Bar>
" \ call <SID>MyFunction(v:register, ...)<Bar>
" \ silent! call repeat#set("\<lt>Plug>MyMap")<CR>
if exists("g:loaded_repeat") || &cp || v:version < 700
finish
endif
let g:loaded_repeat = 1
let g:repeat_tick = -1
let g:repeat_reg = ['', '']
" Special function to avoid spurious repeats in a related, naturally repeating
" mapping when your repeatable mapping doesn't increase b:changedtick.
function! repeat#invalidate()
let g:repeat_tick = -1
endfunction
function! repeat#set(sequence,...)
let g:repeat_sequence = a:sequence
let g:repeat_count = a:0 ? a:1 : v:count
let g:repeat_tick = b:changedtick
endfunction
function! repeat#setreg(sequence,register)
let g:repeat_reg = [a:sequence, a:register]
endfunction
function! repeat#run(count)
if g:repeat_tick == b:changedtick
let r = ''
if g:repeat_reg[0] ==# g:repeat_sequence && !empty(g:repeat_reg[1])
if g:repeat_reg[1] ==# '='
" This causes a re-evaluation of the expression on repeat, which
" is what we want.
let r = '"=' . getreg('=', 1) . "\<CR>"
else
let r = '"' . g:repeat_reg[1]
endif
endif
let c = g:repeat_count
let s = g:repeat_sequence
let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : ''))
call feedkeys(r . cnt, 'n')
call feedkeys(s)
else
call feedkeys((a:count ? a:count : '') . '.', 'n')
endif
endfunction
function! repeat#wrap(command,count)
let preserve = (g:repeat_tick == b:changedtick)
exe 'norm! '.(a:count ? a:count : '').a:command . (&foldopen =~# 'undo' ? 'zv' : '')
if preserve
let g:repeat_tick = b:changedtick
endif
endfunction
nnoremap <silent> . :<C-U>call repeat#run(v:count)<CR>
nnoremap <silent> u :<C-U>call repeat#wrap('u',v:count)<CR>
if maparg('U','n') ==# ''
nnoremap <silent> U :<C-U>call repeat#wrap('U',v:count)<CR>
endif
nnoremap <silent> <C-R> :<C-U>call repeat#wrap("\<Lt>C-R>",v:count)<CR>
augroup repeatPlugin
autocmd!
autocmd BufLeave,BufWritePre,BufReadPre * let g:repeat_tick = (g:repeat_tick == b:changedtick || g:repeat_tick == 0) ? 0 : -1
autocmd BufEnter,BufWritePost * if g:repeat_tick == 0|let g:repeat_tick = b:changedtick|endif
augroup END
" vim:set ft=vim et sw=4 sts=4:

View file

@ -0,0 +1,9 @@
require "vimbot"
PLUGIN_ROOT = File.expand_path("../..", __FILE__)
VIM_REPEAT_PATH = File.expand_path("spec/fixtures/repeat.vim", PLUGIN_ROOT)
RSpec.configure do |c|
c.alias_it_should_behave_like_to :it_has_behavior, 'has behavior:'
end

View file

@ -0,0 +1,343 @@
require "spec_helper"
describe "Yankstack" do
let(:vim) { Vimbot::Driver.new }
before(:all) do
vim.start
vim.set "visualbell"
vim.set "noerrorbells"
vim.set "macmeta"
vim.set "runtimepath+=#{PLUGIN_ROOT}"
vim.runtime "plugin/yankstack.vim"
vim.source VIM_REPEAT_PATH
end
after(:all) { vim.stop }
before(:each) { vim.clear_buffer }
shared_examples "yanking and pasting" do
let(:yank_keys) { "yw" }
before do
vim.insert "first_line<CR>", "second_line<CR>", "third_line<CR>", "fourth_line"
vim.normal "gg"
vim.normal yank_keys, 'j', yank_keys, 'j', yank_keys, 'j', yank_keys
end
it "pushes every yanked string to the :Yanks stack" do
yank_entries[0].should match /0\s+fourth_line/
yank_entries[1].should match /1\s+third_line/
yank_entries[2].should match /2\s+second_line/
yank_entries[3].should match /3\s+first_line/
end
describe "yanking with different keys" do
before do
vim.normal "A", "<CR>", "line to delete", "<Esc>", "^"
end
keys_that_change_register = [
'cc', 'C',
'dd', 'D',
's', 'S',
'x', 'X',
'yy', 'Y'
]
keys_that_change_register.each do |key|
it "pushes to the stack when deleting text with '#{key}'" do
vim.normal key
yank_entries[1].should match /1\s+fourth_line/
end
end
it "pushes to the stack when overwriting text in select mode" do
vim.type "V"
vim.type "<c-g>", "this overwrites the last line"
yank_entries[0].should include "line to delete"
yank_entries[1].should include "fourth_line"
end
end
context "in normal mode" do
before { vim.normal "o", "<Esc>" }
describe "pasting a string with 'p'" do
before { vim.normal "p" }
it "pastes the most recently yanked string" do
vim.line_number.should == 5
vim.line.should == "fourth_line"
end
describe "pressing the repeat key with '.'" do
it "pastes again" do
pending unless File.exists?(VIM_REPEAT_PATH)
vim.type "."
vim.line.should == "fourth_linefourth_line"
end
end
describe "typing the 'cycle paste' key" do
before { vim.normal "<M-p>" }
it "replaces the pasted string with the previously yanked text" do
vim.line.should == "third_line"
end
it "rotates the previously yanked text to the top of the yank stack" do
yank_entries[0].should include 'third_line'
yank_entries[1].should include 'second_line'
yank_entries[2].should include 'first_line'
yank_entries[-1].should include 'fourth_line'
end
it "rotates through the yanks when pressed multiple times" do
vim.normal "<M-p>"
vim.line.should == "second_line"
vim.normal "<M-p>"
vim.line.should == "first_line"
vim.normal "<M-P>"
vim.line.should == "second_line"
vim.normal "<M-P>"
vim.line.should == "third_line"
vim.normal "<M-P>"
vim.line.should == "fourth_line"
end
end
end
describe "typing the `substitute_older_paste` key without pasting first" do
before { vim.type "<M-p>" }
it "pastes the most recently yanked string" do
vim.line_number.should == 5
vim.line.should == "fourth_line"
end
describe "typing the 'cycle paste' key" do
before { vim.normal "<M-p>" }
it "replaces the pasted text with the previously yanked text" do
vim.line.should == "third_line"
end
end
end
describe "typing the `substitute_newer_paste` key without pasting first" do
before { vim.type "<M-P>" }
it "pastes the most recently yanked string" do
vim.line_number.should == 5
vim.line.should == "fourth_line"
end
describe "typing the 'cycle paste' key" do
before { vim.normal "<M-p>" }
it "replaces the pasted text with the previously yanked text" do
vim.line.should == "third_line"
end
end
end
it "allows pasting from a non-default register" do
reg = 'a'
vim.normal "gg"
vim.normal %("#{reg}y$)
vim.normal "G"
vim.normal %("#{reg}p)
vim.line.should == "first_line"
end
it "allows pasting with a count" do
vim.normal "3p"
vim.line_number.should == 5
vim.line.should == "fourth_line" * 3
end
end
context "in visual mode, with text highlighted" do
before do
vim.normal "A<CR>", "line to overwrite"
vim.normal "V"
end
describe "pasting a string with 'p'" do
before do
vim.type "p"
end
it "overwrites the selection with the most recently yanked string" do
vim.line.should == "fourth_line"
end
it "moves the the overwritten text to the bottom of the stack" do
yank_entries[0].should include "fourth_line"
yank_entries[1].should include "third_line"
yank_entries[2].should include "second_line"
yank_entries[-1].should include "line to overwrite"
end
describe "typing the 'cycle older paste' key" do
before { vim.normal "<M-p>" }
it "replaces the pasted text with the previously yanked text" do
vim.line.should == "third_line"
end
it "moves the previously yanked text to the top of the stack" do
yank_entries[0].should include "third_line"
yank_entries[1].should include "second_line"
yank_entries[2].should include "first_line"
yank_entries[-2].should include "line to overwrite"
yank_entries[-1].should include "fourth_line"
end
describe "typing the 'cycle newer paste' key" do
before { vim.normal "<M-P>" }
it "replaces the pasted text with the previously yanked text" do
vim.line.should == "fourth_line"
end
it "moves the previously yanked text to the top of the stack" do
yank_entries[0].should include "fourth_line"
yank_entries[1].should include "third_line"
yank_entries[2].should include "second_line"
yank_entries[3].should include "first_line"
yank_entries[-1].should include "line to overwrite"
end
end
end
end
describe "typing the `substitute_older_paste` key without pasting first" do
before { vim.type "<M-p>" }
it "overwrites the selection with the most recently yanked string" do
vim.line_number.should == 5
vim.line.should == "fourth_line"
end
end
describe "typing the `substitute_newer_paste` key without pasting first" do
before { vim.type "<M-P>" }
it "overwrites the selection with the most recently yanked string" do
vim.line_number.should == 5
vim.line.should == "fourth_line"
end
end
it "allows pasting with a count" do
vim.type "3p"
vim.line_number.should == 5
vim.line.should == "fourth_line"
vim.normal 'j'
vim.line_number.should == 6
vim.line.should == "fourth_line"
vim.normal 'j'
vim.line_number.should == 7
vim.line.should == "fourth_line"
end
end
context "in insert mode" do
before do
vim.normal "A<Cr>", "()", "<Left>"
vim.type "<M-p>"
end
describe "typing the `substitute_older_paste` after a character-wise yank" do
it "pastes the most recently yanked text after the cursor" do
vim.line_number.should == 5
vim.line.should == "(fourth_line)"
end
it "stays in insert mode, with the cursor at the end of the pasted text" do
vim.should be_in_insert_mode
vim.column_number.should == "(fourth_line".length + 1
end
describe "typing the `substitute_older_paste` key again" do
before { vim.type "<M-p>" }
it "replaces the pasted text with the previously yanked text" do
vim.line_number.should == 5
vim.line.should == "(third_line)"
end
it "stays in insert mode, with the cursor at the end of the pasted text" do
vim.should be_in_insert_mode
vim.column_number.should == "(third_line".length+1
end
it "rotates the previously yanked text to the top of the yank stack" do
yank_entries[0].should include 'third_line'
yank_entries[1].should include 'second_line'
yank_entries[2].should include 'first_line'
yank_entries[-1].should include 'fourth_line'
end
it "rotates through the yanks when pressed multiple times" do
vim.type "<M-p>"
vim.line_number.should == 5
vim.line.should == "(second_line)"
vim.type "<M-p>"
vim.line_number.should == 5
vim.line.should == "(first_line)"
vim.type "<M-P>"
vim.line_number.should == 5
vim.line.should == "(second_line)"
vim.type "<M-P>"
vim.line_number.should == 5
vim.line.should == "(third_line)"
vim.type "<M-P>"
vim.line_number.should == 5
vim.line.should == "(fourth_line)"
end
end
end
describe "typing `substitute_older_paste` after a line-wise yank" do
let(:yank_keys) { "yy" }
xit "pastes and puts the cursor after the pasted text" do
vim.line_number.should == 6
vim.line.should == ")"
vim.type "<Up>"
vim.line.should == "(fourth_line"
end
end
end
end
describe "when using the normal default register" do
it_has_behavior "yanking and pasting"
end
describe "when using the system clipboard as the default register" do
before { vim.set "clipboard", "unnamed" }
it_has_behavior "yanking and pasting"
end
def yank_entries
@yank_entries ||= vim.command("Yanks").split("\n")[1..-1]
end
end

View file

@ -16,7 +16,7 @@ from os import path
#--- Globals ---------------------------------------------- #--- Globals ----------------------------------------------
PLUGINS = """ PLUGINS = """
YankRing.vim https://github.com/vim-scripts/YankRing.vim vim-yankstack https://github.com/maxbrunsfeld/vim-yankstack
ack.vim https://github.com/mileszs/ack.vim ack.vim https://github.com/mileszs/ack.vim
bufexplorer https://github.com/corntrace/bufexplorer bufexplorer https://github.com/corntrace/bufexplorer
ctrlp.vim https://github.com/ctrlpvim/ctrlp.vim ctrlp.vim https://github.com/ctrlpvim/ctrlp.vim
@ -89,7 +89,6 @@ def download_extract_replace(plugin_name, zip_path, temp_dir, source_dir):
def update(plugin): def update(plugin):
name, github_url = plugin.split(' ') name, github_url = plugin.split(' ')
zip_path = GITHUB_ZIP % github_url zip_path = GITHUB_ZIP % github_url
print zip_path
download_extract_replace(name, zip_path, download_extract_replace(name, zip_path,
temp_directory, SOURCE_DIR) temp_directory, SOURCE_DIR)