Skip to content

Commit

Permalink
Merge pull request #1779 from Carpetsmoker/ac
Browse files Browse the repository at this point in the history
Add "ac" ("a comment") text object
  • Loading branch information
fatih committed May 28, 2018
2 parents 4d7dbea + 1049ec4 commit 956909d
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 3 deletions.
96 changes: 95 additions & 1 deletion autoload/go/textobj.vim
Original file line number Diff line number Diff line change
@@ -1,10 +1,104 @@
" ( ) motions
" { } motions
" s for sentence
" p for parapgrah
" p for paragraph
" < >
" t for tag

function! go#textobj#Comment(mode) abort
let l:fname = expand('%:p')

try
if &modified
let l:tmpname = tempname()
call writefile(go#util#GetLines(), l:tmpname)
let l:fname = l:tmpname
endif

let l:cmd = ['motion',
\ '-format', 'json',
\ '-file', l:fname,
\ '-offset', go#util#OffsetCursor(),
\ '-mode', 'comment',
\ ]

let [l:out, l:err] = go#util#Exec(l:cmd)
if l:err
call go#util#EchoError(l:out)
return
endif
finally
if exists("l:tmpname")
call delete(l:tmpname)
endif
endtry

let l:result = json_decode(l:out)
if type(l:result) != 4 || !has_key(l:result, 'comment')
return
endif

let l:info = l:result.comment
call cursor(l:info.startLine, l:info.startCol)

" Adjust cursor to exclude start comment markers. Try to be a little bit
" clever when using multi-line '/*' markers.
if a:mode is# 'i'
let l:line = getline('.')
" //text
if l:line[:2] is# '// '
call cursor(l:info.startLine, l:info.startCol+3)
" // text
elseif l:line[:1] is# '//'
call cursor(l:info.startLine, l:info.startCol+2)
" /*
" text
elseif l:line =~# '^/\* *$'
call cursor(l:info.startLine+1, 0)
" /*
" * text
if getline('.')[:2] is# ' * '
call cursor(l:info.startLine+1, 4)
" /*
" *text
elseif getline('.')[:1] is# ' *'
call cursor(l:info.startLine+1, 3)
endif
" /* text
elseif l:line[:2] is# '/* '
call cursor(l:info.startLine, l:info.startCol+3)
" /*text
elseif l:line[:1] is# '/*'
call cursor(l:info.startLine, l:info.startCol+2)
endif
endif

normal! v

" Exclude trailing newline.
if a:mode is# 'i'
let l:info.endCol -= 1
endif

call cursor(l:info.endLine, l:info.endCol)

" Exclude trailing '*/'.
if a:mode is# 'i'
let l:line = getline('.')
" text
" */
if l:line =~# '^ *\*/$'
call cursor(l:info.endLine - 1, len(getline(l:info.endLine - 1)))
" text */
elseif l:line[-3:] is# ' */'
call cursor(l:info.endLine, l:info.endCol - 3)
" text*/
elseif l:line[-2:] is# '*/'
call cursor(l:info.endLine, l:info.endCol - 2)
endif
endif
endfunction

" Select a function in visual mode.
function! go#textobj#Function(mode) abort
let l:fname = expand("%:p")
Expand Down
6 changes: 6 additions & 0 deletions doc/vim-go.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,12 @@ if "inside a function", select contents of a function,
excluding the function definition and the closing bracket. This
text-object also supports literal functions

*go-v_ac* *go-ac*
ac "a comment", select contents of the current comment block.

*go-v_ic* *go-ic*
ic "inner comment", select contents of the current comment block,
excluding the start and end comment markers.

vim-go also defines the following text motion objects:

Expand Down
10 changes: 8 additions & 2 deletions ftplugin/go.vim
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,17 @@ endif

if get(g:, "go_textobj_enabled", 1)
onoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr>
onoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr>
xnoremap <buffer> <silent> af :<c-u>call go#textobj#Function('a')<cr>
onoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr>
xnoremap <buffer> <silent> if :<c-u>call go#textobj#Function('i')<cr>
onoremap <buffer> <silent> ac :<c-u>call go#textobj#Comment('a')<cr>
xnoremap <buffer> <silent> ac :<c-u>call go#textobj#Comment('a')<cr>
onoremap <buffer> <silent> ic :<c-u>call go#textobj#Comment('i')<cr>
xnoremap <buffer> <silent> ic :<c-u>call go#textobj#Comment('i')<cr>
" Remap ]] and [[ to jump betweeen functions as they are useless in Go
nnoremap <buffer> <silent> ]] :<c-u>call go#textobj#FunctionJump('n', 'next')<cr>
nnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('n', 'prev')<cr>
Expand Down

0 comments on commit 956909d

Please sign in to comment.