nmap <Leader>jk <LocalLeader>e{:keys [] :as<Esc>F[
With cursor at m
, turns
(defn inc-x
[m]
(inc x))
into
(defn inc-x
[{:keys [] :as m}]
(inc x))
with the cursor at the opening [
.
(requires vim-sexp)Nice!
very noice ๐:skin-tone-5:
If I have the following code:
(foo
)
โฆand I hit J
on the first line, I get (foo)
, which is great, but if I have this:
[foo
]
and I hit J
on the first line I get [foo ]
with an extra space before the closing bracket. Same with closing braces. Does anyone know how to tell vim not to add the extra space?I know this isn't 100% helpful, but parinfer behaves the way you'd want by default.
@jkrasnay Use gJ
instead ๐ See :help J
if you scroll down a little, you'll see the info about why ) doesn't have a space.
gJ
leaves all the leading space. I kinda want the opposite, to remove all spaces when the next line starts with ]
or }
@dave yeah I looked at Parinfer but Iโm pretty happy working with just vim-sexp. Not sure itโs worth a switch just for this issue.
@jkrasnay uhh, I'm getting different behaviour from you! According to the docs, gJ should remove all the spaces.
*gJ*
gJ Join [count] lines, with a minimum of two lines.
Don't insert or remove any spaces.
Maybe do nmap gJ
to see if anything might be interfering?
"doesn't insert or remove spaces"
doesn't that mean the whitespace is preserved from the previous line
The example didn't have any whitespace ๐ Maybe we're working from a different example then.
maybe it's a tabs vs spaces things
maybe tabs are removed but spaces are not
But what kind of monster would use tabs?
Indeed, haha.
nope same behavior with tab infront
I suspect you're right about it being a problem with leading spaces. The examples above didn't have any, so in real world it probably has leading whitespace which gJ won't touch.
noremap J Jx
seems to work
oh except when the next line is only whitespace it deletes the last char of the current line...
Looks like you have to go into vimscript
well, that's just cheating
I reckon you could do something with multiline regex, just for "J"
This one works pretty well
nmap <C-J> gJi <ESC>diW
:s/\s*\n\s*//
(with nnoremap ofc)
Thanks for all the ideas. It looks like itโs a tricky problem to solve generally, partly because J
can work with a visual selection or line count and partly because in some cases you do want the space, e.g.
[foo
bar]
โฆshould join to [foo bar]
That is true ๐ So I suppose something like :s/\s*\n(\s*\[)}]]//
(without actually trying it, that is)
I ended up maping gJ to do that whitespace removing sine I never used that keybinding normally
I came up with this. Seems to work pretty well:
:nnoremap J J:s/\s*\([]}]\)/\1/g<cr>:noh<cr>
:vnoremap J J:s/\s*\([]}]\)/\1/g<cr>:noh<cr>
The regex seems to work. I wanted to keep the cursor position, and not put the regex in my search register so i call it in a function:
fun ClojureJ()
let l:line = getline('.')
call setline('.', substitute(l:line, '\s*\([]}]\)', '\1', "g"))
endfun
nmap J J:call ClojureJ()<cr>
Thatโs much nicer, thanks!
I also noticed that join leaves trailing spaces after opening brackets and braces. Made this small tweak:
fun ClojureJ()
let l:line = getline('.')
let l:line = substitute(l:line, '\s\+\([]}]\)', '\1', "g")
let l:line = substitute(l:line, '\([[{]\)\s\+', '\1', "g")
call setline('.', l:line)
endfun
nnoremap J J:call ClojureJ()<cr>
vnoremap J J:call ClojureJ()<cr>