views:

649

answers:

4

Given a python file with the following repeated endlessly:

def myFunction(a, b, c):
    if a:
        print b
    elif c:
        print 'hello'

I'd like to move around and edit this file using familiar vim movements. For instance, using (, ), [[, ]], {, } or deleting/yanking/changing text using commands like di}.

In other languages (like C++, Java, C#, etc) you've got curly brackets abound, so using a movement like di} can easily find a matching curly brace and act on that block. And in fact if I am on the 'b' character on the above text and do a di) in vim, it successfully deletes the text between the two parens.

The issue is in python's detection of code blocks, I think. Using (, ), [[, ]], {, or } as movements all pretty much do the same thing, bringing you to the start (above or on the def line) or end (after the last line of the function) of the function. And there is no way, as far as I know, to easily tell vim "select everything for this indentation block." In the above example, I'd like to be on in 'i' of the if line, type di} and have it delete the entire if block (to the end of this particular function).

I'm sure it should be possible to tell vim to operate on an indentation basis for such movements (well, maybe not that particular movement, but some user defined action). Any thoughts on how to accomplish this?

+4  A: 

http://www.vim.org/scripts/script.php?script_id=386

adi92
+1, but could you give a description in your answer to make it clear what this is?
bignose
sorry.. the generic version of this plugin can be found at http://www.vim.org/scripts/script.php?script_id=39 and a ruby-specific version at http://vim.sourceforge.net/scripts/script.php?script_id=290 install these by putting them in the directories specified in the .vim folder of your home directory.. after i installed the ruby one.. i could go to the start or end of a block and press '%' to move to the other end and use '=%' at the start of a block to correct the indentation of that block
adi92
This is nice, but it doesn't fully replace something like di}. With a "matchable" language, you can be anywhere in a block and operate on the entire block with simple commands. Given the syntax of the linked script, I would've hoped something like di]% would work...but it doesn't. I guess this just might not be possible currently.
+1  A: 

It's very easy to move indented blocks when you have set foldmethod=indent. For example, if you're on the def main(): line in the following snippet:

def main():
+-- 35 lines: gps.init()-----------------------------------------------------

if __name__ == "__main__": main()

then dj takes the whole main function and it can be pasted elsewhere.

ΤΖΩΤΖΙΟΥ
A: 

More information on the Vim script refred to above:

http://www.vim.org/scripts/script.php?script_id=386

python_match.vim : Extend the % motion and define g%, [%, and ]% motions for Python files

description This script redefines the % motion so that (in addition to its usual behavior) it cycles through if/elif/else, try/except/catch, for/continue/break, and while/continue/break structures. The script also defines g% to cycle in the opposite direction. Two other motions, [% and ]%, go to the start and end of the current block, respectively.

All of these motions should work in Normal, Visual, and Operator-pending modes. For example, d]% should delete (characterwise) until the end of the current block; v]%d should do the same, going through Visual mode so that you can see what is being deleted; and V]%d makes it linewise.

Rudiger Wolf
+1  A: 

Here is a VIM script http://www.vim.org/scripts/script.php?script_id=30

which makes it much easier to navigate around python code blocks.

Shortcuts:

  • ]t -- Jump to beginning of block
  • ]e -- Jump to end of block
  • ]v -- Select (Visual Line Mode) block
  • ]< -- Shift block to left
  • ]> -- Shift block to right
  • ]# -- Comment selection
  • ]u -- Uncomment selection
  • ]c -- Select current/previous class
  • ]d -- Select current/previous function
  • ] -- Jump to previous line with the same/lower indentation
  • ] -- Jump to next line with the same/lower indentation
Rudiger Wolf