Some of you might be thinking along the lines of "Why not create a page with React?", to which I reply "Why use a excavator when you can use a hammer?". There are times when you don't need big frameworks, like when making templates (like for this blog!), or making static pages for Spring or Quarkus applications. Everything doesn't need to be one of those big web projects. Sometimes it's good to code like it's 2002 :)
Some alternatives to consider
Before we go into my approach, let's look at some other alternatives and why I don't use them:
- nothing at all, just use web-mode witout any completion (except maybe company-dabbrev-code?). Have done this for a long time, and it works. Just missing the finer goodies that Emacs can provide for me :)
Also found a StackOverflow question mentioning Spacemacs and similar functionality that I want, but couldn't find out what it was using. Still, it is more fun writing your own functionality :)
Even if I didn't use or enjoy these, feel free to take inspiration from them for your own setup. You might have different wants and needs than me after all :)
The following packages are used:
- company-mode: General completion engine.
- css-eldoc: Provides CSS documentation using eldoc
In addition, I really enjoy company-box as a company-mode frontend. It provides nice icons, and a documentation popup while you complete (which is really handy when you want to freshen up on the specifics without consulting a documentation website!).
Setup with code
Here is the setup I use in this article. Non-relevant parts are ommited, as is the configuration of
Most of the magic is done through the function
web-mode-language-at-pos from web-mode that is used to find out which language context we are currently in.
Based on what we see in the config above, we can simply open an HTML file and be ready for action! You may notice a message:
Couldn’t locate project root folder with a tsconfig.json or jsconfig.json file. Using ’/home/.../mysite/’ as project root.
That is not too important, as the basic functionality seems to work anyway.
After the settings above, we can activate completion with CTRL-RET, and eldoc-documentation will show automatically.
Just notice that we get completion and documentation (see the minibuffer/echo area!) for CSS:
(notice that we get JSDoc documentation!)
If you try it out, you will also notice that all occurrences of a variable is highlighted when your cursor hovers it!
Regular HTML parts will simply get the regular company-dabbrev-code completions like we are used to, which may just be filled with random text we have written in code. If you want something specific to happen, you can change the company-dabbrev-code line in the themkat/complete-web-mode function.
Sadly there are a few drawbacks I still haven't found good solutions to.
- The first one is that the context aware completions only happens when we request it with CTRL-RET (CTRL ENTER). If you have company completions happening automatically, they will not be context aware. They will probably come from Tide. This doesn't bother me that much, as I didn't get context aware completions at all in the past.
- No flycheck from Tide. Tried and failed to get this working. Probably due to mixed file.
Another drawback is that Tide is meant for TypeScript, and interprets almost everything to be of any-type. This means we do not get completions we want sometimes, and HOW would it even know? (you would have no way of knowing unless you knew what you were thinking!).
If we give it some hints while we are working, it works much better: