Emacs: Restructure config
And actually use a default tangle header (lol)
This commit is contained in:
parent
a5c7d5125b
commit
e67a7ea8c4
|
@ -0,0 +1,4 @@
|
|||
dotslash-lisp
|
||||
=============
|
||||
|
||||
This is for experimental or personal "packages".
|
|
@ -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'.
|
|
@ -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
Loading…
Reference in New Issue