vim 2024-01-04

Is there some magic way to move a function into another namespace and patch up all the code? That is something I've rarely needed before, but as I'm bumbling through learning ClojureScript I've been doing it more.

@alex.sheluchin how can you trigger move-form? Does it work with neovim-lsp?

I made it work like this in neovim using Fennel. Had some help from other folks here:

(module lsp-aug-jp
  {autoload {eval conjure.eval
             str conjure.aniseed.string
             a conjure.aniseed.core}})

(local commands ["cycle-coll"
                 "thread-first"
                 "thread-first-all"
                 "move-to-let"
                 "unwind-thread"
                 "inline-symbol"
                 "move-coll-entry-up"
                 "move-coll-entry-down"
                 "extract-function"
                 "cycle-keyword-auto-resolve"
                 "move-form"])

(vim.api.nvim_create_user_command "CljLsp"
 (fn [info]
    (let [command (a.get info :args)
          position-params (vim.lsp.util.make_position_params)
          uri (a.get-in position-params [:textDocument :uri])
          line (a.get-in position-params [:position :line])
          character (- (a.get-in position-params [:position :character]) 0)
          input (when (or (= command "move-to-let")
                          (= command "extract-function")
                          (= command "move-form"))
                  (vim.fn.input "Enter input: "))]
      (vim.lsp.buf.execute_command
        {:command command
         :arguments [uri line character input]})))
 {:desc "Run clojure-lsp command"
  :nargs 1
  :complete (fn [arg-lead cmd-line cursor-pos]
              (vim.tbl_filter
                (fn [s] (= (a.sub s 1 (a.count arg-lead)) arg-lead))
                commands))})

(vim.keymap.set :n :ez ":CljLsp cycle-coll")
(vim.keymap.set :n :et ":CljLsp thread-first")
(vim.keymap.set :n :el ":CljLsp thread-first-all")
(vim.keymap.set :n :eu ":CljLsp unwind-thread")
(vim.keymap.set :n :ei ":CljLsp inline-symbol")
(vim.keymap.set :n :en ":CljLsp move-to-let")
(vim.keymap.set :n :T ":CljLsp move-coll-entry-up")
(vim.keymap.set :n :t ":CljLsp move-coll-entry-down")
(vim.keymap.set :n :ex ":CljLsp extract-function")
(vim.keymap.set :n :ek ":CljLsp cycle-keyword-auto-resolve")
(vim.keymap.set :n :eo ":CljLsp move-form")
Obviously this snippet isn't optimized for brevity but it should be pretty straight forward to tweak or translate to vimscript or lua.

@dominicm it should work with nvim-lsp, but I recently switched my config to Fennel and haven't got around to figuring this part out yet. I think you would need to use https://neovim.io/doc/user/lsp.html#vim.lsp.buf.execute_command(). With coc.nvim and viml it was:

nnoremap <silent> crmf :call CocRequest('clojure-lsp', 'workspace/executeCommand', {'command': 'move-form', 'arguments': [Expand('%:p'), line('.') - 1, col('.') - 1, input("File: ", "", "file")]})<CR>

Doesn't come up as a code action like I expected, but maybe it's not sending some data it should.

Tried this from command line

=> clojure-lsp rename --from startpage.components/sqrt3 --to startpage.poly/sqrt3
[ 99%] Project analyzed            Nothing to rename
The references option correctly finds the references. Not sure what I'm missing. Looks like editor integration might offer more options, but I haven't climbed that tree yet.

i use ripgrep or my lsp (coc-clojure) to find all of the references, and then i copy the function into the new namespace, and then i go one-by-one through all of the references and update them

i like to use the quick-fix list for this, so i can say :cn to go to the next location after i've edited each invocation

clojure-lsp has a move-form feature that does this https://clojure-lsp.io/features/

💡 1