Emacs: Restructure config

And actually use a default tangle header (lol)
This commit is contained in:
hedy 2023-09-16 21:33:35 +08:00
parent a5c7d5125b
commit e67a7ea8c4
Signed by: hedy
GPG Key ID: B51B5A8D1B176372
4 changed files with 910 additions and 247 deletions

View File

@ -0,0 +1,4 @@
dotslash-lisp
=============
This is for experimental or personal "packages".

View File

@ -0,0 +1,4 @@
dotslash-modules
================
These are extracted, modularized configuration for packages. The package.org file tangles into packages.el here. It `provide's packages `packages'.

View File

@ -1,44 +1,80 @@
#+title: Init.El Literate
:PROPERTIES:
:tangle: ~/.config/emacsd/init.el
:END:
#+TITLE: Init.El Literate
#+PROPERTY: header-args:elisp :tangle ~/.config/emacs/init.el
#+auto_tangle: t
* Variables
#+BEGIN_SRC elisp
(defvar ./variable-pitch-display-font
"Fira Sans"
"Font used for titles")
(defvar ./face-fixed-pitch
'(:foundry "apple" :family "Fira Code" :height 160)
"Contents to be passed to (`set-face-attribute' 'fixed-pitch nil [...]) ")
(defvar ./face-variable-pitch
'(:foundry "apple" :family "Inter" :height 170)
"Contents to be passed to (`set-face-attribute' 'variable-pitch nil [...]) ")
#+END_SRC
* Local custom init (pre)
This file is not tracked in dotfiles and is to be unique, custom configurations for each machine.
It is loaded after [[Variables]] so that I can customize those variables within the file.
#+BEGIN_SRC elisp
(load (locate-user-emacs-file "dotslash-local-pre.el") :no-error :no-message)
#+END_SRC
* Basics
#+BEGIN_SRC emacs-lisp :tangle yes
Make sure custom settings are in a separate file so I can find (and extract) then easily. If they were to be appended to =init.el= it won't work anyway, since my =init.el= is controlled by this Literate config.
#+BEGIN_SRC elisp
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(defun display-startup-echo-area-message ()
(message (format "Emacs %s loaded from %s"
emacs-version user-emacs-directory)))
(message (format "Emacs %s loaded from %s in %s"
emacs-version user-emacs-directory (emacs-init-time))))
(global-set-key (kbd "C-c C-r") 'eval-region)
(setq initial-scratch-message (concat ";; *SCRATCH*\n"
";; C-c C-b (eval-buffer) C-c C-r (eval-region)\n"
";; C-x C-s will let you choose where to save\n\n; "))
(setq initial-scratch-message
(concat ";; *SCRATCH*\n"
";; C-c C-b (eval-buffer) C-c C-r (eval-region)\n"
";; C-x C-s will let you choose where to save\n\n; "))
#+END_SRC
;; Display
** Display
#+BEGIN_SRC elisp
;; Setting this in early-init doesn't seem to work
(set-frame-position (selected-frame) 100 10)
(set-face-attribute 'default nil :height 160)
(add-to-list 'bdf-directory-list "~/Library/Fonts")
(custom-theme-set-faces
'user
'(variable-pitch ((t (:foundry "apple" :family "IBM Plex Sans" :weight normal :height 170))))
'(fixed-pitch ((t (:foundry "apple" :family "Fira Code" :height 160)))))
(set-face-attribute 'default nil :foundry "apple" :family "Fira Code" :height 160)
(set-face-attribute 'variable-pitch nil :foundry "apple" :family "IBM Plex Sans" :height 170)
;; (custom-theme-set-faces
;; 'user
;; '(variable-pitch ((t (:inherit ./face-variable-pitch))))
;; '(fixed-pitch ((t (:inherit ./face-fixed-pitch)))))
(apply #'set-face-attribute 'variable-pitch nil ./face-variable-pitch)
(apply #'set-face-attribute 'fixed-pitch nil ./face-fixed-pitch)
(apply #'set-face-attribute 'default nil ./face-fixed-pitch)
#+END_SRC
** Better defaults (misc)
#+BEGIN_SRC elisp
;;(global-display-line-numbers-mode 1)
(add-hook 'prog-mode-hook (lambda () (display-line-numbers-mode 1)))
(add-hook 'text-mode-hook (lambda () (display-line-numbers-mode 1)))
;; I think this saves the last cursor pos or something
;; FIXME: doesn't work
(require 'saveplace)
(setq-default save-place t)
(setq save-place-file (expand-file-name ".places" user-emacs-directory))
;; Some better defaults?
(setq make-backup-files nil)
(setq auto-save-default nil)
(setq-default major-mode 'text-mode)
@ -55,27 +91,44 @@
(setq electric-pair-inhibit-predicate 'electric-pair-conservative-inhibit)
(electric-pair-mode 1)
(winner-mode 1)
(delete-selection-mode 1) ;; Select and type would replace the selected text
;; IDK
(add-hook 'prog-mode-hook #'subword-mode)
(add-hook 'minibuffer-setup-hook #'subword-mode)
#+END_SRC
;; elisp
(add-hook 'emacs-lisp-mode-hook
** Elisp
#+BEGIN_SRC elisp
(add-hook 'elisp-mode-hook
(lambda ()
(local-set-key (kbd "C-c C-x") #'ielm)
(local-set-key (kbd "C-c C-c") #'eval-defun)
;; These are never used...
;; (local-set-key (kbd "C-c C-x") #'ielm)
;; (local-set-key (kbd "C-c C-c") #'eval-defun)
(local-set-key (kbd "C-c C-r") 'eval-region)
(local-set-key (kbd "C-c C-b") #'eval-buffer)))
#+END_SRC
** WIndow divider
This makes resizing by mouse dragging easier, as it increases the divider width between window borders to make it easy to drag by the pointer targetting that divider area.
#+BEGIN_SRC elisp
(setq window-divider-default-right-width 8)
(setq window-divider-default-places 'right-only)
(window-divider-mode 1)
#+END_SRC
* Helper functions
Hopefully I'll be consistent with the convention of using =./= for all self-defined functions.
To search for these in completion systems, use =\./= (\o/ :D). =./= stands for DOTSLASH
The function below is adapted from a blog post (link lost, sorry) which describes how you can define a function to quickly insert a src code block.
I've adapted it to automatically use =emacs-lisp :tangle yes= if the file currently being edited is in the =user-emacs-directory=, since I use a literate emacs configuration and the only time I'll use this function when I'm in the user emacs directory is when I'm editing my literate org configuration.
I've adapted it to automatically use =elisp :tangle yes= if the file currently being edited is in the =user-emacs-directory=, since I use a literate emacs configuration and the only time I'll use this function when I'm in the user emacs directory is when I'm editing my literate org configuration.
Otherwise (editing any other files) it will read input from the minibuffer for text to insert after the =#+BEGIN_SRC=. The original function used ido completing read with a list of known code types and I've nuked it and just let the user append what ever they want after =#+BEGIN_SRC=: this could be useful for adding =:stuff like this= after the code-type.
@ -83,9 +136,9 @@ Recently I've also added ability to wrap a selected region with src instead, if
This is useful when I transfer org documents written with fixed-pitch font environment where I relied on plain text formatting, so when editting in variable-pitch font I can wrap it within src blocks to have it be formatted properly.
Most-recently I've also added deleting an empty src block (created by =./org-insert-src= itself) if point is within a src block with no content other than a single empty line.
Most recently I've also added deleting an empty src block (created by =./org-insert-src= itself) if point is within a src block with no content other than a single empty line.
#+BEGIN_SRC emacs-lisp :tangle yes
#+BEGIN_SRC elisp
(defun ./org-insert-src (beg end)
"Insert (or wrap region with, or cancel) src block.
@ -98,7 +151,7 @@ cancelling org-edit-src with C-c C-k.
Code type is prompted and `org-edit-src-code' called only for insert,
not for wrap.
Uses 'emacs-lisp :tangle yes' if currently in user-emacs-directory."
Uses 'elisp' if currently in user-emacs-directory."
(interactive (if (use-region-p)
(list (region-beginning) (region-end))
(list (point-min) (point-min))))
@ -106,7 +159,7 @@ Uses 'emacs-lisp :tangle yes' if currently in user-emacs-directory."
(code-type '(if (string=
(file-truename user-emacs-directory)
(file-name-directory (buffer-file-name)))
"emacs-lisp :tangle yes"
"elisp"
(read-from-minibuffer "#+BEGIN_SRC "))))
(if (< (length selection) 2)
(if (./org-empty-src-p)
@ -144,7 +197,11 @@ Uses 'emacs-lisp :tangle yes' if currently in user-emacs-directory."
;; FIXME: putting cursor at the begin src part afterwards doesn't work
(re-search-backward "^\\s-*#\\+BEGIN_SRC")
(end-of-line))))
#+END_SRC
Below is two helper functions used by the above helper function.
#+BEGIN_SRC elisp
(defun ./match-line-p (regexp &optional move keep-pos start)
"Wrapper around string-match-p to use contents of current line.
@ -183,10 +240,11 @@ contents of the required line."
Below is also another helper function for editing my literate configuration. It uses the =#+BEGIN_SRC= content from the current code block (that the cursor is in) and splits the block into two by inserting =#+END_SRC= and copying whatever =#+BEGIN_SRC <...>= that was used in the current code block.
- ~save-excursion~ allows execution of some expressions then move the point back to where it was (before the save-excursion call).
- Note that the ~re-search-backward~ seems to be case-insensitive, surprisingly, so both =BEGIN_SRC= and =begin_src= could be matched.
This is extremely useful when I want to paste some chunk of code into a big code block, then I decide to split them up in order to add documentation for them.
#+begin_src emacs-lisp :tangle yes
Note that ~re-search-backward~ seems to be case-insensitive, surprisingly, so both =BEGIN_SRC= and =begin_src= could be matched.
#+BEGIN_SRC elisp
(defun ./org-split-src ()
"Split current src block into two blocks at point.
@ -198,7 +256,7 @@ Retains src properties."
(defvar beginsrc (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
(insert beginsrc)
(previous-line))
#+end_src
#+END_SRC
** Load file and directory
@ -206,7 +264,7 @@ https://www.emacswiki.org/emacs/LoadingLispFiles#h5o-2 -- Thanks!
This is used for loading my =modules/= dir in =packages.el=.
#+BEGIN_SRC emacs-lisp :tangle yes
#+BEGIN_SRC elisp
(defun ./load-directory (dir)
"Load *.el files in a given directory"
(let ((load-it (lambda (f)
@ -216,7 +274,7 @@ This is used for loading my =modules/= dir in =packages.el=.
TBH this is such a small function but like, does save some parens y'know.
#+BEGIN_SRC emacs-lisp :tangle yes
#+BEGIN_SRC elisp
(defun ./load-file-if-exists (file)
"Same as load-file but NOP if file does not exist"
(if (file-exists-p file)
@ -227,7 +285,7 @@ TBH this is such a small function but like, does save some parens y'know.
https://www.emacswiki.org/emacs/ToggleWindowSplit
#+BEGIN_SRC emacs-lisp :tangle yes
#+BEGIN_SRC elisp
(defun toggle-window-split ()
(interactive)
(if (= (count-windows) 2)
@ -255,11 +313,10 @@ https://www.emacswiki.org/emacs/ToggleWindowSplit
#+END_SRC
* Packages - Elpaca
Bootstrap installation of Elpaca
#+BEGIN_SRC emacs-lisp :tangle yes
#+BEGIN_SRC elisp
(defvar elpaca-installer-version 0.5)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
@ -301,35 +358,94 @@ Bootstrap installation of Elpaca
Note that disabling the built-in =package.el= is in =early-init.el=, which also includes setting of frame size and others.
Enable =use-package= for elpaca and load my package definitions in packages.org
#+BEGIN_SRC emacs-lisp :tangle yes
;; Install use-package support
(elpaca elpaca-use-package
;; Enable :elpaca use-package keyword.
(elpaca-use-package-mode)
;; Assume :elpaca t unless otherwise specified.
(setq elpaca-use-package-by-default t))
#+BEGIN_SRC elisp
;; Install use-package support
(elpaca elpaca-use-package
;; Enable :elpaca use-package keyword.
(elpaca-use-package-mode)
;; Assume :elpaca t unless otherwise specified.
(setq elpaca-use-package-by-default t))
;; Block until current queue processed.
(elpaca-wait)
;; Block until current queue processed.
(elpaca-wait)
;;When installing a package which modifies a form used at the top-level
;;(e.g. a package which adds a use-package key word),
;;use `elpaca-wait' to block until that package has been installed/configured.
;;For example:
;;(use-package general :demand t)
;;(elpaca-wait)
(load (expand-file-name "packages.el" user-emacs-directory))
;;When installing a package which modifies a form used at the top-level
;;(e.g. a package which adds a use-package key word),
;;use `elpaca-wait' to block until that package has been installed/configured.
;;For example:
;;(use-package general :demand t)
;;(elpaca-wait)
#+END_SRC
Below is useful when elpaca installs a package for the first time, and I passed my org literate config files from calling emacs, which would have already been opened, this prevents the right hooks from packages to be loaded; hence I should source my packages config again.
* Fontaine
TODO: doesn't seem to work if called interactively, but if I'm here and use =C-x C-e= on the =( load ...)= call it works -- doesn't trigger elpaca?
This package is the only =use-package= package that is defined outside of =packages.el=.
#+BEGIN_SRC emacs-lisp :tangle yes
(defun ./reload-packages.el ()
"Source packages.el again"
(interactive)
(load (expand-file-name "packages.el" user-emacs-directory)))
FIXME: This doesn't work. Does this have to do with foundries?
#+BEGIN_SRC elisp :noweb yes :noweb-prefix no :tangle no
(use-package fontaine
:config
(setq fontaine-presets <<fontaine-presets>>)
<<fontaine-theme-hook>>
)
#+END_SRC
#+BEGIN_SRC elisp :noweb-ref fontaine-presets :tangle no
'((regular
:default-family "Fira Code"
:default-weight normal
:default-height 160
:fixed-pitch-family "Fira Code"
:fixed-pitch-height 1.0
:variable-pitch-family "Inter"
:variable-pitch-weight normal
:variable-pitch-height 170
:bold-weight bold
:italic-family "Source Code Pro"
:italic-slant italic
:line-spacing 1)
(large
:default-family "Fira Code"
:default-weight normal
:default-height 190
:variable-pitch-family "Fira Sans"
:variable-pitch-weight normal
:variable-pitch-height 1.5
:bold-weight bold
:italic-slant italic
:line-spacing 1.5))
#+END_SRC
https://github.com/protesilaos/fontaine?tab=readme-ov-file#41-persist-font-configurations-on-theme-switch
This allows the font settings to be re-applied after a theme switch.
#+BEGIN_SRC elisp :noweb-ref fontaine-theme-hook :tangle no
(defvar ./post-enable-theme-hook nil
"Normal hook run after enabling a theme.")
(defun ./run-post-enable-theme-hook (&rest _args)
"Run `./post-enable-theme-hook'."
(run-hooks './post-enable-theme-hook))
(advice-add 'enable-theme :after #'./run-post-enable-theme-hook)
(add-hook './post-enable-theme-hook #'fontaine-apply-current-preset)
#+END_SRC
* Packages & Modules
#+BEGIN_SRC elisp
(dolist (path '("dotslash-lisp" "dotslash-modules"))
(add-to-list 'load-path (locate-user-emacs-file path)))
(require 'packages)
(require 'init-highlight)
#+END_SRC
* Local custom init (post)
This file is not tracked in dotfiles and is to be unique, custom configurations for each machine, run at the very end of =init.el=. (Also see [[Local custom init (pre)]].)
#+BEGIN_SRC elisp
(load (locate-user-emacs-file "dotslash-local-post.el") :no-error :no-message)
#+END_SRC

File diff suppressed because it is too large Load Diff