Emacs setup

So far all I’ve done is

(use-package crystal-mode
  :straight t)

Which is a pretty basic setup, but not too bad. Other Emacs users that have a more interesting setup? Any lsp server worth looking into?

2 Likes

I don’t use an LSP, but here’s the relevant section in my .emacs. Using company to autocomplete stuff I’ve already typed is kind of nice at times.

(add-hook 'crystal-mode-hook
          (lambda ()
            (setq show-trailing-whitespace t)
            (setq indent-tabs-mode nil)

            ;; disable unsupported features
            ;;(lsp-deferred)
            (company-mode)

            ;;(setq lsp-prefer-flymake nil)
            ;;(setq lsp-ui-sideline-enable nil)
            (setq company-tooltip-limit 20) ; bigger popup window
            (setq company-idle-delay 0)
            (setq company-tooltip-align-annotations t)
            (setq company-echo-delay 0) ; remove annoying blinking

            ;; I use PascalCase since snake_case is very hard for my eyes to parse.
            (subword-mode) 

            ;; Remove any trailing whitespace from lines when the source file is saved
            (add-hook 'local-write-file-hooks
                      '(lambda ()
                         (save-excursion
                           (goto-char (point-min))
                           (when (search-forward "\t" nil t)
                             (untabify (1- (point)) (point-max)))
                           (delete-trailing-whitespace))))))

I installed crystal-mode and crystal-playground from the package manager (M-x list-packages). The crystal-playground is different than the browser-based playground in that it’s a local Emacs buffer, and can save to a local file. Kinda nice since I don’t have to leave Emacs to do stuff like that ^_^

crystal-mode, unfortunately, has a bit of an issue with the abstract keyword, but it’s just a minor annoyance :sweat_smile:

Following is my crystal-mode specified config.

To be honest, less config than my others mode, but still several of them quite useful.

  1. flycheck
  2. ameba
  3. though i enable LSP(crystalize), but it not so useful for now AFAIK, i even not so useful than tabnine
  4. apheleia is a very useful format tools, format process run asynchronously, i contribute code make it support crystal-mode. (format is a feature of lsp, but i disable it because i use apheleia)

In fact, i found there are many feature i never to tried for crystal-mode, maybe anyone can introduce some of best of them.

Using company to autocomplete stuff I’ve already typed is kind of nice at times.

I’ve been using company-dabbrev for years, used to be the only thing that could produce completions in PHP. While the language servers have caught up, I still have it as a fallback. Also, handy in text buffers.

crystal-playground

Oh, I should get that for quick experimentation.

crystal-mode, unfortunately, has a bit of an issue with the abstract keyword

Oh. I’m not that far that I’ve created any abstract stuff yet.

flycheck

Oh, yeah, flycheck all the things. Though lsp-mode messes a bit with it, which might come around to bite me: I add additional php checkers after the lsp checker, but the lsp checker works with different languages. I’ll probably have to deal with that.

tabnine

I tried that a while back, but was massively underwhelmed. Might have been my setup or lousy PHP code. But I’ve been using GitHub co-pilot for a bit, which isn’t that different.

crystalline

Oh, gotta get that. lsp-mode defaults to scry, which seems a bit dead, maybe we should make a PR to change it to crystalline?

apheleia

Well, I’m coding with myself so far, so strict formatting isn’t so high on my list. But from Radian, so worth checking out…

1 Like

crystal-mode, unfortunately, has a bit of an issue with the abstract keyword

You can’t mark a method with abstract prefix use (mark-sexp), C-M-SPC

Oh, gotta get that. lsp-mode defaults to scry, which seems a bit dead, maybe we should make a PR to change it to crystalline?

Although, config is easy, set following variable BEFORE you require the lsp-mode, you need crystalline on the $PATH anyway.

(setq lsp-clients-crystal-executable '("crystalline" "--stdio"))
(require 'lsp-mode)

Added to my init.el. And I’ve tried getting Support crystalline for Crystal · Issue #4003 · emacs-lsp/lsp-mode · GitHub moving again.

Protip:
crystaline doesn’t seem to do indentation, so marking a region and pressing tab is rather useless. Telling lsp-mode not to bother with indentation in crystal-mode fixes that:

(use-package crystal-mode
  ;; The language server can't figure out how to indent regions, so
  ;; it's basically useless. Tell lsp-mode not to use it.
  :hook (crystal-mode . (lambda ()
                          (setq-local lsp-enable-indentation nil)))
  )

Also makes it work with my auto indenter package GitHub - xendk/indentinator: Automatic indentation mode for Emacs

1 Like

Aha, never try this package, i use Replace auto-indent-mode · Issue #1 · jeffvalk/snap-indent · GitHub

We’ll, indentinator was also born from frustrations with auto-indent-mode. But indentinator re-indent changes, not just what’s yanked, so edits that affects the indention of code after the change is also properly indented. And it only does its thing while Emacs is idle, so even if your change means the whole file needs re-indenting, it wont get in the way.

I should get round to properly packaging it and submitting it to melpa, I’ve been using it for years without much change.

Thanks, switch from snap-indent to this in my config for a try, it works!

Does we still need formatter like apheleia? it run code formatters on after-save-hook.

indeed, most emacs user use package manager, though, for some reasons, i config manually locally.

Excellent! You’re the first install besides my own I’ve heard about, so it’s nice knowing it’s working.

Well, you’ll probably run into annoyances if crystal tool format and crystal-mode disagree on how some code should be indented, so I’d recommend using just one.

It’s a matter of taste and temperament. I’m not a fan of on-save formatting, I prefer the faster feedback of editor-indenting. I had my formative years before on-save reformatting became a thing, and can show off the scars from the Code Style Wars (PHP still haven’t settled whether to put the opening brace of a function on the same or the next line). So I prefer editor driven indentation, so I can catch it and overrule it when I feel like it.

Secondly, randomly saving files to fix formatting will mess with my habit of using entr to watch files for changes and running tests.

But that’s just my personal opinion. apheleia does have the advantage of always following crystal tool format to the letter.

Yeah, I gather that use-package is popular, so naturally there’s a contestant for the throne. But per default it uses package.el to install packages, hence why I need to make a package if I want to spread the usage. And there’s still package.el users, I gather that MistressRemilia is one.

I use use-package, but with elpaca as package manager (after 5 years of using straight). Emacs is more fragmented than most communities, where some communities go with “there’s a proper way to do thing”, other go with “there’s more than one way to do thing”, Emacs has 25 ways of doing it, two built in methods, three major competing packages where the maintainers regularly talk, at least one method involving org-mode and one where the readme makes you wonder if the author is medicated. It’s great.

1 Like

Aha!