This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-11-13
Channels
- # announcements (2)
- # babashka (30)
- # beginners (44)
- # biff (20)
- # calva (15)
- # cider (7)
- # clerk (4)
- # clojure (15)
- # clojure-austin (1)
- # clojure-europe (35)
- # clojure-hungary (1)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-uk (7)
- # clojurescript (33)
- # conjure (1)
- # cryogen (1)
- # cursive (3)
- # data-science (8)
- # docker (2)
- # emacs (78)
- # gratitude (2)
- # hyperfiddle (26)
- # improve-getting-started (1)
- # jobs-discuss (12)
- # lsp (7)
- # malli (11)
- # missionary (57)
- # off-topic (14)
- # pathom (13)
- # portal (6)
- # reagent (6)
- # releases (3)
- # ring (25)
- # shadow-cljs (18)
- # squint (11)
- # vim (3)
How easy is it to switch between doom and spacemacs if your using emacs 29.1. Are their any updated guides on how to do that?
Your level of familiarity with Emacs will determine how quickly you adapt to Doom. If you can clearly distinguish between what in your config comes from Spacemacs and what is a built-in feature or a package, you might be able to start with Doom in about an hour. However, it may take several weeks to tweak it to your satisfaction. This constant tweaking is not unique to Doom; it's part of the Emacs experience.
For a more meticulous approach, you could list what you like and dislike about Spacemacs, and identify the issues you believe Doom could resolve. This might lead you to several options:
• Address the issues with Spacemacs
• Switch to Doom
• Build your own config from scratch
• Explore other options like crafted-emacs, prelude, etc.
I personally switched to Doom because I was frustrated with the tight integration of components in Spacemacs. Users would enthusiastically add hooks, esoteric or debatable features, or introduce a host of new packages to layers I had no interest in using.
Despite creating my own set of layers, I found that Spacemacs still had numerous "default" customizations that I couldn't control. In contrast, Doom has a true lean core layer that primarily bootstraps your package manager, currently Straight.el.
This raises the question, "why use Spacemacs or Doom at all?" When I first switched to Spacemacs, I was an Emacs novice and struggled with certain features. Configuring Evil with all its quirks seemed like an insurmountable task, and giving up on Vim navigation was out of the question. I need Vim-navigation; I love it, I know it, I use it well. Today, I'm absolutely confident that I could build my own config from scratch without using Doom or Spacemacs. So why do I still choose Doom, even though I rarely use any of its modules and have my own set instead? The answer is Doom's core macros. map!
, add-hook!
, defadvice!
, cmd!
and many others. They are incredibly useful and have helped me to reduce unnecessary boilerplate. Doom's command line tool is also very handy.
Can I easily transition from Doom and build my own config from scratch? Absolutely. Do I have any compelling reasons to do so at present? Not really. What if there are aspects that I'm unaware of simply because I lack the knowledge? Here's the thing - with Spacemacs, when something goes wrong, it's often not very apparent and it's usually challenging to identify the cause. With Doom, it's significantly more straightforward. Whenever something malfunctions, I can readily identify the problem and either implement a workaround or temporarily disable it. Issues typically arise when I update. Certain package changes may become incompatible with my config. But since I don't use many modules included with Doom, changes in the modules themselves seldom cause any problems for me.
So, if most of the time something breaks either due to my own sloppy Elisp, or because of specific changes to one of the packages I use, and the breakage has little to do with Doom internals, I guess it would be the same if I used my own config not based on Doom. Then, what's the point of building my own config?
But do I feel that having to learn Spacemacs specifics was a total waste of time? Not at all. I am very grateful to Spacemacs. I learned a multitude of things I didn't have a good understanding of before, or didn't even know existed. One of the best non-Emacs specific things I learned from Spacemacs is the method of organizing your keys. There's a main leader key <Space> and a local-leader-key - <comma> in Spacemacs. Doom also uses a similar approach. However, in Doom, things are a bit messier (in my opinion). After all, Doom is primarily influenced by a single developer, whereas Spacemacs keybindings are community-driven. This doesn't necessarily help to avoid keybinding conflicts you may get if you add too many Spacemacs layers. I believe Spacemacs has a better approach when it comes to organizing keybindings; once you grasp the main idea, you can re-structure your keybindings according to your needs. For instance, I didn't even try to reshape my muscle memory and learn the Doom-way. I almost immediately sat down and made the bindings similar to my Spacemacs config, because that made sense to me. That's where the map!
macro I mentioned earlier becomes really handy.
I can certainly give you a tour of Doom and perhaps share some thoughts, opinions, and recommendations over a call that could help ease your transition.
just in case this is what you're talking about, you can use the --init-directory
option to switch between them pretty easily (or use chemacs, I guess?)
I found my initial use of Doom very frustrating after years of Spacemacs, mostly due to the different key bindings that had become ingrained.
Opening files, projects and Magit all use different key bindings, as does M-x alternatives (`SPC SPC` is SPC :
).
As others have mentioned, it depends how much of Spacemacs is regularly used and how much a person relies on key bindings to work efficiently.
Another noticeable difference is the default narrowing tools used, Helm in Spacemacs and vertigo (?) in Doom. Although conceptually they are mostly the same, usage is noticably different.
For Clojure development, all the tools are the same, although the key bindings were very sparse in Doom compared to Spacemacs (although all the underlying commands are the same)
Doom will used a pinned version of CIDER, clojure-mode, etc so for newer features and fixes either wait for the Doom maintainer to bump the version or 'unpin' the version of packages to get the latest from Melpa.
None of this is an unsurmountable challenge, but there should be enough value or motivation to invest in making the change. I ended up https://github.com/practicalli/doom-emacs-config because otherwise Doom was far too slow for me to use. I still found things missing that wasnt worth my time investing in, but then I do use a lot of Spacemacs features.
Doom and Spacemacs have very different objectives but underneath they share 100s of Emacs packages in common. So the choice comes down to understanding those objectives and working within them to get the most of of each tool.
It quickly became irrelevant as to how quickly Doom Emacs starts, as all user driven events took far longer as the user was trying to use it like Spacemacs...
I did learn more vim-style editing thanks to using Doom for 4 months, especially as there were fewer keybinings for structural editing.
In the end I found using Neovim & Conjure a better alternative to Spacemacs than Doom Emacs (Neovim is very fast and responsive and allowed me to learn even more vim-style editing). I also found Conjure & Clojure LSP simpler to use together than CIDER & Clojure LSP due to their overlap.
Ultimately I dropped Doom as it didnt offer my workflow any value compared to other approaches. However, I have my own opinions and preferences and so if you have time then you should evaluate the tools you use.
As others have said, Dooms keybindings are less polished and not as consistent across different modules. That was a pain point for me. On the other hand Doom comes with 1000 little helpers like map!
, cmd!
, setq-hook!
... that reduce friction when you want to do your own customizations. And you can learn a lot from how these helpers are built. For me, fiddling with Doom was the perfect stepping stone to a "vanilla" config.
Also, if anyone wants to spend some time figuring out why i can't autocomplete all the same functions vscode can with LSP in emacs i would be willing to .. well pay money. lol.
I'm not sure what exactly is missing in my workflow, as I've never used VSCode for writing Clojure. The answer would depend on multiple factors, specifically what you want: There are two main choices today for completions in Emacs: • https://company-mode.github.io/ • https://github.com/minad/corfu Company is older and more "battle-tested". Corfu is created by Daniel Mendler, the author of vertico, consult, jinx.el, and I believe he's also a co-maintainer of Embark. These packages are incredibly useful and can certainly elevate your Emacs skills to a new level, but it will take some time to familiarize yourself with them. My personal opinion? They're totally worth it. Because vertico/consult/embark work well when integrated together, people often refer to them as the "vertico stack". So, if you choose to use it, then perhaps choosing corfu over company would make sense.
I get the same results on doom(company+tweaks) and vscode. What's your exact setup and what aren't you seeing?
@U1UQEM078 i use emacs 29.1 installed vai ubuntu snaps, here is my configuration https://github.com/drewverlee/space/tree/drews-additions What i see is that sometimes autocomplete doesn't work. And by sometimes, i mean maybe ... 3/10 times i try to use it. By autocomplete i mean simply requireing an alias to a namespace, typing that namespace alias, then trying to get the list of functions available on that namespace by hitting tab. Ill load up vscode, and try the exact same thing, and it will work every time. In emacs, it will work sometimes. Like this very moment, the very thing that didn't work last night... works. If this wasn't such a consistent issue over the years for me i could write off a couple issues with my setup as user error, or maybe cosmic radition, but i think something is fundamentally wrong with my setup and i might be due for a complete overhaul. e.g maybe leaving spacemacs and building my own setup from scratch. or as @U0G75ARHC suggests, maybe i should switch from company-mode to corfu and the vertico stack. idk. i just know my setup is way too error prone. The other oddity i see quite often is that eventualy i can't use the M-x commands, e.g if i select an emacs command from history it won't select it. I can use the emacs short cut though. so in the picture, if this bug was in play, hitting enter on magit-init, would do nothing, but typing SPC g i would correctly initialize a repo.
I see. The link you've pasted gives me a 404. Is it perhaps private? Are you using cider or LSP or both? What you're describing is exactly what I get when I have cider connected, add a new aliased namespace via shortcuts/automation but forget to re-eval the namespace.
it is private, ugh. I don't want to make it public because it's slightly to easy for private info to sneak in their. let me think about this for a second.
Yes, it would make sense if cider was getting used and not lsp and i didn't eval the namespace to bring it in. next time it happens ill triple check thats not it. (to be clear i'm 98% sure i did eval the namespace again).
@U1UQEM078 If your free, i can show you one of these mystery cases where things don't autocomplete right now and hopefully you can show me how i'm missing something super obvious...
and... now it works. I think LSP is confused about the project, it seems to have selected the parent folder (which contains lots of clj projects) rather then the specific child one i'm in.
the oddity is that in half the files it was working.
and now it's not working again.
@U1UQEM078 right after i try to do a completion? the clojure-lsp logs show:
2023-11-22T04:48:20.391Z INFO [clojure-lsp.feature.file-management:246] - changes analyzed by clj-kondo took 37ms
2023-11-22T04:48:20.391Z INFO [clojure-lsp.dep-graph:269] - :maintain-dep-graph 0ms
2023-11-22T04:48:20.391Z INFO [clojure-lsp.server:553] - :analyze-file 38ms
2023-11-22T04:48:20.391Z INFO [clojure-lsp.server:164] - :refreshing-test-tree 0ms
2023-11-22T04:48:20.391Z INFO [clojure-lsp.feature.file-management:139] - :reference-files/find 0ms
2023-11-22T04:48:20.391Z INFO [clojure-lsp.feature.file-management:137] - :notify-references 0ms
2023-11-22T04:48:20.416Z INFO [clojure-lsp.server:102] - :publish-diagnostics 0ms
2023-11-22T04:48:20.836Z INFO [clojure-lsp.feature.file-management:250] - changes analyzed by clj-depend took 0ms
2023-11-22T04:48:20.845Z INFO [clojure-lsp.dep-graph:269] - :maintain-dep-graph 0ms
2023-11-22T04:48:20.846Z WARN [clojure-lsp.kondo:363] - Non-fatal error from clj-kondo: No configs copied.
2023-11-22T04:48:20.846Z INFO [clojure-lsp.feature.file-management:246] - changes analyzed by clj-kondo took 10ms
2023-11-22T04:48:20.846Z INFO [clojure-lsp.dep-graph:269] - :maintain-dep-graph 0ms
2023-11-22T04:48:20.852Z INFO [clojure-lsp.server:553] - :analyze-file 16ms
2023-11-22T04:48:20.852Z INFO [clojure-lsp.server:164] - :refreshing-test-tree 0ms
2023-11-22T04:48:20.853Z INFO [clojure-lsp.feature.file-management:139] - :reference-files/find 0ms
2023-11-22T04:48:20.853Z INFO [clojure-lsp.feature.file-management:137] - :notify-references 0ms
2023-11-22T04:48:20.854Z INFO [clojure-lsp.handlers:488] - :code-lens 0ms - waited 63ms
2023-11-22T04:48:20.866Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms - waited 80ms
2023-11-22T04:48:20.867Z INFO [clojure-lsp.handlers:502] - :semantic-tokens-full 1ms - waited 80ms
2023-11-22T04:48:20.870Z INFO [clojure-lsp.handlers:475] - :code-actions 5ms - waited 80ms
2023-11-22T04:48:20.877Z INFO [clojure-lsp.server:102] - :publish-diagnostics 0ms
2023-11-22T04:48:20.909Z INFO [clojure-lsp.handlers:475] - :code-actions 6ms
2023-11-22T04:48:21.578Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2023-11-22T04:48:21.582Z INFO [clojure-lsp.handlers:475] - :code-actions 4ms
2023-11-22T04:48:31.801Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2023-11-22T04:48:31.806Z INFO [clojure-lsp.handlers:475] - :code-actions 5ms
2023-11-22T04:48:33.440Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2023-11-22T04:48:33.445Z INFO [clojure-lsp.handlers:475] - :code-actions 5ms
2023-11-22T04:48:34.329Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2023-11-22T04:48:34.333Z INFO [clojure-lsp.handlers:475] - :code-actions 5ms
2023-11-22T04:48:35.275Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2023-11-22T04:48:35.279Z INFO [clojure-lsp.handlers:475] - :code-actions 5ms
2023-11-22T04:49:31.289Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2023-11-22T04:49:31.296Z INFO [clojure-lsp.handlers:475] - :code-actions 7ms
2023-11-22T04:49:32.732Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2023-11-22T04:49:32.737Z INFO [clojure-lsp.handlers:475] - :code-actions 5ms
2023-11-22T04:49:35.221Z INFO [clojure-lsp.handlers:302] - :document-highlight 0ms
2
so here is an example of an oddity
(ns core
(:require
[clojure.set :as set]
[ubergraph.core :as uber]))
(set/*)
(uber/*)
if my cursor is * then set will autocomplete correct and uber wont. But i have another project where set won't even find completions (intersection, etc...)
What happens is i have this happen all the time, i try to talk to people about it, then we all get busy again. But i would really love someone to come like walk in my shoes for an hour. 👞
Anyway, im off for thanksgiving. Enjoy your holidays 🙂Paging @UKFSJSM38 for some hints as to what to investigate!
The 4 lines of code provided by Drew were enough to repro this on my end - and what he describe sort of matches some hiccups I've seen in the past.
Perhaps clojure-lsp is being misused?
One funny thing I see (as a diagnostics message) is a warning about uber/.
not being a valid symbol (but I didn't type that .
)
this piece of code is not valid:
(ns core
(:require
[clojure.set :as set]
[ubergraph.core :as uber]))
(set/)
(uber/)
so clojure-lsp hacks that and changes the first occurence of that invalid code to:
(ns core
(:require
[clojure.set :as set]
[ubergraph.core :as uber]))
(set/something)
(uber/*)
where something is just something to make the code compile and clj-kondo provide valid analysis and rewrite-clj don't blow up, the problem is that clojure-lsp does that only for the first occurrence, so if you hae uber/ in the next line that will make completions of set don't work reliable as wellbut that's ok usually as you don't have invalid code twice most of the time, as you type one thing at time
Me neither 😂
neil dep add :lib ubergraph/ubergraph :version "0.8.2" :description "Feature-loaded graph implementation"
The repro is what you've attempted, except trying to complete uber/
.
LSP will provide uber as an alias on the completion
if you try this exact repro, does it work for you
(ns core
(:require
[clojure.set :as set]
[ubergraph.core :as uber]))
(uber/|)
where |
is the cursorUber graph cones from here https://github.com/Engelberg/ubergraph That completion stops working if it finds more than two invalid... Things, might explain some behavior i have seen. Is there a way to check if that's happening? My biggest question has always been how to explain what tab/auto complete is trying to do and why it finds nothing. I'm fairly sure i tried them (set/ and Uber/) exclusively, one at a time at some point, but maybe not. I'm away from my computer, so I'll have to try later. Ty for the help.
1. why your right paren dissappear when completing? never saw that
2. try disable lsp-mode completion cache with (setq lsp-completion-no-cache t)
@U0DJ4T5U1 the best way is to debug client<->server logs as mentioned https://clojure-lsp.io/troubleshooting/#client-server-log, you want to search for the textDocument/completion
result from clojure-lsp
I have recordings for those - clojure-lsp returned []
on emacs (but I'm not sure if everything else is correct, such as the trailing .
etc)
clojure-lsp keeps in memory the analyssi of the file, if you have a invalid file, it won't provide completions, and for a instant you had unbalanced parens, so that may explains
some cases are handled like the invalid uber/
which I explained above, but unbalanced parens no
if so, it's not a clojure-lsp bug, it's a lsp-mode fault, that's one of the reasons I use that uncached
Happy to turn that off temporarily (or for clojure-mode)! Would you like me to open an issue on lsp-mode to check if there's something more that could be done re: the interaction with clojure-lsp? I ask because I probably will have to rope you in...
if you have any reliable way to reproduce the problem, that would help, as we may ask for help of yyoncho and kienqq that knows better the completion code of lsp-mode
Isn't what we have reliable enough? Could you try turning on cache and checking that it also happens on your setup?
Assuming drew isn't using doom (since he didn't ask on doom), we already have two datapoints (custom emacs and almost vanilla doom)
I doubt doom is related to that problem, more likely it's a lsp-mode issue. I will try enabling cache, one moment
I can't repro with cache on... following your gif and trying to get a invalid state, but the completions always work for me
try completing a code that the last char of the file is not a invalid char:
(ns foo
(:require
[clojure.set :as set]
[ubergraph.core :as uber]))
uber/|
:something-else
hum, for me it works, and may be related with a merge of cached completion + clojure-lsp handling that invalid code...
Nope, confirmed. On a clean workspace the above also doesn't work - and starts working once I turn off caching. After that, it keeps working even if I turn on caching again.