Fork me on GitHub
#vim
<
2023-06-08
>
Phillip Mates14:06:31

By default in vim when I search via * over clojure.core/inc I get matches for the whole namespaced var. I was wondering if folks have a good way to search for an exact var excluding the namespace? details on my flawed approach in the 🧵

Phillip Mates14:06:35

I used to do autocmd FileType clojure set iskeyword-=/ and then use vim's * feature, but this messes with other clojure specific plugins like autocompletion My current approach leaves something to be desired:

function! SearchClojureWord()
  exe "set iskeyword-=/"
  let var = expand("<cword>")
  exe "set iskeyword+=/"
  return "".var.""
endfunction

autocmd FileType clojure nnoremap * :execute "/\\(^\\\|\"\\\|[\\/(]\\\|\\[\\\|\\s\\+\\)\\zs" . SearchClojureWord() . "\\ze\\(\\]\\\|\\/\\\|\"\\\|\\s*\\)" <CR>
the regex mess is an approximation of vim's exact matching behavior (`/\<inc\>`), which won't match the inc in clojure.core/inc unless I do set iskeyword-=/

dominicm15:06:07

There are some plugins which change * afaik

dave15:06:08

I just checked, and clojure-lsp "find references" does this the way you'd want

dave15:06:27

It's not exactly like *, but worth mentioning anyway in case it's helpful. There are plugins that use LSP to give you a list of references to the thing your cursor is over, across the entire project.

☝️ 2
Noah Bogart17:06:30

Neovim enables using * on selected text with this default mapping: https://neovim.io/doc/user/vim_diff.html#default-mappings

Noah Bogart17:06:56

so you can select just the inc part and then press * to move to the next usage of inc anywhere in the file

Phillip Mates17:06:23

I don't completely follow Noah, like when I put my cursor over the inc of clojure.core/inc in neovim and hit * it searches for the full clojure.core/inc (same if I / then <C-R> to get the current word). Doing autocmd FileType clojure set iskeyword-=/ gets me the behavior I'm (usually) looking for with */`<C-R>` , but as I said messes with a bunch of plugins and trying clojure-lsp "find references" now and it seems to work, though ideally it would only highlight occurrences in the current buffer and not open a quickfix with all references in the project

dave18:06:24

You should try g*. It does something kind of like * but subtly different in a way that I don't remember off-hand

Phillip Mates11:06:20

I ended up switching my entire nvim config to fennel (which has been amazing) and then it was straightforward to code something that worked for me:

(module config.mapping
  {autoload {str conjure.aniseed.string}})

(defn search-clojure-word []
  (let [full-word (vim.call "expand" "<cword>")
        split-word (str.split full-word "/")]
    (if (= 2 (length split-word))
      (do
        (vim.cmd "set iskeyword-=/")
        (let [word (vim.call "expand" "<cword>")]
          (vim.cmd (.. ":execute \"/"
                       (if (= word (. split-word 1))
                         (.. "\\\\<" word "\\\\ze")
                         (.. "\\\\/\\\\zs" word "\\\\>"))
                       "\""))
          (vim.cmd "set iskeyword+=/")))
      (vim.cmd (.. ":execute \"/\\\\<" full-word "\\\\>\"")))))

(vim.api.nvim_create_autocmd [:FileType]
                             {:group (vim.api.nvim_create_augroup "filetypes" {})
                              :pattern :clojure
                              :callback #(vim.keymap.set :n :* search-clojure-word)})