Git Product home page Git Product logo

vim-textobj-user's Introduction

vim-textobj-user - Create your own text objects

Build Status

vim-textobj-user is a Vim plugin to create your own text objects without pain. It is hard to create text objects, because there are many pitfalls to deal with. This plugin hides such details and provides a declarative way to define text objects. You can use regular expressions to define simple text objects, or use functions to define complex ones.

Examples

Simple text objects defined by a pattern

Define ad/id to select a date such as 2013-03-16, and define at/it to select a time such as 22:04:21:

call textobj#user#plugin('datetime', {
\   'date': {
\     'pattern': '\<\d\d\d\d-\d\d-\d\d\>',
\     'select': ['ad', 'id'],
\   },
\   'time': {
\     'pattern': '\<\d\d:\d\d:\d\d\>',
\     'select': ['at', 'it'],
\   },
\ })

Simple text objects surrounded by a pair of patterns

Define aA to select text from << to the matching >>, and define iA to select text inside << and >>:

call textobj#user#plugin('braces', {
\   'angle': {
\     'pattern': ['<<', '>>'],
\     'select-a': 'aA',
\     'select-i': 'iA',
\   },
\ })

Complex text objects defined by functions

Define al to select the current line, and define il to select the current line without indentation:

call textobj#user#plugin('line', {
\   '-': {
\     'select-a-function': 'CurrentLineA',
\     'select-a': 'al',
\     'select-i-function': 'CurrentLineI',
\     'select-i': 'il',
\   },
\ })

function! CurrentLineA()
  normal! 0
  let head_pos = getpos('.')
  normal! $
  let tail_pos = getpos('.')
  return ['v', head_pos, tail_pos]
endfunction

function! CurrentLineI()
  normal! ^
  let head_pos = getpos('.')
  normal! g_
  let tail_pos = getpos('.')
  let non_blank_char_exists_p = getline('.')[head_pos[2] - 1] !~# '\s'
  return
  \ non_blank_char_exists_p
  \ ? ['v', head_pos, tail_pos]
  \ : 0
endfunction

Text objects for a specific filetype

Define a( to select text from \left( to the matching \right), and define i( to select text inside \left( to the matching \right), but only for tex files:

call textobj#user#plugin('tex', {
\   'paren-math': {
\     'pattern': ['\\left(', '\\right)'],
\     'select-a': [],
\     'select-i': [],
\   },
\ })

augroup tex_textobjs
  autocmd!
  autocmd FileType tex call textobj#user#map('tex', {
  \   'paren-math': {
  \     'select-a': '<buffer> a(',
  \     'select-i': '<buffer> i(',
  \   },
  \ })
augroup END

Further reading

You can define your own text objects like the above examples. See also the reference manual for more details.

There are many text objects written with vim-textobj-user. If you want to find useful ones, or to know how they are implemented, see a list of text objects implemented with vim-textobj-user.

vim-textobj-user's People

Contributors

blueyed avatar drewdeponte avatar idbrii avatar kana avatar tandrewnichols avatar tommcdo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vim-textobj-user's Issues

Support "inner line selection"

Suppose the following:

  if (a==b) begin : alabel
    func1();
    func2();
  end
  else begin
    func3();
    func4();
  end

It would be interesting if textobj could line-select (region-type=V) the lines between begin .. end with "vi". With "va" all lines would be selected.
So what I am asking for is a plugin property that enables such selection automatically.

In fact, I don't know if it wouldn't make sense to have the behavior by default when using "V" region type, because otherwise "va" selects the same lines as "vb".

Work on support for count (like v2ib, v3ib, …)

Hi Kana,
I wanted to add support for a count parameter to vim-textobj-user as I would like to use this with a custom brace-delimited-code text object I wrote.
In vanilla vim the following is equivalent: v3abvababab. Using this plugin only the right hand side works.


The basic approach would be to remove the <C-U> from the RHS of generated mappings and instead implement range-accepting functions (see [range] in :help :function and :help :call).

For the s:mapargs_… functions a simple implementation might be:

function! textobj#user#range_proxy(name, ...) range
  let count = a:lastline - a:firstline + 1
  let fun = 'textobj#user#'.name

  if !exists('*'.fun)
    throw 'Unknown function name: ' . string(fun)
  endif

  let expr = fun.'('.join(map(copy(a:000), 'string(v:val)'), ',').')'
  for _ in range(cout)
    call eval(expr)
  endfor
endfunction
function! s:mapargs_single_move(lhs, pattern, flags, previous_mode)
  return printf('<silent> %s  '.
              \ ':call textobj#user#range_proxy("move", %s, %s, %s)<CR>',
              \ a:lhs,
              \ string(a:pattern), string(a:flags), string(a:previous_mode))
endfunction

function! s:mapargs_single_select(lhs, pattern, flags, previous_mode)
  return printf('<silent> %s  '.
              \ ':call textobj#user#range_proxy("select", %s, %s, %s)<CR>',
              \ a:lhs,
              \ string(a:pattern), string(a:flags), string(a:previous_mode))
endfunction

function! s:mapargs_pair_select(lhs, pattern1, pattern2, flags, previous_mode)
  return printf(
       \   '<silent> %s  '.
       \   ':call textobj#user#range_proxy("select_pair", %s, %s, %s, %s)<CR>',
       \   a:lhs,
       \   string(a:pattern1), string(a:pattern2),
       \   string(a:flags), string(a:previous_mode)
       \ )
endfunction

The select_function_wrapper style mappings would also need to be adjusted. Before going any further I would however like to hear your opinion on how you would like this to be implemented or if you have some different idea.

Native option for blackhole register

Some of textobj classes aren't supposed to copy anything into registers "by design".
Suppose we have this class of command:

nmap <buffer> <Plug>(nou-set-goal-postpone) <Plug>(textobj-nou-goal-i)><Esc>

Workflow:

  • [_] task exists in today's agenda
  • I decided not to do it today, but want to keep entry for future -- to find out when it was planned previously
  • so I copy task line yy, and mark task as "postponed" by above mentioned mapping
  • then I move to next week agenda and past previously copied task

Problem:

  • yank buffer contains previously deleted value i.e. _ instead of whole task line

Of course, it can be solved by ad-hoc black hole register:

nmap <buffer> <Plug>(nou-set-goal-postpone) "_c<Plug>(textobj-nou-goal-i)><Esc>

Question:

  • is using such adhoc mapping reasonable and reliable?
  • is such usecase (avoiding copying) frequent in the world?
  • will providing per-mapping option to textobj spec would be better for centralizing efforts?

'< and '> are not restored with right unit

From: #56 (comment)

Perhaps semi-related: I'm noticing that when I specifically do a yie, the '< and '> marks are no longer what they should be if the last visually-selected area was character-wise (i.e. a word)

For example, vjjj<Esc>yaegv reselect the same region as vjjj but it is line-wise instead of character-wise.

Handling startpos == endpos (a.k.a an empty selection, not 0)

If you highlight the left bracket in hello [] and type ci[, the inside of the brackets will be selected to start replacing which is the default text object. As far as I can tell, there is no way of indicating this behavior using the plugin. Is there something I missed, or should I look to try to modify textobj-user, and if so, do you have a suggestion where to start?

Matching a single newline results in unexpected behaviour

call textobj#user#plugin('newline', {
\   '-': {  
\     'pattern': '\n',
\     'select': 'n',
\   },
\ })

Instead of matching a single newline like expected, this matches from the previous newline to the following newline. This persists even with the 'cursor' scan type. It seems to work when the cursor is somehow on the newline character (such as on blank lines).

This issue is specific to newlines. Changing the matched character to something else matches the single character like expected.

This arose when I was trying to match whitespace with:

call textobj#user#plugin('space', {
\   '-': {  
\     'pattern': '\S\zs\_s\+',
\     'select': 's',
\   },
\ })

Which works as expected for every case except for single newlines.

getpos returns the wrong result when in visual mode

If a selection function is called when in visual mode, the function thinks that the cursor is positioned at the beginning of the selection, even if it is at the end.

The following code illustrates the problem.

call textobj#user#plugin('test', {
\      '-': {
\        'select-a': 'at',  '*select-a-function*': 'Select_a_test',
\      }
\    })

function! Select_a_test()
  let startpos = getpos('.')
  echom "Cursor at ".string(startpos)
  echom "Current mode: ".mode()

  return ['V', startpos, startpos]
endfunction

Now edit any file, and in normal mode do ggVGat. Only the first line is selected, and :messages displays Cursor at [0,1,1,0], although the cursor was on the last line. It should only select the last line.

Furthermore, :messages displays Current mode: n, so the function thinks we are in normal mode, although we are in visual line. (I don't know whether that can really be regarded as a bug. But if we knew that we are in visual mode, we could use this information to expand the selection to the outer block, if the visual selection already selects a block.)

Missing LICENSE file

Hi,

I would like to use your plugin, but I'm not sure if it is covered by the Vim license or some other license. It would be great to add the usual LICENSE file to indicate it.

Thanks in advance!

Column position is incorrect when using tabs

textobj-user treats input columns as byte positions instead of screen positions. This makes writing plugins work with tab indentation difficult. I think often people don't consider virtual columns, so if textobj-user did it by default more plugins could "just work".

Take this tab-aware variation of the example line selection:

call textobj#user#plugin('line', {
\   '-': {
\     'select-i-function': 'CurrentLineI',
\     'select-i': 'il',
\   },
\ })

" This function is the main difference from the README example: We use virtcol.
function! s:get_cursor_screenpos()
    let pos = getpos('.')
    let pos[2] = virtcol('.')
    return pos
endf

function! CurrentLineI()
  normal! ^
  let head_pos = s:get_cursor_screenpos()
  normal! g_
  let tail_pos = s:get_cursor_screenpos()
  let non_blank_char_exists_p = getline('.')[head_pos[2] - 1] !~# '\s'
  return
        \ non_blank_char_exists_p
        \ ? ['v', head_pos, tail_pos]
        \ : 0
endfunction

If we convert the file to use tabs and try to select the first let line, it will miss the l and select text after the last ).

We could try to make our plugin tab-aware, but we need to convert virtcol to col. We can do this by positioning the cursor:

function! s:cursor_to_screenpos(pos)
  call cursor(a:pos)
  " Move to input screen column instead of byte index. Assumes input used
  " virtcol.
  execute 'normal! '. a:pos[1] .'|'
endfunction

function! s:virtpos_to_bytepos(vpos)
  let save = winsaveview()
  call s:cursor_to_screenpos(a:vpos)
  let bpos = a:vpos
  let bpos[1] = col('.')
  call winrestview(save)

  return bpos
endfunction

And change CurrentLineI's return to:

return
      \ non_blank_char_exists_p
      \ ? ['v', s:virtpos_to_bytepos(head_pos), s:virtpos_to_bytepos(tail_pos)]
      \ : 0

But this doesn't actually work (maybe I'm missing something). I suppose I could store the byte position when initially determining columns, but I'm searching for the desired selection region and that searching needs to use virtual columns -- so I'd have to store both.

Instead, can textobj-user accept virtual columns? Or provide an option to support them?

Operator with "motion force" is not supported

I realize that you already know this problem very well. But since there is no issue on the issue tracker I figured I'd open one.

Steps to reproduce (_ means space):

On a line containing just

___word__

with the cursor on "word", diw deletes the word and leaves us with

_____

The command dViw deletes the same but "linewise", which means that effectively the whole line is deleted.

Using textobj-line to do the same thing: dil is the same as diw, but with dVil the "linewise" motion force is ignored.

This is not a useful example but it illustrates the problem.

Documentation is at :h o_v. I have reopened the discussion on the vim_dev mailing list:

https://groups.google.com/d/msg/vim_dev/MNtX3jHkNWw/bhL-o6TlKtgJ

vim-textobj-user not working with vim-operator-replace

As you can tell, I'm an avid user of your plugins, but it seems as if there's a problem.

I've tried with a few different textobj like line and quote, and it seems as if replace doesn't work only with user defined textobjects. For example if the textobj is quote and replace is mapped to _, then in the middle of a quote "+_iq fails pulling instead the " register, but "+_i" works fine.

Is this a known bug?

User text-objects reference

I'm already using a bunch of plugins making use of vim-textobj-user and sometimes it's hard to remember what text-objects are contributed by which plugin, or what's available for the current filetype. Is there a way to list them or how hard would that be?

Buffer local textobj mappings in documentation

This plugin is great for defining filetype specific text objects, but it seems they are often defined globally because users don't know how to make them specific to a buffer.

The ability to add <option> flags to mappings, including the <buffer> flag, should be stated more clearly in the documentation. I thought this was impossible for a long time before looking at the source code.

Example: The below is in my .vimrc and defines a bunch of latex related text objects.

" Declare text objects
augroup tex_textobjs
  au!
  au FileType tex call textobj#user#plugin('latex', s:tex_textobjs_dict)
augroup END

" TeX plugin definitions
" Copied from: https://github.com/rbonvall/vim-textobj-latex/blob/master/ftplugin/tex/textobj-latex.vim
let s:tex_textobjs_dict = {
  \   'environment': {
  \     'pattern': ['\\begin{[^}]\+}.*\n', '\\end{[^}]\+}.*$'],
  \     'select-a': '<buffer> aT',
  \     'select-i': '<buffer> iT',
  \   },
  \  'command': {
  \     'pattern': ['\\\S\+{', '}'],
  \     'select-a': '<buffer> at',
  \     'select-i': '<buffer> it',
  \   },
  \  'paren-math': {
  \     'pattern': ['\\left(', '\\right)'],
  \     'select-a': '<buffer> a(',
  \     'select-i': '<buffer> i(',
  \   },
  \  'bracket-math': {
  \     'pattern': ['\\left\[', '\\right\]'],
  \     'select-a': '<buffer> a[',
  \     'select-i': '<buffer> i[',
  \   },
  \  'curly-math': {
  \     'pattern': ['\\left\\{', '\\right\\}'],
  \     'select-a': '<buffer> a{',
  \     'select-i': '<buffer> i{',
  \   },
  \  'angle-math': {
  \     'pattern': ['\\left<', '\\right>'],
  \     'select-a': '<buffer> a<',
  \     'select-i': '<buffer> i<',
  \   },
  \  'dollar-math-a': {
  \     'pattern': '[$][^$]*[$]',
  \     'select': '<buffer> a$',
  \   },
  \  'dollar-math-i': {
  \     'pattern': '[$]\zs[^$]*\ze[$]',
  \     'select': '<buffer> i$',
  \   },
  \  'quote': {
  \     'pattern': ['`', "'"],
  \     'select-a': "<buffer> a'",
  \     'select-i': "<buffer> i'",
  \   },
  \  'quote-double': {
  \     'pattern': ['``', "''"],
  \     'select-a': '<buffer> a"',
  \     'select-i': '<buffer> i"',
  \   },
  \ }

Underscore in pattern is not recognized

Hi,

I don't know if I'm doing sth wrong but following code doesn't work for me:

call textobj#user#plugin('handyobjects', {
  'underscores': {
    'select-i': 'iu',
    'select-a': 'au',
    '*pattern*': ["_", "_"]
  }
}

What I want to achieve is to select "in" and "a" text between underscore characters - "_".
But after typing "ciu" when the cursor is between underscores doesn't work, vim just enters insert mode.

Should I use something else for pattern regexps?

Regards,
Marcin

Can't auto-install textobj-user dependency with GetLatestVimScripts

In textobj-comment I try to support all plugin managers that can install dependencies automatically.

One of them is GetLatestVimScripts, which is included with Vim. Currently textobj-comment cannot be installed automatically because the textobj-user dependency isn't compatible with GetLatestVimScripts.

When is a plugin compatible with GetLatestVimScripts? When it is

  1. uploaded to vim.org as an archive, and
  2. the archive contains only runtime directories, directly at the top-level, and no extra directories or files.

Feel free to close this issue, I can understand if you don't want to support this.

'< '> overwritten

Hi Kana,

I noticed that vim-textobj-user overwrites the last visual selection, for example, with yil and vim-textobj-line.

It seems that this issue has been fixed before #55 , but in the latest version (0.7.6) this issue seems to be back again

Doesn't jump to nearest paired text object

Vim will automatically move the cusor to the next text object when target object is not under cursor.

For example, if you run di" on following example, when cursor is located at first charactor.

Here is the "target"
^

It will autojump to the target and give:

Here is the ""
             ^

This works for the regular textobj defined as

call textobj#user#plugin('quote', {
\   'a': {
\     'pattern': '".*"',
\     'select': ['aB', 'iB'],
\   },
\ })

However, for paired text object, it doesn't work (i.e. cursor does not jump automatically to the next text object when target object is not under cursor)


call textobj#user#plugin('quotep', {
\   'b': {
\     'pattern': ['"', '"'],
\     'select-a': 'aA',
\     'select-i': 'iA',
\   },
\ })


Faulty matching

I wanted to add a text object to match numbers with an optional decimal part, (eg 123 and 123.23). It seemed to work nicely, untill I found out that for certain use cases the pattern matching matches lots of extra, non-digit characters in order to find a match. If I test the pattern with a normal / search, I get the desired result.

    call textobj#user#plugin('number', {
    \   'real': {
    \     'pattern': '\v\d+(\.\d+)?',
    \     'select': ['an', 'in'],
    \   }
    \ })

I tested by launching vim as vim -u NONE, setting rpt+=~/.vim/bundle/vim-textobj-user, and souring the above code.

Then, for a test file like

2abc
         2.    abc2232

Then, by pressing either vin or van:
I get match from the first to the second number 2 if I place the cursor in front of the second number 2.
I also get a match from the second number 2 to the end if I place the cursor on the second number two.
That is, I get these matches:

<2abc
          2>

and

2abc
       <2.   abc2232>

My current vim version is 7.4.473.

I should also add that I am new to textobj-user.

Select the nearest object before OR after

It would be nice if I could create a textobject based on a pattern that would work line-based and would also work on text object before the cursor.

For example, I have a added an url textobject based on a pattern.

This works:

  • This is| my url: http://www.google.com & this is the part after.
  • ciu
  • This is my url: | & this is the part after.

But this doesn't:

vim-surround not working with custom objects

Given:

Plug 'tpope/vim-surround'
Plug 'kana/vim-textobj-user'
Plug 'kana/vim-textobj-function'
Plug 'thinca/vim-textobj-function-javascript'

And file.js:

function foo () {
  throw new Error('what?')
}

If I type ysaf to surround around the function, I get:


tore-marks)unction foo () {
  throw new Error('what?')
}

Apparently, it was caused by 7e67965

8e885f9 doesn't show this behavior

Add a way to specify region types of pattern-based text objects

Custom text objects are defined by patterns or functions. While function-based text objects can specify their region types, there is no such API for pattern-based text objects. It's better to add this, since some text objects are linewise and simple enough to be defined by patterns.

Unknown function: textobj#user#plugin in Neovim 0.2.0

Believe that's all I can say.

What --version returns:

NVIM v0.2.0
Build type: RelWithDebInfo
Compilation: /usr/bin/x86_64-linux-gnu-gcc -g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -DDISABLE_LOG -Wdate-time -D_FORTIFY_SOURCE=2 -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2 -g -DDISABLE_LOG -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wvla -fstack-protector-strong -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -I/build/neovim-LpFVCC/neovim-0.2.0/build/config -I/build/neovim-LpFVCC/neovim-0.2.0/src -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/usr/include -I/build/neovim-LpFVCC/neovim-0.2.0/build/src/nvim/auto -I/build/neovim-LpFVCC/neovim-0.2.0/build/include
Compiled by [email protected]

Feature request: Enable to define user textobj for creating surroundings

Hello @kana,

Continuing from tpope/vim-surround#250, I would like to discuss with you the possibility of making vim-textobj-user automatically (or with some none-breaking changes to the API) define a way for create surroundings of text-objects. I discussed the matter with @tpope and @lervag on lervag/vimtex#1096 as well but I'll explain my idea here with a concise example:

vim-textobj-latex defines several LaTeX specific text-objects. Take LaTeX double quotes for example:

``text''

By default, this text-object can be selected with Q. In addition, vim-textobj-latex defines a text-object for LaTeX environments such as:

\begin{environment}
text
\end{environment}

What vim-textobj-user does is enabling users to delete, clear and yank user-defined text-objects like these, that's very nice indeed. But what I would like to discuss is this:

Do you think it could be possible that in addition to deleting, clearing and yanking user-defined text-objects, while creating a text-object with textobj#user#plugin, additional mappings (inspired by vim-surround in this case) like this will be created:

  • ys<text-object-to-create-surroundings-arround><text-object's-surroundings-to-create>
  • cs<text-object-to-change-surroundings-arround><text-object's-surroundings-to-replace-with>
  • ds<text-object-to-delete-surroundings-arround>

?

Taking my question back to my original example, if you'd edit this text (let █ be the position of the cursor):

\begin{environment}
text█
\end{environment}

Pressing cseQ will change the surrounding environment with Quotes resulting in this:

█``text''

Here's another example: pressing ysieQ will (y) create surroundings inside the environment of a Quote resulting in this:

\begin{environment}
█``text''
\end{environment}

I'd be happy to know your opinion :)

Option to not scan for text object after cursor with 'select'

Vim's default text objects fail to make a selection if the cursor is not on such a text object. For example, on a line with no quotation marks, di" does nothing.

I would like to be able to have the same behaviour with custom text objects defined by textobj-user. Scanning could be enabled by default in order to keep the current behaviour intact, but perhaps a call like the following would cause the text object selection to fail if there isn't one under the cursor:

call textobj#user#plugin(
\   'pattern': '\w\+',
\   'select': ['aw', 'iw'],
\   'scan': 0  " Don't scan forwards for next text object
\)

What do you think?

How do I install this?

I tried making use of the Makefile I found in the archive, but no joy:

Davids-Air-2:vim-textobj-user-0.3.12 dbanas$ ls                                                       │
Makefile        autoload        doc             mduem           test                                  │GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Davids-Air-2:vim-textobj-user-0.3.12 dbanas$ make                                                     │[1 of 4] Compiling ConCat.Learn.Util ( /Users/dbanas/Documents/Projects/Target/concat-learn/src/ConCa
GENERATE .mduem/cache/Makefile.variables                                                              │t/Learn/Util.hs, interpreted )
make: Nothing to be done for `all'.                                                                   │[2 of 4] Compiling ConCat.Learn.DFE ( /Users/dbanas/Documents/Projects/Target/concat-learn/src/ConCat

Default select behavior

I'm not extremely familiar with vimscript, so I'm trying to avoid defining functions in order to match my textobj. Let's assume the textobj is a word for now.

By default, from what I understood, when I do this:

'pattern': '\w\+',
'select': 'iw', 'aw'

aw and iw will behave exactly the same.
I don't know if I'm missing something, but I think it would be super useful if by default a and i would behave like vim defaults: i for the pattern match, while a for the pattern match surrounded by whitespace.

Thanks!

Textobject not behaving as expected.

If I have my cursor placed in this line where the square brackets are as such: my_underscore_wor[d], and then run di_, the resulting string is my_underscore_[o]rd. Similarly, running da_ instead will produce the following: my_underscore[w]ord.

Any help in solving this issue would be appreciated!

Text object movement

Hey!

@JosephFerano noticed on a vim-textobj-variable-segment ticket that there are parameters to plugin that allow defining a function / pattern for moving to the next text object.

I've been playing around a bit with trying to hook that up, but haven't had much success, and can't really find any other text objects that use move-[n|p](-function).

From the docs, it seems like the API these functions are supposed to return is the same as the select functions, i.e. type, start_position, end_position, but I'm not sure I see how that should be necessary – it seems like move-n should want type, end_position and move-p should want type, start_position, and further, it seems like they should not really need defining separately, they're inferable from the select functions. Have I misunderstood something?

(If I add a move-n-function which is just my select-a-function I see something happen, the appropriate range looks like it's being found, but oddly, I just see it get visual selected, and the cursor doesn't keep moving if I keep move-n'ing.)

Expose mechanism for generating mappings...

textobj#user#plugin() takes an obj_spec parameter describing how to wire up the mappings. It'd be nice to expose that machinery. For instance, I've been looking at vim-textobj-diff. While I like most of what it does, I'd like to map things a little differently (use [[, ]], [], ][ to navigate hunks and have the mappings be buffer specific, and they'll be setup at filetype detect time). Unfortunately, it turns out to be quite a bit of work redoing what plugin() is already helping with. It'd be nice to avoid that, and make it so that I can do something like:

call textobj#user#mapping('diff', {
\      'file': {
\        'move-N': '<Leader>dfJ',
\        'move-P': '<Leader>dfK',
\        'move-n': '<Leader>dfj',
\        'move-p': '<Leader>dfk',
\        'select': ['adH', 'adf', 'idH', 'idf'],
\      },
\      'hunk': {
\        'move-n': ']]',
\        'move-N': '][',
\        'move-p': '[[',
\        'move-P': '[]',
\        'select': ['adh', 'idh'],
\      },
\    })

Add doc/tags to .gitignore (based on Vim 8 documentation)

I noticed in #32 that you rejected adding doc/tags to .gitignore, because you believe that people should use non-git-checkout directories as their plugins to Vim.

As of Vim 8, the packages-create documentation suggests that people should be able to git clone vim plugin repositories directly into their package directories.

Quote:

This allows for the user to do: 
        mkdir ~/.vim/pack/myfoobar
        cd ~/.vim/pack/myfoobar
        git clone https://github.com/you/foobar.git

I believe that this justifies adding doc/tags to .gitignore in this project. What do you think?

Thanks for maintaining this plugin!

Support extending the current selection by repeating a custom text object

Several built-in text objects can be repeated to extend the current selection. For example, vawawawaw... and vabababab.... It's not trivial how to extend the current selection for each custom text object, so that vim-textobj-user can't support this behavior by default. It have to be implemented by each custom text object.

To implement this behavior, it's necessary to know

  • Whether a text object is used in Visual mode, and
  • The current selection.

Perhaps the correct information cannot be retrieved with built in functions, so it might be necessary to add or extend API to provide these information.

Don't use noremap or vnoremap

noremap and vnoremap also map keystrokes in select mode, which is not the desired behavior. Instead, you should use onoremap, xnoremap, and nnoremap.

Apply command to each line in "range" / selection

I have a command here:

nmap <buffer> <Plug>(nou-set-goal-mandatory) "_c<Plug>(textobj-nou-goal-i)!<Esc>

which works as [_] task -> [!] task.
Often I have multiple tasks in column and want to apply transformation in batch.
But looking through sources of textobj-user and experimenting with it had no results.
How this usecase can be implemented?
Is it outside of scope of textobj-user or is it not solvable in general?
Am I supposed to write "range" function wrapper and apply textobj manually to each line?

add tags to .gitignore?

Great plugin, thanks.

Can you add tags to .gitignore file to prevent git complaints about modified content when using tags and this plugin is added as git submodule?

'*pattern*': [a, b] does not work when a and b are equal

I'm creating text objects for LaTeX code. In LaTeX, inline equations can be typed \(like this\) or $like this$. I tried to create text objects for both with the following configuration:

\  'paren-math': {
\     '*pattern*': ['\\(', '\\)'],
\     'select-a': 'a\',
\     'select-i': 'i\',
\   },
\  'dollar-math': {
\     '*pattern*': ['[$]', '[$]'],
\     'select-a': 'a$',
\     'select-i': 'i$',
\   },

but only the first one worked. I also tried '*pattern*: '[$][^$]*[$]', also with no positive results.

Am I missing something? Is there another simple way to create text objects where the delimiters are the same (like the ones vim has for quoted text) without defining the selection functions?

Suggestion: Use xmap instead of vmap

xmap targets just visual mode. vmap targets visual mode and also select mode, which I doubt that you want.

Some background on select mode: It is designed to be like selecting something in other standard editors. You select something and whatever you type immediately replaces what was selected. I believe select mode is used in snippet plugins, so I would avoid it in this plugin to avoid conflicting with those plugins.

Select text-object not strictly under the cursor

I'm not sure this is the right place to ask, but I often find myself with the cursor on the start of a line, for instance like this:

\emph{wrong text}

and trying to hit ci} to change wrong text. It feels to me like it should work, much the same as you can use <C-a> to increment the next integer on a line of text. But it does not, instead I have to do f}ci}.

I know this is not a user-defined text-object, but perhaps this plugin could also add that sort of functionality? Or is there some other preferred way of doing what I want?

Kind regards.

Simple usage instructions in a README

I don't mean for how to write a textobj, that seems pretty well documented, but for the user who wants to download and install other textobjs, it doesn't seem like anyone documents how to actually use them. It would be very nice to have a quickstart guide that shows how to wire up textobjects that you install and use them.

User-defined text objects are not correctly repeatable by `.`

See also: kana/vim-textobj-line#2

The key point is to activate Visual mode via :normal! from a motion for a pending operator. For example...

onoremap iw :<C-u>call  Select()<Return>

function! Select()
  " Select a some region without `:normal! v`.
  let p = getpos('.')
  let p[2] += 3
  call setpos('.', p)
endfunction

" Do `diw` on some text...

" Do `.`... it correctly repeats the last executed command.

delfunction Select

" Do `.`... now it raises an error about an undefined function `Select`.
" So Vim records the full key sequence of the last executed command for `.`.
" In other words, `d:<C-u>call Select()<Return>`.

function! Select()
  normal! viw
endfunction

" Do `diw` on some text... especially on a word `foo`.

" Do `.` on some text... especially on a word `barbaz`.
" It repeats the last executed command, but the result is incorrect.
" It doesn't delete a word.  It deletes 3 characters from the cursor.
" So that it repeats to delete `foo` instead of a word.

delfunction Select

" Do `.`... it doesn't raise any error, and repeats deleting `foo`.

" Therefore Vim doesn't record the correct key sequence in this case.

Allow other modifiers

Is it possible to use other modifiers rather than [a,i] ?
I like the idea of having other modifier, kind of what targets.vim does with i,I,a,A

I tried to add another kind of line text object like this:

call textobj#user#plugin('line', {
\      '-': {
\        'select-a': 'al', 'select-a-function': 'textobj#line#select_a',
\        'select-i': 'il', 'select-i-function': 'textobj#line#select_I',
\        'select-I': 'Il', 'select-I-function': 'textobj#line#select_I'
\      },
\    })

But doesn't work. Is this possible somehow? Any guidance would be very much appreciated.

Workaround to select duplicate patterns on several lines

Several issues already states that vim-textobj-user doesn't handle well a text object where the begin and the end pattern are the same (see #2 and #15).

Nevertheless @kana suggested a workaround of the following form:

call textobj#user#plugin('handyobjects', {
\   'underscores_a': {
\     'select': 'au',
\     '*pattern*': '_[^_]*_'
\   },
\   'underscores_i': {
\     'select': 'iu',
\     '*pattern*': '_\zs[^_]\+\ze_'
\   },
\ })

I was trying to adapt this workaround to be able to search for the same pattern but on different lines, It seems that no matter how I try to add a new line in the regex it doesn't work. Can it be done or is it a limitation?

The regex I tried to use was of the following form:

'pattern': '_[\n\|^_]*_'

An example of text to select would be

_
foo
bar buzz
_

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.