Wikia

Vim Tips Wiki

Changes: Commenting with opfunc

Edit

Back to page

(Assign tip id + convert to TipNew template)
(Change <tt> to <code>, perhaps also minor tweak.)
 
Line 3: Line 3:
 
|previous=1569
 
|previous=1569
 
|next=1571
 
|next=1571
|created=June 5, 2008
+
|created=2008
 
|complexity=basic
 
|complexity=basic
 
|author=Jlepak
 
|author=Jlepak
Line 11: Line 11:
 
|category2=
 
|category2=
 
}}
 
}}
This tip uses the <tt>opfunc</tt> option to define two operators. Assuming the default backslash leader key, the operators are:
+
This tip uses the <code>opfunc</code> option to define two operators. Assuming the default backslash leader key, the operators are:
*<tt>\c</tt> &nbsp;&nbsp; to comment lines (insert a comment string before each line)
+
*<code>\c</code> &nbsp;&nbsp; to comment lines (insert a comment string before each line)
*<tt>\C</tt> &nbsp;&nbsp; to uncomment lines
+
*<code>\C</code> &nbsp;&nbsp; to uncomment lines
   
 
==Usage==
 
==Usage==
Line 26: Line 26:
 
</pre>
 
</pre>
   
The command <tt>yip</tt> (yank inner paragraph) would copy the block. In a similar manner, the command <tt>\cip</tt> will comment-out the block, resulting in:
+
The command <code>yip</code> (yank inner paragraph) would copy the block. In a similar manner, the command <code>\cip</code> will comment-out the block, resulting in:
 
<pre>
 
<pre>
 
class Example:
 
class Example:
Line 36: Line 36:
 
</pre>
 
</pre>
   
Later, you could remove the comment signifiers with <tt>\Cip</tt>.
+
Later, you could remove the comment signifiers with <code>\Cip</code>.
   
 
An operator can be used in two ways:
 
An operator can be used in two ways:
Line 43: Line 43:
   
 
Examples:
 
Examples:
*<tt>\ciB</tt> &nbsp;&nbsp; comment inner block (between braces)
+
*<code>\ciB</code> &nbsp;&nbsp; comment inner block (between braces)
*<tt>\c}</tt> &nbsp;&nbsp; comment to end paragraph
+
*<code>\c}</code> &nbsp;&nbsp; comment to end paragraph
*<tt>\cG</tt> &nbsp;&nbsp; comment to end buffer
+
*<code>\cG</code> &nbsp;&nbsp; comment to end buffer
*<tt>Vjjj\c</tt> &nbsp;&nbsp; comment visually-selected lines
+
*<code>Vjjj\c</code> &nbsp;&nbsp; comment visually-selected lines
   
 
==Script==
 
==Script==
Line 94: Line 94:
   
 
==Explanation==
 
==Explanation==
A custom operator can be defined using visual-mode maps (to apply the operator to a selection), and using the <tt>operatorfunc</tt> (<tt>opfunc</tt>) option (to apply the operator to a movement).
+
A custom operator can be defined using visual-mode maps (to apply the operator to a selection), and using the <code>operatorfunc</code> (<code>opfunc</code>) option (to apply the operator to a movement).
   
The <tt>g@</tt> operator can be used in a map to define your own operator. When <tt>g@</tt> is invoked, the function defined by the <tt>opfunc</tt> option is called with an argument indicating the type of motion ("line", "char" or "block"). In addition, the <tt>'[</tt> and <tt>']</tt> marks identify the start and end positions of the motion.
+
The <code>g@</code> operator can be used in a map to define your own operator. When <code>g@</code> is invoked, the function defined by the <code>opfunc</code> option is called with an argument indicating the type of motion ("line", "char" or "block"). In addition, the <code>'[</code> and <code>']</code> marks identify the start and end positions of the motion.
   
You can let the script determine the comment string from the filetype, or you can define the buffer-local variable <tt>comment</tt>, for example:
+
You can let the script determine the comment string from the filetype, or you can define the buffer-local variable <code>comment</code>, for example:
 
<pre>
 
<pre>
 
:let b:comment='#---'
 
:let b:comment='#---'

Latest revision as of 06:34, July 13, 2012

Tip 1570 Printable Monobook Previous Next

created 2008 · complexity basic · author Jlepak · version 7.0


This tip uses the opfunc option to define two operators. Assuming the default backslash leader key, the operators are:

  • \c    to comment lines (insert a comment string before each line)
  • \C    to uncomment lines

UsageEdit

For example, put the cursor anywhere in the def block in the following Python code:

class Example:

    def f(self, x):
        if x < 5:
            print "Pointless function."
        return 0

The command yip (yank inner paragraph) would copy the block. In a similar manner, the command \cip will comment-out the block, resulting in:

class Example:

    # def f(self, x):
    #     if x < 5:
    #         print "Pointless function."
    #     return 0

Later, you could remove the comment signifiers with \Cip.

An operator can be used in two ways:

  • Invoke the operator, then enter a movement command. or
  • Visually select a block, then invoke the operator.

Examples:

  • \ciB    comment inner block (between braces)
  • \c}    comment to end paragraph
  • \cG    comment to end buffer
  • Vjjj\c    comment visually-selected lines

ScriptEdit

Here's the code. It only handles linewise comments.

" Comment or uncomment lines from mark a to mark b.
function! CommentMark(docomment, a, b)
  if !exists('b:comment')
    let b:comment = CommentStr() . ' '
  endif
  if a:docomment
    exe "normal! '" . a:a . "_\<C-V>'" . a:b . 'I' . b:comment
  else
    exe "'".a:a.",'".a:b . 's/^\(\s*\)' . escape(b:comment,'/') . '/\1/e'
  endif
endfunction

" Comment lines in marks set by g@ operator.
function! DoCommentOp(type)
  call CommentMark(1, '[', ']')
endfunction

" Uncomment lines in marks set by g@ operator.
function! UnCommentOp(type)
  call CommentMark(0, '[', ']')
endfunction

" Return string used to comment line for current filetype.
function! CommentStr()
  if &ft == 'cpp' || &ft == 'java' || &ft == 'javascript'
    return '//'
  elseif &ft == 'vim'
    return '"'
  elseif &ft == 'python' || &ft == 'perl' || &ft == 'sh' || &ft == 'R'
    return '#'
  elseif &ft == 'lisp'
    return ';'
  endif
  return ''
endfunction

nnoremap <Leader>c <Esc>:set opfunc=DoCommentOp<CR>g@
nnoremap <Leader>C <Esc>:set opfunc=UnCommentOp<CR>g@
vnoremap <Leader>c <Esc>:call CommentMark(1,'<','>')<CR>
vnoremap <Leader>C <Esc>:call CommentMark(0,'<','>')<CR>

ExplanationEdit

A custom operator can be defined using visual-mode maps (to apply the operator to a selection), and using the operatorfunc (opfunc) option (to apply the operator to a movement).

The g@ operator can be used in a map to define your own operator. When g@ is invoked, the function defined by the opfunc option is called with an argument indicating the type of motion ("line", "char" or "block"). In addition, the '[ and '] marks identify the start and end positions of the motion.

You can let the script determine the comment string from the filetype, or you can define the buffer-local variable comment, for example:

:let b:comment='#---'

See alsoEdit

ReferencesEdit

CommentsEdit

Around Wikia's network

Random Wiki