When I create a buffer for a new file in a Clojure project, something automatically populates it with an empty ns form based on the filename and path.
1. What is creating this ns form? I assume clojure-mode, but can't find anything in the docs about this feature.
2. clojure-mode-hooks seem to run before this ns form is inserted. Is there any hook I can use that will run after?
@enn this is the package https://github.com/corgi-emacs/clj-ns-name
Standard part of Corgi emacs
@enn You can easily customize how emacs creates buffer names for identical file names by setting 'uniquify-buffer-name-style'. For your use case (setq uniquify-buffer-name-style 'forward) will add the directory name in front of the filename to make the buffer name distinct: routes/foo.clj and handler/foo.clj
clojure-lsp and clj-refactor do that, probably it's your clojure-lsp
check :auto-add-ns-to-new-files? in clojure-lsp https://clojure-lsp.io/settings/
ah, thank you
check your find-file-hook in particular, clj-refactor adds itself to it when loaded.
The context here is: I want to have my Clojure buffers named after the namespace rather than the filename. I have a function to do this that looks like so:
(defun rename-buffer-to-ns ()
(interacive)
(when (buffer-file-name)
(let ((ns (clojure-find-ns)))
(when (and ns (not (string= "" ns)))
(rename-buffer ns)))))
I have this function added as a clojure-mode-hook and that works fine for opening already-existing Clojure files. It does not work for new files because clojure-find-ns returns nil because this hook runs before the ns form is inserted. If I run this function manually after the buffer is opened and the ns form is inserted, it renames the buffer correctly.
Is there an obvious way to make this run after lsp-mode inserts the ns form? Or is there some other, better approach to having my buffers named after the namespace?First why you want a different name? Probably because your source paths not match? If so, configuring Clojure-lsp source-paths may be a good idea
I do remember he at some point was experimenting with naming the buffers like FQN of namespaces
If you're doing that purely for a better way of finding the right ns file quickly - maybe don't. Use consult-lsp instead
My source paths match, I just find the namespace more useful than the filename.
In my Clojure projects I often have a bunch of same-named files in different parts of the source tree. Maybe I have a routes/foo.clj that has the API route definitions for the foo domain entity, a handler/foo.clj that has the HTTP handlers, a domain/foo.clj that has the domain model, a validation/foo.clj that has some business logic, etc. I also usually have a bunch of core.cljs and util.cljs. By default Emacs gives these buffers the useless names foo.clj, foo.clj<2> , foo.clj<3>, etc.
It's much more helpful to see names like my-project.routes.foo, my-project.handler.foo, etc. in the modeline and in my buffer list.
I'll take a look at plexus's Emacs config, thanks for the tip
Ah so its not the ns you wanna customize, but the modeline to show the ns and not the file name? Got it
right, I want the buffer name to be the ns
Yeah I'm not aware of any "official" way to do that, but sounds like somethhing interesting that lsp-mode could have optionally indeed
@enn ah, I found Arne's experiment. Gosh it's been 7 years ago https://gist.github.com/plexus/5418819323afb892b481816745be15e0
I have this in my setup
(setq-default mode-line-buffer-identification
'(:eval (format-mode-line
(propertized-buffer-identification
(or (when (project-current)
(when-let* ((buffer-file-truename buffer-file-truename)
(prj (project-root (project-current)))
(prj-parent (file-name-directory (directory-file-name (expand-file-name prj)))))
(concat (file-relative-name (file-name-directory buffer-file-truename) prj-parent) (file-name-nondirectory buffer-file-truename))))
;; (file-name-nondirectory buffer-file-truename)
"%b")))))
which will put the project name and full path to the file in the place of the buffer name when the file it's pointing to is part of a project.el project, so it looks something like thisI also tend to use project-find-file to find files and don't really look at the buffer list very much. So maybe that's why I'm fine with not renaming the buffers. I'm sure there are schemes for changing how unique buffer names are chosen when they clash, So you get a dir name instead of <2> etc.... let me google a sec
yeah maybe look at the variable uniquify-buffer-name-style? Maybe setting that to forward would be good enough?