-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update vim section movement mappings to support hanging indents. #11492
Conversation
else | ||
nmap <buffer> ][ /\}<CR>b99]} | ||
nmap <buffer> ]] j0[[%/\{<CR> | ||
endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this mapcheck('/') == ''
check? That makes it very fragile. I presume you are assuming that the alternative is map / /\v
; this is very dangerous: it may well not be the case. This sort of thing is why you should use noremap
rather than map
. (That means doing things like expanding the [[ in the ]] mapping manually—very well, that's what needs to be done to make it robust.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There, I'm done with comments for now. If I haven't made myself clear or if you disagree on any points, just holler. :-) |
|
|
Thanks, that's fixed up those problems—but after trying it I still find myself unhappy, partly because I didn't think through all the implications (and didn't try it before):
I'll see if I can figure a way to fix up these issues. |
I believe I've got it pretty much sorted out now. diff --git a/src/etc/vim/ftplugin/rust.vim b/src/etc/vim/ftplugin/rust.vim
index 281a63e..dcd4f44 100644
--- a/src/etc/vim/ftplugin/rust.vim
+++ b/src/etc/vim/ftplugin/rust.vim
@@ -42,4 +42,55 @@ if exists("g:loaded_delimitMate")
let b:delimitMate_excluded_regions = delimitMate#Get("excluded_regions") . ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
endif
-let b:undo_ftplugin = "setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd< | if exists('b:rust_original_delimitMate_excluded_regions') | let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions | unlet b:rust_original_delimitMate_excluded_regions | elseif exists('b:delimitMate_excluded_regions') | unlet b:delimitMate_excluded_regions | endif"
+" Bind motion commands to support hanging indents
+nnoremap <silent> <buffer> [[ :call <SID>Rust_Jump('n', 'Back')<CR>
+nnoremap <silent> <buffer> ]] :call <SID>Rust_Jump('n', 'Forward')<CR>
+xnoremap <silent> <buffer> [[ :call <SID>Rust_Jump('v', 'Back')<CR>
+xnoremap <silent> <buffer> ]] :call <SID>Rust_Jump('v', 'Forward')<CR>
+onoremap <silent> <buffer> [[ :call <SID>Rust_Jump('o', 'Back')<CR>
+onoremap <silent> <buffer> ]] :call <SID>Rust_Jump('o', 'Forward')<CR>
+
+let b:undo_ftplugin = "
+ \setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd<
+ \|if exists('b:rust_original_delimitMate_excluded_regions')
+ \|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions
+ \|unlet b:rust_original_delimitMate_excluded_regions
+ \|elseif exists('b:delimitMate_excluded_regions')
+ \|unlet b:delimitMate_excluded_regions
+ \|endif
+ \|nunmap <buffer> [[
+ \|nunmap <buffer> ]]
+ \|xunmap <buffer> [[
+ \|xunmap <buffer> ]]
+ \|ounmap <buffer> [[
+ \|ounmap <buffer> ]]
+ \"
+
+if exists('*<SID>Rust_Jump') | finish | endif
+
+function! <SID>Rust_Jump(mode, function) range
+ let cnt = v:count1
+ normal! m'
+ if a:mode ==# 'v'
+ norm! gv
+ endif
+ let foldenable = &foldenable
+ set nofoldenable
+ while cnt > 0
+ execute "call <SID>Rust_Jump_" . a:function . "()"
+ let cnt = cnt - 1
+ endwhile
+ let &foldenable = foldenable
+endfunction
+
+function! <SID>Rust_Jump_Back()
+ call search('{', 'b')
+ keepjumps normal! w99[{
+endfunction
+
+function! <SID>Rust_Jump_Forward()
+ normal! j0
+ call search('{', 'b')
+ keepjumps normal! w99[{%
+ call search('{')
+endfunction There are still a few caveats:
|
Awesome work @chris-morgan! I was content with a minor fix of the Anyway I'm going to close this PR and let you open up your own since at this point none of my suggested changes are relevant. :) |
(Expressed another way: make `[[` et al. work with the curly brace at the end of a line as is standard Rust style, not just at the start is it is by default in Vim, from K&R style.) This came out of rust-lang#11492, where a simpler but less effective technique was initially proposed; some discussion of the techniques, ways and means can be found there. There are still a few caveats: - Operator-pending mode behaves differently to the standard behaviour: if inside curly braces, it should delete up to and including the closing of the outermost curly brace (that doesn't seem to me consistent with documented behaviour, but it's what it does). Actual behaviour (the more logical and consistent, in my opinion): up to the start of the next outermost curly brace. - With folding enabled (`set fdm=syntax`), `[[` and `]]` do not behave as they should: the default behaviour treats an entire closed fold as one line for these purposes while this code does not (I explicitly `set nofoldenable` in the function—the side-effects are worse with folds enabled), leading to unexpected behaviour, the worst of which is `[[` and/or `]]` not working in visual mode on a closed fold (visual mode keeps it at the extreme end of the region line of the folded region, so it's always going back to the opening line of that fold and immediately being shoved back to the end by visual mode). - `[[` and `]]` are operating inside comments, whereas the standard behaviour skips comments. - The viewport position is sometimes changed when it should not be necessary.
(Expressed another way: make `[[` et al. work with the curly brace at the end of a line as is standard Rust style, not just at the start is it is by default in Vim, from K&R style.) This came out of rust-lang#11492, where a simpler but less effective technique was initially proposed; some discussion of the techniques, ways and means can be found there. There are still a few caveats: - Operator-pending mode behaves differently to the standard behaviour: if inside curly braces, it should delete up to and including the closing of the outermost curly brace (that doesn't seem to me consistent with documented behaviour, but it's what it does). Actual behaviour (the more logical and consistent, in my opinion): up to the start of the next outermost curly brace. - With folding enabled (`set fdm=syntax`), `[[` and `]]` do not behave as they should: the default behaviour treats an entire closed fold as one line for these purposes while this code does not (I explicitly `set nofoldenable` in the function—the side-effects are worse with folds enabled), leading to unexpected behaviour, the worst of which is `[[` and/or `]]` not working in visual mode on a closed fold (visual mode keeps it at the extreme end of the region line of the folded region, so it's always going back to the opening line of that fold and immediately being shoved back to the end by visual mode). - `[[` and `]]` are operating inside comments, whereas the standard behaviour skips comments. - The viewport position is sometimes changed when it should not be necessary.
…ure, r=Centri3 Fix mutaby used async function argument in closure for `needless_pass_by_ref_mut` Fixes rust-lang/rust-clippy#11380. The problem was that it needed to go through closures as well in async functions to correctly find the mutable usage of async function arguments. changelog: Correctly handle mutable usage of async function arguments in closures. r? `@Centri3`
By default vim's section motion commands support K&R style braces. This updates the mapping to support Rust's idiomatic style of using hanging indents.