Commit 475a0936 authored by Neil Mather's avatar Neil Mather
Browse files

Literature config for spacemacs files

parent 535d3269
#+TITLE: 2020-11-26
- More and more I would like to learn [[file:../racket.org][Racket]].
- I'm encountering increasingly frequent slowdowns and annoyances in [[file:../emacs.org][Emacs]] of late. I think mostly when I'm working in [[file:../org-roam.org][org-roam]]. It seems pretty buggy - possibly just due to my config. But it doesn't find files that I know exist, it slows down massively when processing the DB.
- Ah - so not finding files might have been due to my use of a relative path in dir-locals.
- I seem to have to keep on running ~org-roam-db-clear~ and ~org-roam-db-build-cache~ of late. Hope I've got it sorted now.
- I am also getting big, annoying interruptions from this background process that runs to update the DB. ~org-roam-db-update-method~ is set to ~'idle-timer~, and ~org-roam-db-update-idle-seconds~ by default is set to 2. I think I'll try changing the method first to ~'immediate~. If that is still no good, I'll change back to idle timer but with a increased number of seconds.
- immediate works a bit better for me, because I'm more likely to naturally pause after saving a file, so the brief processing time doesn't bother me as much.
- Still, would be good to see if the time for updating the DB could be reduced.
- A [[file:../20200801184138-spaced_repetition.org][spaced repetition]] approach that might work with org-roam: [[https://ag91.github.io/blog/2020/09/04/the-poor-org-user-spaced-repetition/][The Poor Org-User Spaced Repetition - Where parallels cross]]
- Removed [[file:../helm.org][helm]] duplicates, that was getting a bit annoying. https://github.com/syl20bnr/spacemacs/issues/13564
- My [[file:../spacemacs.org][spacemacs]] config is getting a bit unwieldy. I'd quite like to do that org-babel literate config thing that people do. But probably a bit of a unnecessary yak shave right now.
- Decided to shave that yak. Not too bad. [[file:../setting_up_a_spacemacs_literate_config_file.org][Setting up a spacemacs literate config file]].
- Decided to shave that yak. Not too bad. [[file:../setting-up-a-spacemacs-literate-config-file.org][Setting up a spacemacs literate config file]].
- I'd like to the issue on [[file:../flock.org][Flock]] where reloading a page with stacked notes sometimes gives a 'page not redirecting correctly' error.
- Also some links from subfolders don't work.
#+title: Literate config
#+TITLE: My Spacemacs User Config
#+property: header-args:elisp :tangle ~/.spacemacs.d/user-config.el :comments org
#+LAST_MODIFIED: [2020-11-26 Thu 16:29]
* Preamble
This is the [[file:literate-config.org][literate]] source for my [[file:spacemacs.org][spacemacs]] user config. I use [[file:org-babel.org][org-babel]] to tangle it together into the actual config file.
#+begin_src elisp :exports none
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; GENERATED FROM USER-CONFIG.ORG - DON'T EDIT THIS DIRECTLY!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#+end_src
#+TOC: headlines 2
* Coding
** PHP
*** Set up keyboard shortcuts for PHPUnit
#+begin_src elisp
(with-eval-after-load 'php-mode
(define-key php-mode-map (kbd "C-c C-t t") 'phpunit-current-test)
(define-key php-mode-map (kbd "C-c C-t c") 'phpunit-current-class)
(define-key php-mode-map (kbd "C-c C-t p") 'phpunit-current-project))
#+end_src
*** Use web-mode for Laravel templates.
#+begin_src elisp
(add-to-list 'auto-mode-alist '("\\.blade.php\\'" . web-mode))
#+end_src
* Productivity
** org
*** Agenda
**** Use org-super-agenda a nicer looking agenda.
#+begin_src elisp
(org-super-agenda-mode)
(setq org-agenda-custom-commands
'(("g" "Super groups"
agenda ""
((org-super-agenda-groups
'((:auto-property "agenda-group")))))
("u" "Super view"
agenda ""
((org-super-agenda-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Today" ; Optionally specify section name
:time-grid t ; Items that appear on the time grid
:tag "today"
:todo "TODAY") ; Items that have this TODO keyword
(:name "Important"
;; Single arguments given alone
:tag "bills"
:priority "A")
;; Set order of multiple groups at once
(:name "Quick wins (< 20 mins)"
:effort< "0:20")
(:name "Cleaning"
:tag "cleaning"
:order 5)
(:name "Chores"
:tag "chore"
:order 5)
(:name "Stuck"
:tag "stuck"
:order 2)
(:name "Town"
:tag ("town" "@town")
:order 9)
(:order-multi (2 (:name "Shopping in town"
;; Boolean AND group matches items that match all subgroups
:and (:tag "shopping" :tag "@town"))
;;(:name "Personal"
;; :habit t
;; :tag "personal")
(:name "Food-related"
;; Multiple args given in list with implicit OR
:tag ("food" "dinner"))))
;; Groups supply their own section names when none are given
(:todo "WAITING" :order 8) ; Set order of this section
(:todo ("SOMEDAY" "TO-READ" "CHECK" "TO-WATCH" "WATCHING")
;; Show this group at the end of the agenda (since it has the
;; highest number). If you specified this group last, items
;; with these todo keywords that e.g. have priority A would be
;; displayed in that group instead, because items are grouped
;; out in the order the groups are listed.
:order 9)
(:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:order 3)
;; After the last group, the agenda will display items that didn't
;; match any of these groups, with the default order position of 99
))))))
#+end_src
*** Capturing
**** capture templates
#+begin_src elisp
(require 'org-protocol)
(add-to-list 'load-path "/home/neil/.emacs.d/private/org-protocol-capture-html")
(require 'org-protocol-capture-html)
(setq org-capture-templates
(quote
(("c" "TODO scheduled today"
entry (file+headline "~/org/_GTD.org" "Inbox")
"** TODO %?\n SCHEDULED: %t\n")
("w" "Web site"
entry (file+olp "/home/shared/commonplace/clippings.org" "Clippings")
"** %c :website:\n%U %?%:initial"))))
;; to start in insert mode when creating via capture template
(add-hook 'org-capture-mode-hook 'evil-insert-state)
#+end_src
*** Refiling
#+begin_src elisp
(setq org-refile-targets '((nil :maxlevel . 9)
(org-agenda-files :maxlevel . 9)))
(setq org-outline-path-complete-in-steps nil) ; Refile in a single go
(setq org-refile-use-outline-path t) ; Show full paths for refiling
#+end_src
*** Babel
#+begin_src elisp
;; babel
(with-eval-after-load 'org
(org-babel-do-load-languages
'org-babel-load-languages
'((sql . t)
(python . t)
(plantuml . t)
(sqlite . t)
(shell . t))))
#+end_src
*** Misc
**** Deleting links
See: https://emacs.stackexchange.com/questions/10707/in-org-mode-how-to-remove-a-link
#+begin_src elisp
(defun ngm/org-delete-link ()
"Replace an org link of the format [[LINK][DESCRIPTION]] with DESCRIPTION.
If the link is of the format [[LINK]], delete the whole org link.
In both the cases, save the LINK to the kill-ring.
Execute this command while the point is on or after the hyper-linked org link."
(interactive)
(when (derived-mode-p 'org-mode)
(let ((search-invisible t) start end)
(save-excursion
(when (re-search-backward "\\[\\[" nil :noerror)
(when (re-search-forward "\\[\\[\\(.*?\\)\\(\\]\\[.*?\\)*\\]\\]" nil :noerror)
(setq start (match-beginning 0))
(setq end (match-end 0))
(kill-new (match-string-no-properties 1)) ; Save the link to kill-ring
(replace-regexp "\\[\\[.*?\\(\\]\\[\\(.*?\\)\\)*\\]\\]" "\\2" nil start end)))))))
#+end_src
**** org-timeline
#+begin_src elisp
(require 'org-timeline)
(add-hook 'org-agenda-finalize-hook 'org-timeline-insert-timeline :append)
#+end_src
* Writing and knowledge management
I do my writing mostly in org-journal and org-roam.
#+begin_src elisp
(setq org-journal-file-format "%Y-%m-%d.org")
#+end_src
** Writing mode
A couple of customisations to make writing prose a nice experience.
#+begin_src elisp
(defun ngm-visual-line-motion ()
"So j and k move up and down more like you'd expect in visual line mode"
(interactive)
(define-key evil-motion-state-map "j" 'evil-next-visual-line)
(define-key evil-motion-state-map "k" 'evil-previous-visual-line))
(defun ngm-journal-mode ()
"Set up journalling mode the way that I like it"
(interactive)
(olivetti-mode)
(variable-pitch-mode 1)
(face-remap-add-relative 'variable-pitch '(:family "Roboto Slab" :height 140))
(ngm-visual-line-motion)
(setq company-backends '(company-capf)) ; for org-roam completion
)
#+end_src
** org-roam
org-roam builds on top of org-mode, but I feel like it deserves it's own section.
*** Prefer immediate DB update method.
This updates the DB on save, rather than on an idle timer. I was finding idle timer frustrating, as the unexpected DB update interrupted my flow. Updating on save works better for me, as I tend to pause momentarily after a save anyway, as I usually save at the end of a sentence.
#+begin_src elisp
(setq org-roam-db-update-method 'immediate)
#+end_src
*** Wikilink syntax for adding links
For inserting links to other wiki pages more quickly, essentially with wikilink syntax.
See: [[file:using_fuzzy_links_aka_wikilinks_in_org_roam.org][Using fuzzy links AKA wikilinks in org-roam]].
#+begin_src elisp
(require 'key-chord)
(key-chord-mode 1)
(key-chord-define org-mode-map "[[" #'ngm/insert-roam-link)
(defun ngm/insert-roam-link ()
"Inserts an Org-roam link."
(interactive)
(insert "[[roam:]]")
(backward-char 2))
#+end_src
*** org-roam capture templates
Add CREATED and LAST_MODIFIED properties to the new note.
#+begin_src elisp
(setq org-roam-capture-templates
'(("d" "default" plain (function org-roam--capture-get-point)
"%?"
:file-name "${slug}"
:head "#+title: ${title}\n#+CREATED: %U\n#+LAST_MODIFIED: %U\n\n"
:unnarrowed t)))
(setq org-roam-dailies-directory "journal")
(setq org-roam-dailies-capture-templates '(("d" "daily" plain (function org-roam-capture--get-point) ""
:immediate-finish t
:file-name "journal/%<%Y-%m-%d>"
:head "#+TITLE: %<%Y-%m-%d>")))
#+end_src
#+RESULTS:
*** Updating timestamps on save
I would prefer to do this on org-roam files only.
See [[https://org-roam.discourse.group/t/update-a-field-last-modified-at-save/321/19][Update a field (#+LAST_MODIFIED: ) at save - How To - Org-roam]].
Doesn't seem to work though.
#+begin_src elisp
(setq time-stamp-active t
time-stamp-start "#\\+LAST_MODIFIED:[ \t]*"
time-stamp-end "$"
time-stamp-format "\[%04y-%02m-%02d %3a %02H:%02M\]")
(add-hook 'before-save-hook 'time-stamp nil)
#+end_src
*** Graph settings
Exclude some of the big files from the graph.
#+begin_src elisp
(setq org-roam-graph-exclude-matcher '("sitemap" "index" "recentchanges"))
#+end_src
* Look'n'feel
** Theme (Doom)
#+begin_src elisp
(doom-themes-treemacs-config)
(doom-themes-org-config)
#+end_src
** Solaire
See https://github.com/hlissner/emacs-solaire-mode
#+begin_src elisp
(require 'solaire-mode)
;; Enable solaire-mode anywhere it can be enabled
(solaire-global-mode +1)
;; To enable solaire-mode unconditionally for certain modes:
(add-hook 'ediff-prepare-buffer-hook #'solaire-mode)
;; ...if you use auto-revert-mode, this prevents solaire-mode from turning
;; itself off every time Emacs reverts the file
(add-hook 'after-revert-hook #'turn-on-solaire-mode)
;; highlight the minibuffer when it is activated:
(add-hook 'minibuffer-setup-hook #'solaire-mode-in-minibuffer)
;; if the bright and dark background colors are the wrong way around, use this
;; to switch the backgrounds of the `default` and `solaire-default-face` faces.
;; This should be used *after* you load the active theme!
;;
;; NOTE: This is necessary for themes in the doom-themes package!
(solaire-mode-swap-bg)
#+end_src
** Tabs (centaur)
Not currently using this, as I think it broke something.
#+begin_src elisp
;; centaur-tabs configuration
;; https://github.com/ema2159/centaur-tabs
;(require 'centaur-tabs)
;(centaur-tabs-mode t)
;(global-set-key (kbd "C-<prior>") 'centaur-tabs-backward)
;(global-set-key (kbd "C-<next>") 'centaur-tabs-forward)
;(centaur-tabs-mode)
;(centaur-tabs-headline-match)
;(setq centaur-tabs-set-modified-marker t
; centaur-tabs-modified-marker " ● "
; centaur-tabs-cycle-scope 'tabs
; centaur-tabs-height 35
; centaur-tabs-set-icons t
; centaur-tabs-close-button " × ")
;(dolist (centaur-face '(centaur-tabs-selected
; centaur-tabs-selected-modified
; centaur-tabs-unselected
; centaur-tabs-unselected-modified))
; (set-face-attribute centaur-face nil :family "Noto Sans Mono" :height 100))
#+end_src
** Helm
#+begin_src elisp
(defun open-local-file-projectile (directory)
"Helm action function, open projectile file within DIRECTORY
specify by the keyword projectile-default-file define in
`dir-locals-file'"
(let ((default-file (f-join directory (nth 1
(car (-tree-map (lambda (node)
(when (eq (car node) 'projectile-default-file)
(format "%s" (cdr node))))
(dir-locals-get-class-variables (dir-locals-read-from-dir directory))))))))
(if (f-exists? default-file)
(find-file default-file)
(message "The file %s doesn't exist in the select project" default-file)
)
)
)
;; helm-related
;; remove helm duplicates: https://github.com/syl20bnr/spacemacs/issues/13564
(setq history-delete-duplicates t)
(with-eval-after-load "helm-projectile"
(helm-add-action-to-source "Open default file"
'open-local-file-projectile
helm-source-projectile-projects)
)
;; (add-to-list 'helm-source-projectile-projects-actions '("Open default file" . open-local-file-projectile) t)
;; https://github.com/syl20bnr/spacemacs/issues/13100
;(setq completion-styles '(helm-flex))
#+end_src
* Communications
** mu4e (mail)
#+begin_src elisp
;; mu4e
(setq mu4e-maildir "~/Maildir"
mu4e-attachment-dir "~/downloads"
mu4e-sent-folder "/Sent"
mu4e-drafts-folder "/Drafts"
mu4e-trash-folder "/Trash"
mu4e-refile-folder "/Archive")
(setq user-mail-address "neil@doubleloop.net"
user-full-name "Neil Mather")
;; Get mail
(setq mu4e-get-mail-command "mbsync protonmail"
mu4e-change-filenames-when-moving t ; needed for mbsync
mu4e-update-interval 120) ; update every 2 minutes
(defun htmlize-and-send ()
"When in an org-mu4e-compose-org-mode message, htmlize and send it."
(interactive)
(when (member 'org~mu4e-mime-switch-headers-or-body post-command-hook)
(org-mime-htmlize)
(message-send-and-exit)))
(add-hook 'org-ctrl-c-ctrl-c-hook 'htmlize-and-send t)
;; composing mail
;(setq mu4e-compose-format-flowed nil)
;(add-hook 'mu4e-compose-mode-hook (lambda () (turn-off-auto-fill) (use-hard-newlines -1)))
;; enable format=flowed
;; - mu4e sets up visual-line-mode and also fill (M-q) to do the right thing
;; - each paragraph is a single long line; at sending, emacs will add the
;; special line continuation characters.
;; - also see visual-line-fringe-indicators setting below
(setq mu4e-compose-format-flowed t)
;; because it looks like email clients are basically ignoring format=flowed,
;; let's complicate their lives too. send format=flowed with looong lines. :)
;; https://www.ietf.org/rfc/rfc2822.txt
(setq fill-flowed-encode-column 998)
;; in mu4e with format=flowed, this gives me feedback where the soft-wraps are
(setq visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow))
;; Send mail
(setq message-send-mail-function 'smtpmail-send-it
smtpmail-auth-credentials "~/.authinfo" ;; Here I assume you encrypted the credentials
smtpmail-smtp-server "127.0.0.1"
smtpmail-smtp-service 1025)
;; look'n'feel
(setq mu4e-html2text-command 'mu4e-shr2text)
(setq shr-color-visible-luminance-min 60)
(setq shr-color-visible-distance-min 5)
(setq shr-use-colors nil)
(advice-add #'shr-colorize-region :around (defun shr-no-colourise-region (&rest ignore)))
#+end_src
** IRC (erc)
#+begin_src elisp
(setq erc-hide-list '("JOIN" "PART" "QUIT"))
#+end_src
* Misc
** Tidal
#+begin_src elisp
;; tidal
;;(add-to-list 'load-path "/home/neil/.emacs.d/private/tidal")
;;(require 'tidal)
#+end_src
#+title: org-babel
#+title: Setting up a spacemacs literate config file
* Why?
I use [[file:spacemacs.org][spacemacs]] *a lot*. For coding, for work, for organisation, for org-roam. It's central to to most of my day-to-day activities. I've been using for maybe 4 years now, and have built up quite a mess of a configuration file with various tweaks over the years.
Given how much I use it, it seems sensible to give a bit of TLC to this configuration. I've tried to comment it as I've tweaked it, but it still has gotten messy. And there's lots of longer form notes that get a bit lost as I don't put them in short comments.
I'm also just keen to try out org-babel for some literate coding, and this is an easy way in to doing that.
* What I did
Here's what I've done to get there.
** File reorganisation
#+begin_src shell
mkdir ~/.spacemacs.d
cp ~/.spacemacs .spacemacs.d/init.el
#+end_src
Try that, make sure things still work.
** Extract out user-config into own file
- move everything in user-config function in to .spacemacs.d/user-config.el
- source that from init.el
#+begin_src elisp
(defun dotspacemacs/user-config ()
(let ((uc (concat dotspacemacs-directory "user-config.el")))
(message (concat "ds-d" dotspacemacs-directory))
(load-file uc)))
#+end_src
* Move config into an org file and set up tangling on it
The section on [[https://leanpub.com/lit-config/read#leanpub-auto-converting-your-existing-config-files][Converting your existing config files]] in Literature Configuration was really helpful for this. Basically allowing you to move things piece by piece, and also a few handy tips and tricks such as ~org-babel-demarcate-block~ and file level properties.
So I moved my user-config in to [[file:my-spacemacs-user-config.org][My Spacemacs User Config]] here in my wiki, and set it up so that I can tangle that to ~.spacemacs/user-config.el~. I started off with one huge source block, but that gradually split that up with ~org-babel-demarcate-block~, putting each section in to an org heading.
* Resources
- [[https://leanpub.com/lit-config/read][Read Literate Configuration | Leanpub]]
- [[http://www.howardism.org/Technical/Emacs/literate-programming-tutorial.html][Introduction to Literate Programming]]
- [[https://www.reddit.com/r/emacs/comments/7ntc6p/spacemacs_configuration_in_a_structured_orgmode/][Spacemacs configuration in a structured org-mode file : emacs]]
#+title: Using fuzzy links AKA wikilinks in org-roam
Added in org-roam 1.2.2. These are my notes from when upgrading to that version.
#+begin_quote
In this release we support fuzzy links of the form ~[[roam:Title]]~, ~[[roam:*Headline]]~ and ~[[roam:Title*Headline]]~. Completion for these fuzzy links is supported via completion-at-point.
#+end_quote
I think I might need to set up company-at-point. Do I have it out of the box? The double-bracket thing isn't working, anyway.
Hmm, it's because for my ~ngm-journal-mode~, my writing mode that I use for files in my org-roam wiki, I turn it off. I think because it annoyed me with word completions all the time when I was writing. Maybe there's a way to choose which completions company mode does. I'll come back to that... for now I'll just not turn it off.
From this post, [[https://org-roam.discourse.group/t/how-to-to-get-title-of-the-target-note-working-with-inline-autocomplete-in-org-roam/782][How to to get {{Title of the target note}} working with inline autocomplete i...]], I can see that
#+begin_src emacs-lisp
(smartparens-global-mode t)
(setq company-minimum-prefix-length 2)
(setq company-idle-delay 0.25)
(setq company-backends '(company-capf))
#+end_src
works kind of.
But here [[https://www.orgroam.com/manual/Inserting-Links.html#Inserting-Links][Inserting Links (Org-roam User Manual)]] has a different way of doing it.
#+begin_quote
To easily insert roam links, one may wish to use a package like key-chord.
#+end_quote
OK, I installed key-chord by adding to spacemacs extra packages.
#+begin_src emacs-lisp
dotspacemacs-additional-packages '(... key-chord)
#+end_src
Then add the recommended function from org-roam docs in to my config.
#+begin_src emacs-lisp
(key-chord-define org-mode-map "[[" #'ngm/insert-roam-link)
(defun ngm/insert-roam-link ()
"Inserts an Org-roam link."
(interactive)
(insert "[[roam:]]")
(backward-char 2))
#+end_src
OK, so that works OK too. If I type [[ quickly, I can then start typing the name of the note and get autocompletion.
I think both of those ways work. I'll stick with the one from the docs.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment