-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
4. Tutorial: Text Objects
Text Objects are a way to manipulate a piece of text in a structured way. They allow you to refer to blocks of text based on their purpose and perform powerful actions. For example:
- Selecting inside of a function.
- Select the next argument.
- Select the next changed text tracked by git.
- Select the previous type.
Notice that in each item in the above list we select something? This builds upon the idea that we talked about in the selection-first approach section.
Text objects allow us to use this mechanism to be even more productive.
In each example [[
represents start of a selection, and ]]
represents end of a selection.
For example, with the following Python file:
class Thing:
def __init__(self):
self.thing = "Hi"
def say_thing(self):
print(self.thing)
-
Move your cursor in the
__init__
method, and press maf for match around function to select the entire method.This is the text that will be selected:
class Thing:
[[def __init__(self):
self.thing = "Hi"]]
def say_thing(self):
print(self.thing)
-
Use mif for match inside function to select the body of the method:
Selection will now become:
class Thing:
def __init__(self):
[[self.thing = "Hi"]]
def say_thing(self):
print(self.thing)
-
Additionally, you can move between most text objects.
For instance, use ]f with go to the previous function.
Selection will now become:
class Thing:
def __init__(self):
self.thing = "Hi"
[[def say_thing(self):
print(self.thing)]]
-
mi +
<textobject>
to match inside a textobject. Highlight a smaller region of the text object, for example the body of a function. -
ma +
<textobject>
to match around a textobject. Selects the entire text object, which usually includes surrounding whitespace. -
] +
<textobject>
to go to the next instance of the textobject. -
[ +
<textobject>
to go to the previous instance of the textobject.
-
p
,w
andW
: primitive text objects -
(
,)
,{
,}
,[
,]
,<
,>
,'
,"
and`
: pair text objects -
g
: git hunk -
f
,t
,a
,c
,T
,g
: tree-sitter text objects
A word consists only of alphanumeric characters and underscores, so a-Z
, 0-9
and _
.
For instance, take the following file, with 2 cursors:
pri[[n]]tln!("Hey, w[[o]]rld!")
- Match inside word with miw, then this text will be selected:
[[println]]!("Hey, [[world]]!")
- Matching around word with maw, then this text will be seletced:
[[println]]!("Hey,[[ world]]!")
Note that we now also have the space before the world
as our selection!
A WORD is always delimited by whitespace such as newlines, tabs and spaces.
Consider this file again:
pri[[n]]tln!("Hey, w[[o]]rld!")
- Match inside WORD with miW:
[[println!("Hey,]] [[world!")]]
- Matching around WORD with maW:
[[println!("Hey, world!")]]
Note that the first selection was println!("Hey,
and the second selection is world!");
, since these selections share a common character (the space), they essentially merge.
A paragraph is delimited by two newlines, as well as start and end of files. For example in the following file with 3 cursors:
One two thr[[e]]e
Four fiv[[e]] six
Seven [[e]]ight nine
- Match inside paragraph with mip:
[[One two three]]
[[Four five six]]
[[Seven eight nine]]
- Match around paragraph with map:
[[One two three
]]
[[Four five six
]]
[[Seven eight nine
]]
Notice that the surrounding newlines (whitespace) is also included now!
These allow you to select:
- Inside of the surrounding pair, excluding the surrounding characters
- Inside of the surrounding pair, including the surrounding characters
For example, with the following file:
const say = (s: s[[t]]ring) => console.log(s);
- Pressing mi( will select:
const say = ([[s: string]]) => console.log(s);
- While ma( will select:
const say = [[(s: string)]] => console.log(s);
Full list of available pairs:
-
(
and)
-
[
and]
-
{
and}
-
<
and>
-
'
and'
-
"
and"
-
`
and`
If you are in a repository, then you will also have the g
for git hunk textobject.
It will select the entire change.
For instance, if we have the following file, with the added lines shown with +++
:
One two three
+++ Four five six
+++
+++ Seve[[n]] eight nine
Eleven twelve
Using mig will select the added lines (the git "Hunk"):
One two three
+++ [[Four five six
+++
+++ Seven eight nine
+++ ]]
Eleven twelve
Available for most languages, specifically ones with text objects support. See the full list of all languages with configured text object queries.
To find out for your language from the terminal, run hx --health <language>
. If queries for a specific language like python are available, running hx --health python
will show:
Textobject queries: ✓
List of available text objects:
-
f
for function -
t
for type -
a
for argument -
c
for comment -
T
for Test
Some commands allow you to move the selection according to its location in the syntax tree. For example, many languages have the following syntax for function calls:
fn([[a]]rg1, arg2, arg3)
- If you use Alt + n, it will select the next sibling:
fn(arg1, [[arg2]], arg3)
- Similarly, Alt + p selects the previous sibling:
fn([[arg1]], arg2, arg3)
- Alt + o will expand selection to syntactically encompass more "nodes":
fn([[arg1, arg2, arg3]])