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?
To address your final paragraph, the following script defines a new "indent" text-object that you can perform actions on. For instance, dii deletes everything indented at the same level as the line the cursor is on.
See the plugin's documentation for more info: http://www.vim.org/scripts/script.php?script_id=3037
Square Bracket Mappings
[[
,]]
,[m
,]m
and similar$VIMRUNTIME/ftplugin/python.vim
now (2018) remaps all builtin mappings documented under:h ]]
and:h ]m
for the python language. The mappings are:Following example source code with comments illustrates the different mappings
The mappings have been added and improved in the commits abd468ed0 (2016-09-08), 01164a6546b4 (2017-11-02), and 7f2e9d7c9cd (2017-11-11).
If you do not have the new version of this file yet, you can download it and put it into
~/.vim/ftplugin/python.vim
. This folder takes precedence before$VIMRUNTIME/ftplugin
.Before these mappings have been added to
$VIMRUNTIME
, there has been the pluginpython-mode
which provides[[
,]]
,[M
, and]M
. In additionpython-mode
also defines the text objectsaC
,iC
,aM
, andiM
:Plugin python-mode
This vim plugin provides motions similar to built-in ones:
Plugin Pythonsense
This plugin provides similar motions but slightly modified:
All details and examples are given at https://github.com/jeetsukumaran/vim-pythonsense#stock-vim-vs-pythonsense-motions. In addition, this plugin defines the text objects
ic/ac
(class),if/af
(function),id/ad
(docstring).For a discussion about textobjects for python see what's the fastest way to select a function of Python via VIM?.
python.vim
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]<up>
-- Jump to previous line with the same/lower indentation]<down>
-- Jump to next line with the same/lower indentationpython_match.vim
extends
%
:%
- cycle through if/elif/else, try/except/catch, for/continue/breakg%
- move opposite of%
[%
- move to the beginning of the current code block]%
- move to the end of the current code blockAll the above motions work with Normal, Visual, and Operator-pending modes, so:
d]%
- delete until the end of the current blockv]%d
- should do the same, going through Visual mode so that you can see what is being deletedV]%d
- above, but with line selectionIt's very easy to move indented blocks when you have
set foldmethod=indent
. For example, if you're on thedef main():
line in the following snippet:then
dj
takes the whole main function and it can be pasted elsewhere.