On MacOS, I specifically use d12frosted/emacs-plus
:
https://github.com/d12frosted/homebrew-emacs-plus
Here are the commands I’ve used:
brew tap d12frosted/emacs-plus
brew install emacs-plus —-with-ctags —-with-dbus —-with-debug —-with-no-frame-refocus --with-native-comp --with-modern-black-variant-icon
I use tree-sitter
, which can have language grammars installed via
M-x treesit-install-language-grammer
.
I rely upon solargraph
as my Ruby LSP: https://solargraph.org/.
My config follows the comment structure outlined here: https://www.gnu.org/software/emacs/manual/html_node/elisp/Comment-Tips.html
The structure is the following:
;
:- align comment to the same column to the right of the code, explain how code on that line does it’s job
;;
:- align comment to the same level of indentation of the code, describe purpose of following lines or state of program at that point
- also used for comments outside of functions
;;;
:- start at left margin, used for comments to be considered headings
;;;;
:- start at left margin, used for headings of major sections
Additionally, I like to use comments to link to the specific source of the package that I’m using.
Everything is wrapped in use-package
. consult-outline
can be used to jump
from each use-package
declaration.
Here are various resources I’ve referenced in the past that has helped make my emacs configuration what it is today:
- Reddit post on package.el and use-package
- Very interesting read on
package.el
anduse-package
- it shows how to have more control ofpackage.el
and making your config files reflect what is installed - I mentioned this very post in a thread on Bluesky
- Very interesting read on
- https://manueluberti.eu/posts/2021-03-08-package/
- Good post on
straight
versus just usingpackage.el
- I agree with it, which is why I also droppedstraight
straight
is still an amazing package though, and I wouldn’t be surprised if I switched back to it
- Good post on
- Manual on use-package
- https://protesilaos.com/codelog/2024-11-28-basic-emacs-configuration/
- Great article that serves as a starting point for an Emacs config
- As someone who has used Emacs for years, I learned a lot here!
- https://github.com/emacs-tw/awesome-emacs
- I reference to these two lists often, and I try to contribute to
awesome-emacs
whenever I can!
- I reference to these two lists often, and I try to contribute to
- https://github.com/caisah/emacs.dz
- Collection of amazing Emacs configurations!
- https://karthinks.com/tags/emacs/
- https://www.masteringemacs.org/all-articles
- https://learnxinyminutes.com/docs/elisp/
- Learn X in Y minutes is a great resource in general and I reference this guide often
- http://xahlee.info/emacs/emacs/elisp.html
- Xahlee has so much info, this Elisp tutorial is a great starting point
- https://github.com/p3r7/awesome-elisp
General pieces of advice I’ve collected throughout my time with Emacs.
“In general, you should keep :init forms as simple and quick as possible, and put as much as you can get away with into the :config block. This way, deferred loading can help your Emacs to start as quickly as possible.”
If you are having trouble understanding why your use-package
declaration isn’t working, try placing your cursor after the declaration and doing M-x pp-macroexpand-last-sexp
. This command prints out the actual code that use-package
generates.
fido-mode tempo (snippet) skeleton(snippet) hippie expand (completion) project.el (project mgmt) chruby (ruby)
Is it possible to have it work alongside corfu
, when you aren’t using it?
Basically, doing something like toggling corfu
off when lsp-bridge
is
turned on.
https://github.com/plexus/chruby.el is an old package that doesn’t support the auto switching of chruby - e.g. the auto detection of .ruby-version and changing accordingly
If no .ruby-version
is found within the project or globally, then default to a setting within init.el
Set up code to have a use-package
keyword for specifying that a package is
part of package-selected-packages
.
I may switch from straight
to just using use-package
with :vc
This was previously used when setting up ctags
with the project.
This is an example configuration I had:
;; From here: https://github.com/universal-ctags/citre
(use-package citre
:defer t
:init
;; This is needed in `:init' block for lazy load to work.
(require 'citre-config)
;; Bind your frequently used commands. Alternatively, you can define them
;; in `citre-mode-map' so you can only use them when `citre-mode' is enabled.
(global-set-key (kbd "C-x c j") 'citre-jump)
(global-set-key (kbd "C-x c J") 'citre-jump-back)
(global-set-key (kbd "C-x c P") 'citre-ace-peek)
(global-set-key (kbd "C-x c p") 'citre-peek)
(global-set-key (kbd "C-x c u") 'citre-update-this-tags-file)
:config
(setq
;; Set these if readtags/ctags is not in your path.
citre-readtags-program "/usr/local/bin/readtags"
citre-ctags-program "/usr/local/bin/ctags"
;; Set this if you use project management plugin like projectile. It's
;; used for things like displaying paths relatively, see its docstring.
citre-project-root-function #'projectile-project-root
;; Set this if you want to always use one location to create a tags file.
citre-default-create-tags-file-location 'global-cache
;; See the "Create tags file" section above to know these options
citre-use-project-root-when-creating-tags t
citre-prompt-language-for-ctags-command t
;; By default, when you open any file, and a tags file can be found for it,
;; `citre-mode' is automatically enabled. If you only want this to work for
;; certain modes (like `prog-mode'), set it like this.
citre-auto-enable-citre-mode-modes '(prog-mode)))
;; Fallback to Citre if reference can't be found within LSP
;; From: https://github.com/universal-ctags/citre/wiki/Use-Citre-together-with-lsp-mode
(define-advice xref--create-fetcher (:around (-fn &rest -args) fallback)
(let ((fetcher (apply -fn -args))
(citre-fetcher
(let ((xref-backend-functions '(citre-xref-backend t)))
(apply -fn -args))))
(lambda ()
(or (with-demoted-errors "%s, fallback to citre"
(funcall fetcher))
(funcall citre-fetcher)))))
;; Use Citre with company
;; From: https://github.com/universal-ctags/citre/wiki/Use-Citre-together-with-lsp-mode
(defun company-citre (-command &optional -arg &rest _ignored)
"Completion backend of Citre. Execute COMMAND with ARG and IGNORED."
(interactive (list 'interactive))
(cl-case -command
(interactive (company-begin-backend 'company-citre))
(prefix (and (bound-and-true-p citre-mode)
(or (citre-get-symbol) 'stop)))
(meta (citre-get-property 'signature -arg))
(annotation (citre-capf--get-annotation -arg))
(candidates (all-completions -arg (citre-capf--get-collection -arg)))
(ignore-case (not citre-completion-case-sensitive))))