Skip to content
This repository was archived by the owner on Sep 28, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/zepl-contrib.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ Copy/adapt the code below to your |vimrc| to add improved F# support.
\ 'formatter': function('zepl#contrib#fsharp#formatter')
\ }
<
------------------------------------------------------------------------------
*zepl-clojure*

Copy/adapt the code below to your |vimrc| to add improved Clojure support.
>
runtime zepl/contrib/clojure.vim

autocmd! FileType clojure let b:repl_config = {
\ 'cmd': filereadable('deps.edn') ? 'clj' : 'lein repl',
\ 'formatter': function('zepl#contrib#clojure#formatter')
\ }
<
==============================================================================
3. EXTRA FEATURES *zepl-extra-features*

Expand Down
67 changes: 67 additions & 0 deletions zepl/contrib/clojure.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
" Description: Text formatter for Clojure code.
" File: zepl/contrib/clojure.vim
" Author: Paul Fernandez <paul4nandez@gmail.com>
" Help: :help zepl-clojure
" Legal: No rights reserved. Public domain.

function s:stripLeadingEmptyLines(lines) abort
while !empty(a:lines)
if a:lines[0] =~# '\m^\s*$'
call remove(a:lines, 0)
else
break
endif
endwhile
return a:lines
endfunction

function s:stripTrailingEmptyLines(lines) abort
let idx = len(a:lines) - 1
while idx >= 0
if a:lines[idx] =~# '\m^\s*$'
call remove(a:lines, idx)
let idx -= 1
else
break
endif
endwhile
return a:lines
endfunction

function s:normalizeIndents(lines) abort
let depth = len(matchstr(a:lines[0], '\m\C^\s*'))
return map(a:lines, 'v:val[' . depth . ':]')
endfunction
Comment on lines +7 to +34
Copy link
Copy Markdown
Contributor Author

@pfernandez pfernandez May 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code in these three functions are ripped straight from the other formatters. At some point they could potentially be moved into a shared file like contrib/utils.vim.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I've actually thought about this before, but haven't got around to it. I think they should probably live under autoload/zepl/fmt.vim or similar (still not sure on the naming yet).

Then they can be called like this:

return zepl#fmt#NormaliseIndentation(a:lines)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, the default formatter should probably do some of this anyway. Maybe I'll get round to that at some point in the future.


function s:processLine(...) abort
" Remove trailing newlines.
let line = trim(a:2, "\r\n\<CR>", 2)

" Remove two leading spaces added by the Clojure repl.
return substitute(line, '\m^\s\s', '', '')
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this behavior in both the Clojure and Leiningen repls. A two-space indent is always added after the first line break.

Before
Screen Shot 2022-05-11 at 4 35 09 PM

After
Screen Shot 2022-05-11 at 4 36 21 PM

Copy link
Copy Markdown
Owner

@axvr axvr May 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's odd. I've never had this problem, so using this formatter actually has the inverse problem. What OS and Vim version are you using?

With formatter Without formatter

Regardless, I'm fine including this, but maybe there should be a config option for it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using macOS Monterey 12.3.1, and run Vim inside iTerm:

$ vim --version
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Apr 20 2022 18:55:37)
macOS version - x86_64
Included patches: 1-4800
Compiled by Homebrew
Huge version without GUI.

I'll go back and strip my vimrc to the bare essentials, and also try it with Gvim and on a Ubuntu machine I have lying around. While I'm at it, I'll dig deeper into the mysterious ^M I mentioned above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been pretty busy at work, but today I removed everything except zepl from my vim config and tried it again. I found that the problem is the same in either case, but that my "eliminate two spaces" code only worked because I was always using a two-space indent inside comment forms. I was just covering up the fact that the indentation code that I borrowed from the F# formatter wasn't actually doing anything.

I'll come back to this when I have more time and give it a fresh look.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, don't worry, there's no rush. I'm happy to help where needed, but I am quite busy too.

endfunction

function zepl#contrib#clojure#formatter(lines)
let lines = s:stripLeadingEmptyLines(a:lines)
let lines = s:stripTrailingEmptyLines(lines)

if empty(lines)
return ''
endif

let lines = s:normalizeIndents(lines)
let lines = map(lines, function("s:processLine"))

return join(lines, "\<CR>") . "\<CR>"
endfunction

" EXAMPLE: Configure zepl.vim to use the Clojure formatter in Clojure buffers.
" (Replace 'plugins/' with your plugin directory path.)
"
" runtime plugins/zepl.vim/zepl/contrib/clojure.vim
Comment on lines +59 to +61
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about this, does just runtime zepl/contrib/clojure.vim not work for you?

Which plugin manager are you using?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using vim-plug, which actually uses ~/.vim/plugged/. I wrote plugins/ because that's Vim's default plugin directory, but mainly was just trying to be more clear that you need to figure out the path for yourself depending on your setup.

" let g:repl_config = {
" \ 'clojure': {
" \ 'cmd': filereadable('deps.edn') ? 'clj' : 'lein repl',
Copy link
Copy Markdown
Contributor Author

@pfernandez pfernandez May 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works to determine whether we're in a leiningen project or not, but assumes that the user is working from the project root. Nevertheless I think it's a useful example.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Maybe this example could include the 'rlwrap' flag too? (You don't have to if you'd rather not.)

"   let g:repl_config = {
"   \   'clojure': {
"   \     'cmd': filereadable('deps.edn') ? 'clj' : 'lein repl',
"   \     'rlwrap': filereadable('deps.edn') ? 1 : 0
"   \     'formatter': function('zepl#contrib#clojure#formatter')
"   \   }
"   \ }

(+ If you decide to update this, don't forget to update the example in the doc too.)

" \ 'formatter': function('zepl#contrib#clojure#formatter')
" \ }
" \ }