*targets.txt* Provide additional text objects Author: Christian Wellenbrock License: MIT license ____ \___\_.::::::::::.____ /___/ '::::::::::' ============================================================================== INTRODUCTION *targets-introduction* Targets.vim adds various |text-objects| to give you more targets to operate on. It expands on the idea of simple commands like `di'` (delete inside the single quotes around the cursor) to give you more opportunities to craft powerful commands that can be repeated reliably. Another major goal is to handle all corner cases correctly. ============================================================================== EXAMPLES *targets-examples* The following examples are displayed as three lines each. The top line denotes cursor positions from where the presented command works. The middle line shows the contents of the example line that we're working on. The last line shows the part of the line that the command will operate on. To change the text in the next pair of parentheses, use the `cin)` command ..................... This is example text (with a pair of parentheses) ~ └───────── cin) ─────────┘ To delete the item in a comma separated list under the cursor, use `da,` ......... Shopping list: oranges, apples, bananas, tomatoes ~ └─ da, ─┘ Notice how the selection includes exactly one of the surrounding commas to leave a proper comma separated list behind. ============================================================================== OVERVIEW *targets-overview* Targets.vim comes with five kinds for text objects: Pair text objects |targets-pair-text-objects| Quote text objects |targets-quote-text-objects| Separator text objects |targets-separator-text-objects| Argument text objects |targets-argument-text-objects| Tag text objects Each of those kinds is implemented by a targets source. Third party plugins can provide additional sources to add even more text objects which behave like the built in ones. See plugins.md in the targets.vim repo for details on how to implement your own targets source. ============================================================================== PAIR TEXT OBJECTS *targets-pair-text-objects* These text objects are similar to the built in text objects such as |i)|. Supported trigger characters: ( ) (work on parentheses) { } B (work on curly braces) [ ] (work on square brackets) < > (work on angle brackets) t (work on tags) Pair text objects work over multiple lines and support |targets-pair-seek|. We borrowed the aliases `r` and `a` from the |surround| plugin by Tim Pope. The following examples will use parentheses, but they all work for each listed trigger character accordingly. i( i) i[ i] iB *i(_t* *i)_t* *i[_t* *i]_t* *iB_t* i{ i} i< i> it *i{_t* *i}_t* *i<_t* *i>_t* *it_t* Select inside of pair characters. This overrides Vim's default text object to allow seeking for the next pair in the current line to the right or left when the cursor is not inside a pair. This behavior is similar to Vim's seeking behavior of `di'` when not inside of quotes, but it works both ways. Accepts a [count] to select multiple blocks. ............ a ( b ( cccccccc ) d ) e ~ │ └── i) ──┘ │ └───── 2i) ──────┘ a( a) a[ a] aB *a(_t* *a)_t* *a[_t* *a]_t* *aB_t* a{ a} a< a> at *a{_t* *a}_t* *a<_t* *a>_t* *at_t* Select a pair. Overrides Vim's default text object to allow seeking. Accepts [count]. ............ a ( b ( cccccccc ) d ) e ~ │ └─── a) ───┘ │ └────── 2a) ───────┘ I( I) I[ I] IB *I(_t* *I)_t* *I[_t* *I]_t* *IB_t* I{ I} I< I> It *I{_t* *I}_t* *I<_t* *I>_t* *It_t* Select contents of pair characters. Like inside of parentheses, but exclude whitespace at both ends. Useful for changing contents while preserving spacing. Accepts [count]. ............ a ( b ( cccccccc ) d ) e ~ │ └─ I) ─┘ │ └──── 2I) ─────┘ A( A) A[ A] AB *A(_t* *A)_t* *A[_t* *A]_t* *AB_t* A{ A} A< A> At *A{_t* *A}_t* *A<_t* *A>_t* *At_t* Select around pair characters. Like a pair, but include whitespace at one side of the pair. Prefers to select trailing whitespace, falls back to select leading whitespace. Accepts [count]. ............ a ( b ( cccccccc ) d ) e ~ │ └─── A) ────┘ │ └────── 2A) ────────┘ ------------------------------------------------------------------------------ NEXT AND LAST PAIR *targets-next-last-pair* Work directly on distant pairs without moving there separately. in( in) in[ in] inB *in(* *in)* *in[* *in]* *inB* in{ in} in< in> int *in{* *in}* *in<* *in>* *int* an( an) an[ an] anB *an(* *an)* *an[* *an]* *anB* an{ an} an< an> ant *an{* *an}* *an<* *an>* *ant* In( In) In[ In] InB *In(* *In)* *In[* *In]* *InB* In{ In} In< In> Int *In{* *In}* *In<* *In>* *Int* An( An) An[ An] AnB *An(* *An)* *An[* *An]* *AnB* An{ An} An< An> Ant *An{* *An}* *An<* *An>* *Ant* il( il) il[ il] ilB *il(* *il)* *il[* *il]* *ilB* il{ il} il< il> ilt *il{* *il}* *il<* *il>* *ilt* al( al) al[ al] alB *al(* *al)* *al[* *al]* *alB* al{ al} al< al> alt *al{* *al}* *al<* *al>* *alt* Il( Il) Il[ Il] IlB *Il(* *Il)* *Il[* *Il]* *IlB* Il{ Il} Il< Il> Ilt *Il{* *Il}* *Il<* *Il>* *Ilt* Al( Al) Al[ Al] AlB *Al(* *Al)* *Al[* *Al]* *AlB* Al{ Al} Al< Al> Alt *Al{* *Al}* *Al<* *Al>* *Alt* All the above pair text objects can be shifted to the next pair by including the letter `n`. The command `in)` selects inside of the next pair. Use the letter `l` instead to work on the previous (last) pair. Uses a [count] to skip multiple pairs. Skipping works over multiple lines. *targets-pair-charts* The following charts summarizes all pair mappings for a list of pairs and nested pairs: .......... a ( bbbbbbbb ) ( ccccccc ) ( dddddd ) ( eeeeeee ) ( ffffffff ) g ~ ││└ 2Il) ┘│││││└ Il) ┘│││││└ I) ┘│││││└ In) ┘│││││└ 2In) ┘│││ │└─ 2il) ─┘│││└─ il) ─┘│││└─ i) ─┘│││└─ in) ─┘│││└─ 2in) ─┘││ ├── 2al) ──┘│├── al) ──┘│├── a) ──┘│├── an) ──┘│├── 2an) ──┘│ └── 2Al) ───┘└── Al) ───┘└── A) ───┘└── An) ───┘└── 2An) ───┘ .......... a ( b ( cccccccc ) d ) ( e ( ffffff ) g ) ( h ( iiiiiiii ) j ) k ~ │││ ││└ 2Il) ┘││││││││││ ││└ I) ┘││││││││││ ││└ 2In) ┘│││││││ │││ │└─ 2il) ─┘│││││││││ │└─ i) ─┘│││││││││ │└─ 2in) ─┘││││││ │││ ├── 2al) ──┘││││││││ ├── a) ──┘││││││││ ├── 2an) ──┘│││││ │││ └── 2Al) ───┘│││││││ └── A) ───┘│││││││ └── 2An) ───┘││││ ││└───── Il) ────┘│││││└─── 2I) ────┘│││││└───── In) ────┘│││ │└────── il) ─────┘│││└──── 2i) ─────┘│││└────── in) ─────┘││ ├─────── al) ──────┘│├───── 2a) ──────┘│├─────── an) ──────┘│ └─────── Al) ───────┘└───── 2A) ───────┘└─────── An) ───────┘ ------------------------------------------------------------------------------ PAIR SEEK *targets-pair-seek* If any of the normal pair commands (not containing `n` or `l`) is executed when the cursor is not positioned inside a pair, it seeks for pairs before or after the cursor by searching for the appropriate delimiter on the current line. This is similar to using the explicit version containing `n` or `l`, but in only seeks on the current line. ============================================================================== QUOTE TEXT OBJECTS *targets-quote-text-objects* These text objects are similar to the built in text objects such as |i'|. Supported trigger characters: ' (work on single quotes) " (work on double quotes) ` (work on back ticks) These quote text objects try to be smarter than the default ones. They count the quotation marks from the beginning of the line to decide which of these are the beginning of a quote and which ones are the end. If you type `ci"` on the `,` in the example below, it will automatically skip and change `world` instead of changing `,` between `hello` and `world`. join("hello", "world") ~ └─────┘ └─────┘ proper quotes └──┘ false quotes Quote text objects work over multiple lines and support |targets-quote-seek|. The following examples will use single quotes, but they all work for each listed quoting character accordingly. i' i" i` *i`_t* *i'_t* *iquote_t* Select inside quote. This overrides Vim's default text object to allow seeking in both directions. ............ a ' bbbbbbbb ' c ' d ' e~ └── i' ──┘ a' a" a` *a`_t* *a'_t* *aquote_t* Select a quote. This overrides Vim's default text object to support |targets-quote-seek|. Unlike Vim's quote text objects, this incudes no surrounding whitespace. ............ a ' bbbbbbbb ' c ' d ' e~ └─── a' ───┘ I' I" I` *I`* *I'* *Iquote* Select contents of a quote. Like inside quote, but exclude whitespace at both ends. Useful for changing contents while preserving spacing. ............ a ' bbbbbbbb ' c ' d ' e~ └─ I' ─┘ A' A" A` *A`* *A'* *Aquote* Select around a quote. Like a quote, but include whitespace in one direction. Prefers to select trailing whitespace, falls back to select leading whitespace. ............ a ' bbbbbbbb ' c ' d ' e~ └─── A' ────┘ ------------------------------------------------------------------------------ NEXT AND LAST QUOTE *targets-next-last-quote* Work directly on distant quotes without moving there separately. in' in" in` il' il" il` *in`* *in'* *inquote* *il`* *il'* *ilquote* an' an" an` al' al" al` *an`* *an'* *anquote* *al`* *al'* *alquote* In' In" In` Il' Il" Il` *In`* *In'* *Inquote* *Il`* *Il'* *Ilquote* All the above pair text objects can be shifted to the next quote by including the letter `n`. The command `in'` selects inside of the next single quotes. Use the letter `l` instead to work on the previous (last) quote. Uses a [count] to skip multiple quotation characters. *targets-quote-chart* The following chart summarizes all quote mappings: ............. a ' bbbbbbb ' c ' dddddd ' e ' fffffff ' g ~ ││└ Il' ┘│││ ││└ I' ┘│││ ││└ In' ┘│││ │└─ il' ─┘││ │└─ i' ─┘││ │└─ in' ─┘││ ├── al' ──┘│ ├── a' ──┘│ ├── an' ──┘│ └── Al' ───┘ └── A' ───┘ └── An' ───┘ ------------------------------------------------------------------------------ QUOTE SEEK *targets-quote-seek* If any of the normal quote commands (not containing `n` or `l`) is executed when the cursor is not positioned inside a quote, it seeks for quotes before or after the cursor by searching for the appropriate delimiter on the current line. Similar to using the explicit version containing `n` or `l`. ============================================================================== SEPARATOR TEXT OBJECTS *targets-separator-text-objects* These text objects are based on single separator characters like the comma in one of our |targets-examples|. The text between two instances of the separator character can be operated on with these targets. Supported separators: , . ; : + - = ~ _ * # / | \ & $ ~ Separator text objects work over multiple lines and support |targets-separator-seek|. The following examples will use commas, but they all work for each listed separator character accordingly. i, i. i; i: i+ i- i= i~ *i,* *i.* *i;* *i:* *i+* *i-* *i=* *i~* i_ i/ i| i\ i& i$ i# i* *i_* *i/* *i|* *i\* *i&* *i$* *i#* *istar* Select inside separators. ........... a , b , cccccccc , d , e ~ └── i, ──┘ a, a. a; a: a+ a- a= a~ *a,* *a.* *a;* *a:* *a+* *a-* *a=* *a~* a_ a/ a| a\ a& a$ a# a * *a_* *a/* *a|* *a\* *a&* *a$* *a#* *astar* Select an item in a list separated by the separator character. This includes the leading separator, but excludes the trailing one. This leaves a proper list separated by the separator character after deletion. See |targets-examples|. ........... a , b , cccccccc , d , e ~ └─── a, ──┘ I, I. I; I: I+ I- I= I~ *I,* *I.* *I;* *I:* *I+* *I-* *I=* *I~* I_ I/ I| I\ I& I$ I# I * *I_* *I/* *I|* *I\* *I&* *I$* *I#* *Istar* Select contents between separators. Like inside separators, but exclude whitespace at both ends. Useful for changing contents while preserving spacing. ........... a , b , cccccccc , d , e ~ └─ I, ─┘ A, A. A; A: A+ A- A= A~ *A,* *A.* *A;* *A:* *A+* *A-* *A=* *A~* A_ A/ A| A\ A& A$ A# A * *A_* *A/* *A|* *A\* *A&* *A$* *A#* *Astar* Select around a pair of separators. This includes both separators and a surrounding whitespace, similar to `a'` and `A(`. ........... a , b , cccccccc , d , e ~ └─── A, ────┘ ------------------------------------------------------------------------------ NEXT AND LAST SEPARATOR *targets-next-last-separator* Work directly on distant separators without moving there separately. *in,* *in.* *in;* *in:* *in+* *in-* *in=* *in~* *an,* *an.* *an;* *an:* *an+* *an-* *an=* *an~* *In,* *In.* *In;* *In:* *In+* *In-* *In=* *In~* *An,* *An.* *An;* *An:* *An+* *An-* *An=* *An~* *il,* *il.* *il;* *il:* *il+* *il-* *il=* *il~* *al,* *al.* *al;* *al:* *al+* *al-* *al=* *al~* *Il,* *Il.* *Il;* *Il:* *Il+* *Il-* *Il=* *Il~* *Al,* *Al.* *Al;* *Al:* *Al+* *Al-* *Al=* *Al~* *in_* *in/* *in|* *in\* *in&* *in$* *in#* *instar* *an_* *an/* *an|* *an\* *an&* *an$* *an#* *anstar* *In_* *In/* *In|* *In\* *In&* *In$* *In#* *Instar* *An_* *An/* *An|* *An\* *An&* *An$* *An#* *Anstar* *il_* *il/* *il|* *il\* *il&* *il$* *il#* *ilstar* *al_* *al/* *al|* *al\* *al&* *al$* *al#* *alstar* *Il_* *Il/* *Il|* *Il\* *Il&* *Il$* *Il#* *Ilstar* *Al_* *Al/* *Al|* *Al\* *Al&* *Al$* *Al#* *Alstar* in, in. in; in: in+ in- in= in~ in_ in/ in| in\ in& in$ in# in* an, an. an; an: an+ an- an= an~ an_ an/ an| an\ an& an$ an# an* In, In. In; In: In+ In- In= In~ In_ In/ In| In\ In& In$ In# In* An, An. An; An: An+ An- An= An~ An_ An/ An| An\ An& An$ An# An* il, il. il; il: il+ il- il= il~ il_ il/ il| il\ il& il$ il# il* al, al. al; al: al+ al- al= al~ al_ al/ al| al\ al& al$ al# al* Il, Il. Il; Il: Il+ Il- Il= Il~ Il_ Il/ Il| Il\ Il& Il$ Il# Il* Al, Al. Al; Al: Al+ Al- Al= Al~ Al_ Al/ Al| Al\ Al& Al$ Al# Al* All the above separator text objects can be shifted to the next separator by including the letter `n`. The command `in,` selects inside of the next commas. Use the letter `l` instead to work on the previous (last) separators. Uses a [count] to skip multiple separator characters. *targets-separator-chart* The following chart summarizes all separator mappings: ......... a , bbbbbbbb , ccccccc , dddddd , eeeeeee , ffffffff , g ~ ││└ 2Il, ┘│││└ Il, ┘│││└ I, ┘│││└ In, ┘│││└ 2In, ┘│ │ │└─ 2il, ─┤│├─ il, ─┤│├─ i, ─┤│├─ in, ─┤│├─ 2in, ─┤ │ ├── 2al, ─┘├┼─ al, ─┘├┼─ a, ─┘├┼─ an, ─┘├┼─ 2an, ─┘ │ └── 2Al, ──┼┘ └┼─ A, ──┼┘ └┼─ 2An, ───┘ └─ Al, ──┘ └─ An, ──┘ ------------------------------------------------------------------------------ SEPARATOR SEEK *targets-separator-seek* Like |targets-quote-seek|. If any of the normal separator commands (not containing `n` or `l`) is executed when the cursor is not positioned inside a pair of separators, it seeks for the separator before or after the cursor. This is similar to using the explicit version containing `n` or `l`. ============================================================================== ARGUMENT TEXT OBJECTS *targets-argument-text-objects* These text objects are similar to separator text objects, but are specialized for arguments surrounded by braces and commas. They also take matching braces into account to capture only valid arguments. Argument text objects work over multiple lines and support |targets-argument-seek|. ia *ia* Select inside argument. Accepts a [count] to select bigger nested arguments. ........... a , b ( cccccccc , d ) e ~ └── ia ──┘ aa *aa* Select an argument in a list of arguments. This includes a separator if present, but excludes surrounding braces. This leaves a proper of arguments after deletion. Accepts a [count] to select bigger nested arguments. ........... a , b ( cccccccc , d ) e ~ └─── aa ──┘ Ia *Ia* Select contents of an argument. Like inside argument, but exclude whitespace at both ends. Useful for changing contents while preserving spacing. Accepts a [count] to select bigger nested arguments. ........... a , b ( cccccccc , d ) e ~ └─ Ia ─┘ Aa *Aa* Select around an argument. This includes both delimiters and a surrounding whitespace, similar to `a'` and `A(`. Accepts a [count] to select bigger nested arguments. ........... a , b ( cccccccc , d ) e ~ └─── Aa ────┘ ------------------------------------------------------------------------------ NEXT AND LAST ARGUMENT *targets-next-last-argument* Work directly on distant arguments without moving there separately. ina ana Ina Ana *ina* *ana* *Ina* *Ana* ila ala Ila Ala *ila* *ala* *Ila* *Ala* All the above argument text objects can be shifted to the next argument by including the letter `n`. The command `ina` selects inside of the next argument. Use the letter `l` instead to work on the previous (last) argument. Uses a [count] to skip multiple argument characters. The order is determined by the nearest surrounding argument delimiter. *targets-argument-chart* The following chart summarizes all argument mappings: ......... a ( bbbbbb , ccccccc , d ( eeeeee , fffffff ) , gggggg ) h ~ ││├2Ila┘│││└─Ila─┘││││ ││├─Ia─┘│││└─Ina─┘│││││└2Ina┘│ │ │└┼2ila─┘│├──ila──┤│││ │└┼─ia──┘│├──ina──┤│││├─2ina─┤ │ │ └2ala──┼┤ ││││ │ └─aa───┼┤ │││├┼─2ana─┘ │ └──2Ala──┼┘ ││││ └───Aa───┼┘ │││└┼─2Ana───┘ ├───ala──┘│││ ├───ana──┘││ │ └───Ala───┼┤│ └───Ana───┼┤ │ ││└─────2Ia────────────┘│ │ │└──────2ia─────────────┤ │ ├───────2aa─────────────┘ │ └───────2Aa───────────────┘ ------------------------------------------------------------------------------ ARGUMENT SEEK *targets-argument-seek* Like |targets-separator-seek|. If any of the normal argument commands (not containing `n` or `l`) is executed when the cursor is not positioned inside an argument, it seeks for the argument before or after the cursor. This is similar to using the explicit version containing `n` or `l`. ============================================================================== MULTI TEXT OBJECTS *targets-multi-text-objects* Two multi text objects are included in default settings. See the section on settings below to see how to set up other similar multi text objects or customize the built in ones. ------------------------------------------------------------------------------ ANY BLOCK *targets-any-block* inb anb Inb Anb ilb alb Ilb Alb~ Similar to pair text objects, if you type `dib` within `()` it will delete in these. If you do the same within `{}` it will delete in those. If you type `d2inb` it will skip one next pair (any kind) and delete in the one after (any kind). If you're within `()` nested in `{}`, type `d2ib` to delete in `{}`. All of the usual seeking, growing and skipping works. ------------------------------------------------------------------------------ ANY QUOTE *targets-any-quote* inq anq Inq Anq ilq alq Ilq Alq~ Similar to quote text objects, if you type `diq` within `""` it will delete in these. If you do the same within `''` it will delete in those. If you type `d2inq` it will skip one next quote text object (any kind) and delete in the one after (any kind). If you're within `""` nested in `''`, type `d2iq` to delete in `''`. All of the usual seeking, growing and skipping works. ============================================================================== SETTINGS *targets-settings* You can customize the mappings and text objects with the settings described here. Available options: ~ |g:targets_aiAI| |g:targets_nl| |g:targets_seekRanges| |g:targets_jumpRanges| |targets#mappings#extend| ------------------------------------------------------------------------------ *g:targets_aiAI* Default: let g:targets_aiAI = 'aiAI' ~ Controls the normal mode operator mode maps that get created for In Pair (i), A Pair (a), Inside Pair (I), and Around Pair (A). Required to be a 4 character long list. Use a space to deactivate a mode. ------------------------------------------------------------------------------ *g:targets_nl* Default: let g:targets_nl = 'nl' ~ Controls the keys used in maps for seeking next and last text objects. For example, if you want 'n' to always search for the next object and `N` to search for the last, you could set: let g:targets_nl = 'nN' ~ Required to be a 4 character long list. Use a space to deactivate a direction. ------------------------------------------------------------------------------ *g:targets_seekRanges* Default: let g:targets_seekRanges = 'cc cr cb cB lc ac Ac lr rr ll lb ar ab lB Ar aB Ab AB rb al rB Al bb aa bB Aa BB AA' ~ Defines a priority ordered, space separated list of range types which can be used to customize seeking behavior. When using a command like `cib` to change inside a block, targets.vim considers the three targets: smallest target around cursor next target after cursor last target before cursor For each of those that were found, we detect what range type it has. A range type depends on the relative position of the start and end of the target, relative to the current cursor position and the currently visible lines. The possibly relative positions are: c on cursor position ~ l left of cursor in current line ~ r right of cursor in current line ~ a above cursor on screen ~ b below cursor on screen ~ A above cursor off screen ~ B below cursor off screen ~ All possibly ranges are listed below, denoted by two characters: one for the relative start and one for the relative end position of the target. For example, `lr` means "from left of cursor to right of cursor in cursor line". Next to each range type is a pictogram of an example. They are made of these symbols: . current cursor position ~ ( ) start and end of target ~ / line break before and after cursor line ~ | screen edge between hidden and visible lines ~ Ranges on cursor: cc | / O / | target equals cursor position (single character) ~ cr | / () / | starting on cursor, current line ~ cb | / ( /) | starting on cursor, multiline down, on screen ~ cB | / ( / |) starting on cursor, multiline down, partially off screen ~ lc | / () / | ending on cursor, current line ~ ac | (/ ) / | ending on cursor, multiline up, on screen ~ Ac (| / ) / | ending on cursor, multiline up, partially off screen ~ Ranges around cursor: lr | / (.) / | around cursor, current line ~ lb | / (. /) | around cursor, multiline down, on screen ~ ar | (/ .) / | around cursor, multiline up, on screen ~ ab | (/ . /) | around cursor, multiline both, on screen ~ lB | / (. / |) around cursor, multiline down, partially off screen ~ Ar (| / .) / | around cursor, multiline up, partially off screen ~ aB | (/ . / |) around cursor, multiline both, partially off screen bottom ~ Ab (| / . /) | around cursor, multiline both, partially off screen top ~ AB (| / . / |) around cursor, multiline both, partially off screen both ~ Ranges after (right of/below) cursor rr | / .()/ | after cursor, current line ~ rb | / .( /) | after cursor, multiline, on screen ~ rB | / .( / |) after cursor, multiline, partially off screen ~ bb | / . /()| after cursor below, on screen ~ bB | / . /( |) after cursor below, partially off screen ~ BB | / . / |() after cursor below, off screen ~ Ranges before (left of/above) cursor ll | /(). / | before cursor, current line ~ al | (/ ). / | before cursor, multiline, on screen ~ Al (| / ). / | before cursor, multiline, partially off screen ~ aa |()/ . / | before cursor above, on screen ~ Aa (| )/ . / | before cursor above, partially off screen ~ AA ()| / . / | before cursor above, off screen ~ A a l r b B relative positions └───────────┘ visible screen └─────┘ current line Given the range types of our targets, we then pick the one that appears first in `g:targets_seekRanges`. If none is found, the selection fails. The default setting generally prefers targets around the cursor, with one exception: If the target around the cursor is not contained in the current cursor line, but the next or last target are, then prefer those. Targets beginning or ending on the cursor are preferred over everything else. Some other useful example settings (or build your own!): Prefer multiline targets around cursor over distant targets within cursor line: let g:targets_seekRanges = 'cc cr cb cB lc ac Ac lr lb ar ab lB Ar aB Ab AB rr ll rb al rB Al bb aa bB Aa BB AA' ~ Never seek backwards: let g:targets_seekRanges = 'cc cr cb cB lc ac Ac lr rr lb ar ab lB Ar aB Ab AB rb rB bb bB BB' ~ Only seek if next/last targets touch current line: let g:targets_seekRanges = 'cc cr cb cB lc ac Ac lr rr ll lb ar ab lB Ar aB Ab AB rb rB al Al' ~ Only consider targets fully visible on screen: let g:targets_seekRanges = 'cc cr cb cB lc ac Ac lr lb ar ab rr rb bb ll al aa' ~ Only consider targets around cursor: let g:targets_seekRanges = 'cc cr cb cB lc ac Ac lr lb ar ab lB Ar aB Ab AB' ~ Only consider targets fully contained in current line: let g:targets_seekRanges = 'cc cr cb cB lc ac Ac lr rr ll' ~ ------------------------------------------------------------------------------ *g:targets_jumpRanges* Default: let g:targets_jumpRanges = 'bb bB BB aa Aa AA' ~ Defines an unordered, space separated list of range types which can be used to customize the jumplist behavior (see documentation on seek ranges). It controls whether or not to add the cursor position prior to selecting the text object to the jumplist. The default setting adds the previous cursor position to the jumplist if the target that was operated on doesn't intersect the cursor line. That means it adds a jumplist entry if the target ends above the cursor line or starts below the cursor line. Some other useful example settings (or build your own!): Never add cursor position to jumplist: let g:targets_jumpRanges = '' ~ Always add cursor position to jumplist: let g:targets_jumpRanges = 'cr cb cB lc ac Ac lr rr ll lb ar ab lB Ar aB Ab AB rb al rB Al bb aa bB Aa BB AA' ~ Only add to jumplist if cursor was not inside the target: let g:targets_jumpRanges = 'rr rb rB bb bB BB ll al Al aa Aa AA' ~ ------------------------------------------------------------------------------ *targets#mappings#extend* This function can be used to modify an internal dictionary used to control the mappings. The default value of that dictionary is: {~ \ '(': {'pair': [{'o': '(', 'c': ')'}]},~ \ ')': {'pair': [{'o': '(', 'c': ')'}]},~ \ '{': {'pair': [{'o': '{', 'c': '}'}]},~ \ '}': {'pair': [{'o': '{', 'c': '}'}]},~ \ 'B': {'pair': [{'o': '{', 'c': '}'}]},~ \ '[': {'pair': [{'o': '[', 'c': ']'}]},~ \ ']': {'pair': [{'o': '[', 'c': ']'}]},~ \ '<': {'pair': [{'o': '<', 'c': '>'}]},~ \ '>': {'pair': [{'o': '<', 'c': '>'}]},~ \ '"': {'quote': [{'d': '"'}]},~ \ "'": {'quote': [{'d': "'"}]},~ \ '`': {'quote': [{'d': '`'}]},~ \ ',': {'separator': [{'d': ','}]},~ \ '.': {'separator': [{'d': '.'}]},~ \ ';': {'separator': [{'d': ';'}]},~ \ ':': {'separator': [{'d': ':'}]},~ \ '+': {'separator': [{'d': '+'}]},~ \ '-': {'separator': [{'d': '-'}]},~ \ '=': {'separator': [{'d': '='}]},~ \ '~': {'separator': [{'d': '~'}]},~ \ '_': {'separator': [{'d': '_'}]},~ \ '*': {'separator': [{'d': '*'}]},~ \ '#': {'separator': [{'d': '#'}]},~ \ '/': {'separator': [{'d': '/'}]},~ \ '\': {'separator': [{'d': '\'}]},~ \ '|': {'separator': [{'d': '|'}]},~ \ '&': {'separator': [{'d': '&'}]},~ \ '$': {'separator': [{'d': '$'}]},~ \ 't': {'tag': [{}]},~ \ 'a': {'argument': [{'o': '[([]', 'c': '[])]', 's': ','}]},~ \ 'b': {'pair': [{'o':'(', 'c':')'}, {'o':'[', 'c':']'}, {'o':'{', 'c':'}'}]},~ \ 'q': {'quote': [{'d':"'"}, {'d':'"'}, {'d':'`'}]},~ \ }~ The keys in this dictionary correspond to the trigger character. For example if you type `di(`, `(` is the trigger and gets mapped to the `pair` target source with arguments `'o':'('` (opening) and `'c':')'` (closing). Sources `quote` and `separator` have argument `'d'` (delimiter), `tag` has no arguments and `argument` text objets take `'o'` (opening), `'c'` (closing) and `'s'` (separator). Notably the `b` (any block) and `q` (any quote) triggers map to one source with three sets of `pair` and `quote` args dictiory respectively. That means if you type `dib` each of those sources get taken into account to pick the proper target. Also note that it's even possible to have one target mapped to multiple different sources to select any of those different text objects (see example below). You can use the `targets#mappings#extend()` function to modify these internal mappings. For example if you wanted to switch `b` back to the Vim default behavior of operating on paretheses only, you can add this to your vimrc: autocmd User targets#mappings#user call targets#mappings#extend({~ \ 'b': {'pair': [{'o':'(', 'c':')'}]}~ \ })~ Note that you should always use that `autocmd` prefix to make sure your modifications get applied at the right time. There's a similar autogroup for plugins which can add other sources and default mappings, which gets triggered before this `#user` one. That way the user mappings always take precedence over the plugins default mappings If you want to remove a mapping from the defaults, just set it to an empty list of sources: autocmd User targets#mappings#user call targets#mappings#extend({~ \ 'q': {},~ \ })~ That way targets.vim will ignore it and fall back to Vim default behavior, which for the case of `q` does nothing. Finally here's a more complex example which adds too triggers `s` (any separator text object) and `@` (anything at all). So you could type `das` to delete the closest separator text object near the cursor, or `da@` to operate on the closest text object available via targets.vim. All of those support seeking and counts like `d3ins`. autocmd User targets#mappings#user call targets#mappings#extend({~ \ 's': { 'separator': [{'d':','}, {'d':'.'}, {'d':';'}, {'d':':'}, {'d':'+'}, {'d':'-'},~ \ {'d':'='}, {'d':'~'}, {'d':'_'}, {'d':'*'}, {'d':'#'}, {'d':'/'},~ \ {'d':'\'}, {'d':'|'}, {'d':'&'}, {'d':'$'}] },~ \ '@': {~ \ 'separator': [{'d':','}, {'d':'.'}, {'d':';'}, {'d':':'}, {'d':'+'}, {'d':'-'},~ \ {'d':'='}, {'d':'~'}, {'d':'_'}, {'d':'*'}, {'d':'#'}, {'d':'/'},~ \ {'d':'\'}, {'d':'|'}, {'d':'&'}, {'d':'$'}],~ \ 'pair': [{'o':'(', 'c':')'}, {'o':'[', 'c':']'}, {'o':'{', 'c':'}'}, {'o':'<', 'c':'>'}],~ \ 'quote': [{'d':"'"}, {'d':'"'}, {'d':'`'}],~ \ 'tag': [{}],~ \ },~ \ })~ Also note how this example shows that you can set multiple triggers in a single `targets#mappings#extend()` call. To keep the autocmd overhead minimal I'd recommend to keep all your mappings setup in a single such call. But do as you wish, I'm not your mom! ------------------------------------------------------------------------------ DEPRECATED SETTINGS *targets-deprecated-settings* If you have set any of the following settings in your vimrc, they will still be respected when creating the default mappings dictionary. But it's not possible to set up any multi source targets (like any block or any quote) this way. It's recommendet to retire those legacy settings and use `targets#mappings#extend()` as described above. g:targets_pairs~ g:targets_quotes~ g:targets_separators~ g:targets_tagTrigger~ g:targets_argClosing~ g:targets_argOpening~ g:targets_argSeparator~ g:targets_argTrigger~ However, those new mappings settings will only be respected when targets.vim can use expression mappings, which need Neovim or Vim with version 7.3.338 or later. If you are using an older Vim version, these legacy settings are still the only way to do any customization. Please refer to an older version of this README (before October 2018) for details. Or open an issue for me to describe those legacy settings somewhere still. ============================================================================== NOTES *targets-notes* Repeating an operator-pending mapping forgets its last count. https://groups.google.com/forum/?fromgroups#!topic/vim_dev/G4SSgcRVN7g Works since Vim 7.4.160 ============================================================================== ISSUES *targets-issues* Empty matches can't be selected because it is not possible to visually select zero-character ranges. Forcing motion to work linewise by inserting `V` in `dVan(` doesn't work for operator-pending mappings. See |o_V|. Report issues or submit pull requests to: https://github.com/wellle/vim-targets ============================================================================== TODOS *targets-todos* Create more mappings to support commands like `danw` or `danp` to delete the next word or paragraph. ------------------------------------------------------------------------------ vim:tw=78:ts=8:ft=help:norl: