vim

Phillip Mates 2023-06-08T14:39:31.916559Z

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 Mates 2023-06-08T14:39:35.421279Z

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-=/

dominicm 2023-06-08T15:07:07.323349Z

There are some plugins which change * afaik

dave 2023-06-08T15:53:08.605809Z

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

dave 2023-06-08T15:54:27.607789Z

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.

☝️ 1
2023-06-08T17:08:30.683619Z

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

2023-06-08T17:08:56.659389Z

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

Phillip Mates 2023-06-08T17:53:23.613559Z

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

dave 2023-06-08T18:14:24.817919Z

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

Phillip Mates 2023-06-16T11:35:20.383789Z

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)})