-
Notifications
You must be signed in to change notification settings - Fork 59
Patched indent object.vim
Sorry, I am not able to send you a file using email at the moment.
Here is a small refactorings:
- prevnonblank and nextnonblank builtin functions are used instead of checking for `’^\s*$`
- start value of `idnt` is indent of the first line in a given range instead of 1000
- linewise selection, thus column range (c0, c1) is not needed anymore
- small changes here and there
Could you pls check it?
PS.
Looks like it doesn’t respect top level blocks.
" vim: noet sw=2 ts=2 "-------------------------------------------------------------------------------- " " Copyright (c) 2010 Michael Smith <[email protected]> " " http://github.com/michaeljsmith/vim-indent-object " " Permission is hereby granted, free of charge, to any person obtaining a copy " of this software and associated documentation files (the "Software"), to " deal in the Software without restriction, including without limitation the " rights to use, copy, modify, merge, publish, distribute, sublicense, and/or " sell copies of the Software, and to permit persons to whom the Software is " furnished to do so, subject to the following conditions: " " The above copyright notice and this permission notice shall be included in " all copies or substantial portions of the Software. " " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING " FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS " IN THE SOFTWARE. " "-------------------------------------------------------------------------------- " Mappings excluding line below. onoremap <silent>ai :<C-u>cal TextObject(0, 0, [line("."), line(".")])<CR> onoremap <silent>ii :<C-u>cal TextObject(1, 0, [line("."), line(".")])<CR> vnoremap <silent>ai :<C-u>cal TextObject(0, 0, [line("'<"), line("'>")])<CR><Esc>gv vnoremap <silent>ii :<C-u>cal TextObject(1, 0, [line("'<"), line("'>")])<CR><Esc>gv " Mappings including line below. onoremap <silent>aI :<C-u>cal TextObject(0, 1, [line("."), line(".")])<CR> onoremap <silent>iI :<C-u>cal TextObject(1, 1, [line("."), line(".")])<CR> vnoremap <silent>aI :<C-u>cal TextObject(0, 1, [line("'<"), line("'>")])<CR><Esc>gv vnoremap <silent>iI :<C-u>cal TextObject(1, 1, [line("'<"), line("'>")])<CR><Esc>gv function! TextObjectCount(inner, incbelow, range, count) " Record the current state of the visual region. let l0 = a:range[0] let l1 = a:range[1] " Repeatedly increase the scope of the selection. let cnt = a:count while cnt > 0 " Look for the minimum indentation in the current visual region. " Skip empty lines. let l = l0 let idnt = indent(nextnonblank(l)) while l > 0 && l <= l1 let idnt = min([idnt, indent(l)]) let l = nextnonblank(l+1) endwhile " Search backward for the first line with less indent than the target " indent (skipping blank lines). let l_1 = l0 let l_1o = l_1 while l_1 > 0 && indent(l_1) >= idnt let l_1o = l_1 let l_1 = prevnonblank(l_1-1) endwhile " Search forward for the first line with more indent than the target " indent (skipping blank lines). let l2 = l1 let l2o = l2 while l2 != 0 && indent(l2) >= idnt let l2o = l2 let l2 = nextnonblank(l2+1) endwhile " Determine which of these extensions to include. Include neither if " we are selecting an 'inner' object. Exclude the bottom unless are " told to include it. let idnt2 = max([indent(l_1), indent(l2)]) if indent(l_1) < idnt2 || a:inner let l_1 = l_1o endif if indent(l2) < idnt2 || a:inner || !a:incbelow let l2 = l2o endif let l_1 = max([l_1, 1]) let l2 = min([l2, line("$")]) " Check whether the visual region has changed. let chg = 0 let chg = chg || l0 != l_1 let chg = chg || l1 != l2 " Update the vars. let l0 = l_1 let l1 = l2 " If there was no change, then don't decrement the count (it didn't " count because it didn't do anything). if chg let cnt = cnt - 1 else let l0 = prevnonblank(l0-1) endif endwhile " Apply the range we have found. call cursor(l0, 1) normal! V call cursor(l1, 1) endfunction function! TextObject(inner, incbelow, range) call TextObjectCount(a:inner, a:incbelow, a:range, v:count1) endfunction
Comments (Michael Smith)
Hi habamax – thankyou for your patch! I’m really glad at least one person is interested in the plugin :)
However, I had a couple of problems with the patch:
Firstly, as you noticed the top level behaviour was altered. This was because the code that resets the terminal positions was changed to use prevnonblank()/nextnonblank() in some way. Using these built-in functions is probably faster than using the re, but I think the code as it is is more flexible.
Also, the new patch uses line mode as you pointed out. After thinking about it, I think it’s bad that the plugin changes the visual mode to either normal or line based. Therefore in the latest code it now maintains whatever visual mode was in effect (including block mode).
It would be great if you could get the latest code and check it out again. It addresses one of your issues, but not the other (I’ll also comment on the issues).
I am sure that 99% would like to operate with inner blocks using line selection. And it is really ok to change visual mode to line based. For example builtin `vap` does it.
Besides that if you press `vii` for the first time what would be the previous visual mode?
Maxim Kim
What I mean is that pressing v has already entered (normal) visual mode, pessing ai after that just extends the selection. If you want to enter line select mode, you can type Vai instead. You can keep pressing ai after that – for instance vaiai is the same as v2ai. I don’t want to force the user into one mode or another – in particular since I’ve updated the ii mapping so that it works better with indentation.
Yeah, I understand. Btw, with `Vii` you can not extend selection further as with `vii`
Maxim Kim