vim

For discussion on all things (neo)vim.
walterl 2020-10-06T17:19:31.012600Z

What do you guys use to format large EDN blobs, on a single line, in vim? Something like passing it through pprint

walterl 2020-10-06T17:23:57.013300Z

Concrete example: I have a big Ring request, logged by timbre, so it's all on one long line

dominicm 2020-10-06T17:30:52.013800Z

Def it, then eval it

walterl 2020-10-06T17:33:31.014400Z

Some of the values are objects, so not readily deserializable 😞

Jan K 2020-10-06T17:43:46.016600Z

I have a socket REPL with cljfmt dependency on port 5353 and filter lines through a hacky oneliner shell script

echo "(do (require 'cljfmt.core)(print (cljfmt.core/reformat-string \"$(sed 's/\\/\\\\\\\\/g;s/"/\\"/g')\" $opts)))" | nc -N localhost 5353 | awk 'BEGIN{RS="\n?(nil\n)?user=> (nil\n)?"} $0'

Jan K 2020-10-06T17:54:54.018200Z

Actually as it is this probably woudln't help for individual EDN values, cljfmt doesn't break them up in lines, I use it for misformatted code

2020-10-06T17:57:08.018900Z

yeah, the vim clojure mode already knows how to indent correctly (using =) the question is where to put the line breaks

2020-10-06T17:57:33.019300Z

you do have to tweak settings a bit to make it agree with cljfmt

walterl 2020-10-06T18:10:08.020400Z

Closest I got is :%s/, /<C-v><CR>/g<CR>==... but that replaces commas in strings too 🤷

walterl 2020-10-06T18:10:26.020800Z

At least it's readable like this

defndaines 2020-10-06T18:22:28.021200Z

Mine isn’t pretty either …

defndaines 2020-10-06T18:22:41.021600Z

nnoremap <leader>e :call FormatEDN()<CR>1G=G<CR>

function! FormatEDN()
  if search('" "')
    execute '%s/" "/"\r"/g'
  endif
  " Break lists of maps onto separate lines.
  if search('} {')
    execute '%s/} {/}\r{/g'
  endif
  " Convert commas into newlines in maps.
  if search(', :')
    execute '%s/, :/\r:/g'
  endif
endfunction

walterl 2020-10-06T20:53:39.022Z

Better than what I got. Thanks, @defndaines!