Fork me on GitHub
#vim
<
2021-06-25
>
walterl01:06:07

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)

😍 6
berkeleytrue03:06:35

very noice 👌:skin-tone-5:

jkrasnay15:06:04

If I have the following code:

(foo
)

jkrasnay15:06:28

…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?

👀 2
dave15:06:39

I know this isn't 100% helpful, but parinfer behaves the way you'd want by default.

dominicm15:06:41

@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.

jkrasnay15:06:37

gJ leaves all the leading space. I kinda want the opposite, to remove all spaces when the next line starts with ] or }

jkrasnay15:06:18

@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.

👍 2
dominicm15:06:06

@jkrasnay uhh, I'm getting different behaviour from you! According to the docs, gJ should remove all the spaces.

dominicm15:06:22

*gJ*
gJ			Join [count] lines, with a minimum of two lines.
			Don't insert or remove any spaces.

dominicm15:06:19

Maybe do nmap gJ to see if anything might be interfering?

berkeleytrue15:06:52

"doesn't insert or remove spaces"

berkeleytrue15:06:11

doesn't that mean the whitespace is preserved from the previous line

dominicm15:06:31

The example didn't have any whitespace 😄 Maybe we're working from a different example then.

berkeleytrue15:06:42

maybe it's a tabs vs spaces things

berkeleytrue15:06:51

maybe tabs are removed but spaces are not

dominicm15:06:01

But what kind of monster would use tabs?

berkeleytrue15:06:36

nope same behavior with tab infront

dominicm15:06:09

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.

berkeleytrue15:06:37

noremap J Jx seems to work

berkeleytrue15:06:11

oh except when the next line is only whitespace it deletes the last char of the current line...

dominicm15:06:36

Looks like you have to go into vimscript

berkeleytrue15:06:39

well, that's just cheating

dominicm15:06:58

I reckon you could do something with multiline regex, just for "J"

berkeleytrue15:06:32

This one works pretty well

nmap <C-J> gJi <ESC>diW

dominicm15:06:45

:s/\s*\n\s*//

dominicm15:06:04

(with nnoremap ofc)

jkrasnay16:06:30

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]

dominicm17:06:47

That is true 🙂 So I suppose something like :s/\s*\n(\s*\[)}]]// (without actually trying it, that is)

berkeleytrue18:06:06

I ended up maping gJ to do that whitespace removing sine I never used that keybinding normally

jkrasnay19:06:49

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>

Sigve07:06:00

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>

1
jkrasnay13:06:53

That’s much nicer, thanks!

jkrasnay13:06:39

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>

🎉 4