reddit / emacs

How to rewrite my large init.el file with use-package

pragmat1c1 · 2022-06-04 15:46
I have started using Emacs in summer 2020 seriously, and when I did this I have rewritten my init.el file from the scratch. Now I was aware that many out there use `use-package` for configuration, but I always postponed using it. Meanwhile my `init.el` file has over 5000 lines, and it seems like an unsurmountable mountain to rewrite it using use-package. The biggest chellange for me is: I have custom functions and configs spread all over my init.el file. How do I know which of those settings belong together into one use-package sexpr? Is there a good intro / article that shows me how to tackle this task? Anyone can point me to some articles / threads? ## Edit: Just to give an example ### Example 1 ;; -------------------------------------------------------------- ;;; `DEVONthink' shortcuts ;; -------------------------------------------------------------- (defun ugt-open-devonthink-database (name url) "Open DEVONthink database." (interactive) (let ((uid (substring url 20))) (org-devonthink-item-open uid))) Where do I put this? In which `use-package` expression? ### Example 2 (set-fontset-font t '(#x1f000 . #x1faff) (font-spec :family "Apple Color Emoji")) ;; ---------------------------------------------------------------------- ;;; encoding ;; ---------------------------------------------------------------------- ;; https://www.masteringemacs.org/article/working-coding-systems-unicode-emacs (prefer-coding-system 'utf-8) (set-default-coding-systems 'utf-8) (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) (setq default-buffer-file-coding-system 'utf-8) (set-language-environment "UTF-8") ;; via xah ;; ---------------------------------------------------------------------- ;;; basic settings ;; ---------------------------------------------------------------------- ;;; turn off "beeps" (setq ring-bell-function 'ignore) ;;; do not yank with decorations (strip properties) (setq yank-excluded-properties t) ;;; confirm exit ;;(setq confirm-kill-emacs 'yes-or-no-p) ;;; basic settings ;;;; turn off toolbar if not in terminal ;; (when (display-graphic-p) ;; ;;(menu-bar-mode -1) ;; (toggle-scroll-bar -1) ;; (tool-bar-mode -1)) ;;(menu-bar-mode -1) (toggle-scroll-bar -1) (tool-bar-mode -1) ;;; column numbers (setq column-number-mode t) ;;;; disable splash screen and startup message ;; https://linux-tips.com/t/disabling-emacs-splash-screen/211 (setq inhibit-startup-message t) ;;(setq initial-scratch-message nil) ;;;; tab related ;; https://emacs.stackexchange.com/a/45063/29404 (setq-default indent-tabs-mode nil) (setq-default tab-width 8) ;;(setq indent-line-function 'insert-tab) ;;;; join lines (using it a lot) (defun ugt-join-line-with-next () "Join this line and next line. Default function `join-line' will join this with previous line." (interactive) (forward-line 1) (join-line)) (global-set-key (kbd "M-j") 'ugt-join-line-with-next) (defun ugt-join-line-with-previous () "Join this line and next line. Default function `join-line' will join this with previous line." (interactive) (join-line)) (global-set-key (kbd "M-J") 'ugt-join-line-with-previous) ### Example 3 ;; -------------------------------------------------------------- ;;; `magit' shortcuts ;; -------------------------------------------------------------- (defun ugt-magit-blame-addition () "Blame additions if file visiting buffer" (interactive) (if buffer-file-name (call-interactively 'magit-blame-addition) (message "Buffer is not visiting a file."))) (defun ugt-magit-status-org-file () "Magit status for current buffer." (interactive) (magit-status org-directory)) (defun ugt-magit-status-current-file () "Magit status for current buffer." (interactive) (magit-status (file-name-directory buffer-file-name))) (defhydra ugt-magit (:color red :hint nil :exit nil) " ^Magit Menu^ ^^^^^^^^^^^^---------------------------------------------------- _a_ magit-log-all _c_ magit-log-current _l_ magit-log-buffer-file _b_ magit-balame-addition (for current buffer file) _o_ magit-status-org-file _s_ magit-status-current-file ------------------------------------------------------------- " ("a" magit-log-all) ("c" magit-log-current) ("l" magit-log-buffer-file) ("b" ugt-magit-blame-addition) ("o" ugt-magit-status-org-file) ("s" ugt-magit-status-current-file) ("q" nil "Quit" :color blue)) (global-set-key (kbd "s-m") 'ugt-magit/body)
MitchellMarquez42 · 2022-06-04 16:32
1. _Not everything needs to be in a `use-package` statement._ For example, I put all my functions in a separate file, then use a `require` to load it. There's probably a better way of doing that too, but for now it's nice to at least trim the init-file down. One thing I've seen some people do for common settings like Encoding is (use-package emacs :init (set-default-coding-system 'utf8) ;; etc... ) but again, that's not necessary at all. 2. For things like Example 3 where it's all magit-related stuff, you could do something like (use-package magit :init ;; defuns, defhydra :bind ((kbd "s-m") 'ugt-magit/body)) Hope this helps just a little bit before someone comes along with actual links...
pragmat1c1 · 2022-06-04 16:37
These are good ideas. Thank you.
__rompy · 2022-06-04 20:36
For the defuns you could use `:preface`. Some of the options mentioned can be set using `:custom`. Iirc use-package integrates with hydra too. Look at my dotfiles, I set a lot of the mentioned things (some with use-package, some directly with setq): https://github.com/cbsirb/dotfiles/blob/master/emacs.d/init.el
Phil-Hudson · 2022-06-05 04:37
The top two suggestions I had have already been given (split out and `require` sub-files, use `:preface`). I'd just add a couple of useful `use-package`-adjacent techniques. The first is `initsplit` (by the same author), which lets you group your Customize settings into sub-files automatically and transparently by regex. The second is this: don't be afraid to create and use your own features. Each feature is just a symbol, after all. You can add features (using `provide`) like `'my/startup-complete`, then use them in `use-package` `:after` clauses, or in your own `with-eval-after-load` forms.
AptC34 · 2022-06-05 21:32
I’d suggest you don’t put functions inside your use-package definitions. It will look like these functions are private to them but they are not. Once they run they are available on the global environment. The structure of my init file is very simple: 1. the bootstrapping code for straight/use package, 2. all my defuns, 3. all my use package declarations. In my use-package declarations I just reference my defuns. Either as hooks or as bindings. Notice that there’s the fake package “emacs ” for every configuration that is not tied to an external package. You can also nest use-package declarations. For example. I have a use-package for a programming language and in its config session I have a use package for eglot containing the eglot specific configuration/hooks for this language.
pragmat1c1 · 2022-06-06 09:04
> fake package “emacs ” Excellent. Thank you. Will need that.