Code Monkey home page Code Monkey logo

Comments (11)

andymass avatar andymass commented on May 31, 2024

I agree a shortcut would be nice, but A and I already have distinct meaning in visual mode. Can you think of a different map? Or perhaps A%/I% only as an operator pending would be acceptable?

Visual i%/a% should already expand nicely. You don't necessarily need to press v1a%, you can just repeat va%a%a%. The intended behavior is after the first selection, only full blocks are selected.

Currently, v9a% doesn't work (same with vim's v9ab), but I will see if it can be done easily.

from vim-matchup.

andymass avatar andymass commented on May 31, 2024

Implementing v9a% is harder than I imagined. The reason is currently there is no way to determine if a delimiter is at the highest level or not. There could always be wrapped if/endif around any piece of code 100s of lines away. So what would need to happen is v9a% would search until a timeout, and pick the outermost scope found so far. I think this delay would be distracting. Any ideas?

from vim-matchup.

kiryph avatar kiryph commented on May 31, 2024

Hi, sorry for my delayed response and nice to hear that you think it could be a sensible feature.

  1. Commit Tweak i% text object
    Can you explain to me your commit from last December 7418342?

  2. Choice of mapping
    I didn't thought about this properly. I had remembered that the plugin https://github.com/wellle/targets.vim uses capital A and I.
    Of course, you are right that they have a distinct meaning in visual block mode which I actually use quite often (:h v_b_I). I am suprised that I overlooked this.
    The plugin targets.vim does not document its behavior properly: you have to read issues, commit messages and commit discussions to see how it handles this. It seems to be that they are supported in visual mode but not in visual-block mode: wellle/targets.vim#25.
    (previous commit and issue: wellle/targets.vim#9, wellle/targets.vim#23). Would you add a similar behavior?

  3. Second a% always selects full blocks: A% would only be useful for first invocation
    Your point that after the first a% only full blocks are selected makes this issue look a little bit dumb 😞. However, having them for operator pending mode might be a justification for this.

  4. v9a% as shorthand to select the outer most matching pair
    This would be great and I did not originally have this in mind. However, I also do not know a clever answer how to achieve this fast and reliable. Adding an option to limit the search similar to :h :syn-sync-maxlines could keep it responsive and provide a solution for a majority of cases. If the outer is not matched, manually pressing a% should still work.

However, I would already be happy (😄) ifvA% and vI% work as synonyms for v1a% and v1i% in visual mode excluding visual block and A% and I% in operating pending mode even though as discussed it is not a huge improvement.

from vim-matchup.

andymass avatar andymass commented on May 31, 2024

Can you explain to me your commit from last December 7418342?

I don't completely remember all the details, but it was to fix up a number of corner cases in the text objects (there are many). The most important change was to make ci% work properly for function() (this is actually really difficult in vim). It was tangentially related to this issue because there were some cases the count wasn't handled as documented.

Choice of mapping

Do you use targets.vim? I would have to be careful to not introduce an incompatibility. Would it be strange if A%/I% do not behave like the other targets.vim maps, like A(?

from vim-matchup.

kiryph avatar kiryph commented on May 31, 2024

Thanks for your notes about the commit.

Do you use targets.vim?

No, I don't use targets.vim. So it would not be strange if they behave different.

The last time I tried targets.vim the added startup time was for me one of the showstopper. Apparently, there has been a change: wellle/targets.vim#199.

I have already encountered compatibility issues between at least one other plugin and targets.vim. However, I can't remember which one it was and actually which one was to blame.

On the other side, I am not sure whether targets.vim could be considered as a mainstream plugin such as surround or fugitive. I admit that I think it is one of the plugins noteworthy in the vim plugin world. People at https://www.vi-improved.org/plugins/ seem to agree.

That said, these are plugins that the #vim community considers "do no harm" plugins. "Do no harm" plugins don't break core Vim features and play nice with other plugins (try not to conflict with keybindings, etc) and respect your settings and colorscheme.

  • ...
  • targets: adds various text objects to give you more targets to operate on
  • ...

The plugins they do not like are listed here https://www.vi-improved.org/loathing/ (most notably: airline and YCM) and unrecommended/unneeded plugins are https://www.vi-improved.org/recommendations/.

from vim-matchup.

andymass avatar andymass commented on May 31, 2024

Regarding the first issue, you can place this in your vimrc/configs (there is no actual match-up dependency):

function! s:matchup_convenience_maps()
  xnoremap <sid>(std-I) I
  xnoremap <sid>(std-A) A
  xmap <expr> I mode()=='<c-v>'?'<sid>(std-I)':(v:count?'':'1').'i'
  xmap <expr> A mode()=='<c-v>'?'<sid>(std-A)':(v:count?'':'1').'a'
  for l:v in ['', 'v', 'V', '<c-v>']
    execute 'omap <expr>' l:v.'I%' "(v:count?'':'1').'".l:v."i%'"
    execute 'omap <expr>' l:v.'A%' "(v:count?'':'1').'".l:v."a%'"
  endfor
endfunction
call s:matchup_convenience_maps()

Warning up front: it is definitely not compatible with targets.vim. I am reluctant to make these maps default or even an option but I could make a note in the docs about it.

from vim-matchup.

kiryph avatar kiryph commented on May 31, 2024

Thanks for your code snippet! It works great.

I can understand your hesitation to add it to matchup itself. I think adding a note to the docs would be good enough together with a note about compatibility issues with plugins such as targets.vim.

from vim-matchup.

kiryph avatar kiryph commented on May 31, 2024

I have another question: Why does the second, third and so forth a% always select full blocks?

Consider a nested if construct:

function! s:test()

    if l:x == 1
        if l:y == "hello andy"
            echom "hello andy" " CURSOR
        endif
        call one()
    else
      call two()
    elseif
      call three()
    endif

    let l:str = "hello"

    return l:str

endfunction

If I want to select the first outer if-branch, I can only do this if the cursor is not located on the nested if.
I think this makes a% less flexible than a user would expect.

from vim-matchup.

andymass avatar andymass commented on May 31, 2024

Why does the second, third and so forth a% always select full blocks?

It simplified the internal logic. I'm willing to re-visit it because I noticed some other unrelated problems.
Also there is no way to target "second partial block" in one go. With one block you have i% and 1i%, but with two you only have 2i%, and since count > 0 it selects full blocks. I think I am OK with incremental logic working differently to numbered logic (i.e., i%i% will be different from 2i%).

Anyway, I've been holding off because I can't decide on the exact behavior. Here is an example,

function! Fcn()
    " cursor 1
    if 0
        " cursor 2
        return
        " cursor 3
    else
        " cursor 4
        return
        " cursor 5
    endif
    " cursor 6
endfunction

What should vi% select in each of the 6 cases?

from vim-matchup.

kiryph avatar kiryph commented on May 31, 2024

In your example there is ambiguity because of intertwined blocks:

 1      +    function! Fcn()
 2      |        " cursor 1
 3      |        if 0             +
 4      |            " cursor 2   |
 5      +            return       |
 6      |            " cursor 3   |
 7      |        else             +
 8      |            " cursor 4   |
 9      +            return       |
10      |            " cursor 5   |
11      |        endif            +
12      |        " cursor 6
13      +    endfunction

Different user might have different expectations what vi% should do.

I would argue that an inner any-block (here the if-block with the else branch) should take higher precedence than an outer any-block (here the function block with the return expressions).

This means for vi% :

  • cursor 1: Selects from the word function to the first return.
  • cursor 2 and 3: Selects the inner if branch
  • cursor 4 and 5: selects the inner else branch
  • cursor 6: selects the text after the last return expression.
  • a user cannot select the text between the first return and second return expression.

When pressing vi%i% the cursor is moved after the first selection, and therefore changes what possibly is considered the intended block.

I admit this is a difficult problem and there might be no solution which will make everyone happy.

I think my original issue is actually solved and therefore I close it.

from vim-matchup.

andymass avatar andymass commented on May 31, 2024

FYI, I re-wrote the text objects so you can now target outer if..else blocks. It's now fairly close to what you suggest and I think it makes sense this way. v2i% has changed meaning since it no longer targets whole blocks only.

You can also choose to set g:matchup_delim_count_fail=1 and then vi9% will work, although it's not perfect. See also g:matchup_delim_count_max. The interface isn't completely stable and it's not all documented yet.

from vim-matchup.

Related Issues (20)

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.