This Emacs package extends Evil (evil-mode) with text objects that
operate on Python statements.
The evil-text-object-python package provides two text objects to
operate on a complete Python statement (or multiple statements if a
count is given):
evil-text-object-python-inner-statementis the 'inner' text object that selects the actual code of the current statement. This text object is character based, and does not include any leading whitespace (indentation).evil-text-object-python-outer-statementis the 'outer' text object that selects all lines of the current statement. This text object is line based, and includes leading whitespace.
The default key bindings are il and al, which can be memorised
as ‘inner line‘ and ‘a line‘. (Note that is and as are already
taken, since Evil and Vim use those to operate on sentences.)
It also provides a text object to operate on complete functions (or multiple functions).
evil-text-object-python-functionis the 'function' text object that selects the lines of the current function.
Consider this sample code:
class Foo:
def bar(self):
print("hello")
some_complicated_function(
that='takes',
quite='a',
few=very(
'complex',
arguments={
'as': 'you',
'can': 'see',
},
),
so="it is spread over multiple lines",
but="in the end it's still a single statement")
do_something()
if some_condition:
do_another_thing()
do_something_else()With point (the cursor position) somewhere in the middle of the line containing the word ’complex’, this works:
ccchanges only that line (default in evil)dddeletes only that line (default in evil)cildeletes the call tosome_complicated_function(...), and changes to insert state at the right indentation level.caldoes the same ascil.dildeletes the call tosome_complicated_function(...), leaving behing an empty line.daldeletes the call tosome_complicated_function(...), leaving no traces behind.2daldeletes the call tosome_complicated_function(...), and also the statement that follows, which isdo_something().vilenters visual state, and selects the call tosome_complicated_function(...), without the indentationvalenters visual state, selects the call tosome_complicated_function(...), including indentation, and switches to line based visual state.v5alselects 5 statements starting at point using line based visual state.
Install from Melpa:
M-x package-install RET evil-text-object-python RET
Then add this to init.el:
(add-hook 'python-mode-hook 'evil-text-object-python-add-bindings)Note that the implementation uses various Python navigation commands
provided by python-mode, which ships with Emacs itself.
The default key binding uses the letter l (il and al), but
can be customised by changing evil-text-object-python-statement-key.
For example:
(setq evil-text-object-python-statement-key "x")Alternatively, use the Customize interface:
M-x customize-group RET evil-text-object-python RET
This package complements the line-based and indentation-based motions and text objects:
- For simple Python statements, such as
x = 3, the standard line-based editing operations work fine. For example,dddeletes a line,ccchanges a line, and so on. - The indentation-based text objects provided by evil-indent-plus make it easy to edit
(change, copy, delete, and so on) indented blocks of code such as
the body of an
ifstatement, or even the complete block including theifstatement itself.
However, for Python statements that span multiple lines, things don't work as nicely as they should:
- Line-based editing does not match the structure of the code.
- Indentation-based editing selects only partial statements, and depending on where the closing parentheses are, it may select incomplete expressions.
While both can be useful, it's not always what's intended. It’s also very easy to end up with code that contains syntax errors.
A statement-based text object is a powerful addition to the existing editing operations, and hence makes it easier to modify Python code.
- Incremental expansion of the selection in visual mode has not been
implemented, so
valalalwill not select a single statement, then two statements, then three statements.