jeetsukumaran / vim-indentwise

A Vim plugin for indent-level based motion.
220 stars 17 forks source link

Have relative indent movement include end line #12

Open psycotica0 opened 8 years ago

psycotica0 commented 8 years ago

It's possible this already exists, but I couldn't find it in the docs. I find a lot of the time I want to do something like this:

if (condition) {
    stuff;
    stuff;
}

And I start on the first line and if I do "y]=" It will only give me:

if (condition) {
    stuff;
    stuff;

But it'd be useful to have the option to include that last line too. Also super useful for xml, or anything with nesting. Except python.

Does this exist?

eedrah commented 6 years ago

I'd be interested in this too. Anyone have an interim solution?

cascassette commented 4 years ago

I have this problem as well. This in vim is the difference between inclusive and exclusive motions, and I've searched through the source code for those words. It seems it should be fixable, what we all want is that in operator mode (after d, y, etc) it is inclusive, right? I'll see if I can come up with something.

edit: basically it's just changing the ones in the onoremap lines: https://github.com/jeetsukumaran/vim-indentwise/blob/master/plugin/indentwise.vim#L403 to zeroes. Restart vim, done, boom.

eedrah commented 4 years ago

Oh great, good job! I wonder, is there a way to do it without editing the code of the plugin itself? Something that we could stick in our .vimrc?

jeetsukumaran commented 4 years ago

Thanks for helping out with this.

For an end-user fix, I think just suppressing keymaps and redefining them in your vimrc should work. Or just redefining /overriding them.

For a more permanent fix, it gets to be more complicated. I am hesitant to make the change without exploring what the impact would be on other languages, e.g. Python, which may or may not want the last line grabbed. If there is a language difference, then filetype-specific logic needs to be added.

eedrah commented 4 years ago

Here's the solution I've come up with for my .vimrc. First I need to define a function that can replace the <SID> in the mapping, and then I can do the remapping.

" https://stackoverflow.com/questions/24027506/get-a-vim-scripts-snr
func! GetScriptNumber(script_name)
    " Return the <SNR> of a script.
    "
    " Args:
    "   script_name : (str) The name of a sourced script.
    "
    " Return:
    "   (int) The <SNR> of the script; if the script isn't found, -1.

    redir => scriptnames
    silent! scriptnames
    redir END

    for script in split(l:scriptnames, "\n")
        if l:script =~ a:script_name
            return str2nr(split(l:script, ":")[0])
        endif
    endfor

    return -1
endfunc

onoremap <silent> <Plug>(IndentWiseNextEqualIndent)        V:<C-U>call eval(printf('<SNR>%d_move_to_indent_depth(1, "==", 0, "o")', GetScriptNumber("vim-indentwise")))<CR>
cascassette commented 1 year ago

For anybody who might have this issue in the future, I have created a fork that just has the 0 zeroes for o mode bindings as well. So you can now just put cascassette/vim-indentwise in your vim package manager if you need that behaviour. If I understand you correctly, @jeetsukumaran, you would not like this as a PR but would rather first see if this is solveable on a per-language basis (understandable) for example for Python. Is that correct?

In any case, this option will let you in C-like languages like javascript, rust, etc. do a simple y]= from a line with the start of an if, function, etc., to copy the whole block.

I'm down to look around how to make language specific behaviour happen, but not sure where to start.