UI, Persistence

This commit is contained in:
Ashley Duckworth 2021-01-20 12:57:24 -06:00
parent d7b7145461
commit da92f0693f
3 changed files with 346 additions and 52 deletions

View File

@ -1,6 +1,6 @@
#+TITLE: Emacs configuration, literate-style
#+AUTHOR: Case Duckworth
#+PROPERTY: header-args :tangle yes :tangle-mode (identity #o444) :comments both :mkdirp yes
#+PROPERTY: header-args :tangle yes :tangle-mode (identity #o444) :comments both
* Settings
@ -56,11 +56,10 @@ These should not require non-built-in packages.
(add-function :before after-focus-change-function #'acdw/set-custom-faces)
(defmacro cussface (face spec &optional _docstring)
"Add the form (FACE SPEC) to `acdw--custom-faces', and add a
hook to run `acdw/set-custom-faces' after init."
"Add the form (FACE SPEC) to `acdw--custom-faces'."
(declare (doc-string 3)
(indent 2))
`(add-to-list acdw--custom-faces '(,face ,spec)))
(indent defun))
`(add-to-list 'acdw--custom-faces '(,face ,spec)))
#+end_src
*** Only do something when Emacs is unfocused
@ -110,43 +109,6 @@ My name and email address.
(blink-cursor-mode -1)
#+end_src
*** Dialogs and alerts
**** Don't use a dialog box
#+begin_src emacs-lisp
(cuss use-dialog-box nil)
#+end_src
**** Yes or no questions
#+begin_src emacs-lisp
(fset 'yes-or-no-p #'y-or-n-p)
#+end_src
**** The Bell
#+begin_src emacs-lisp
;; Don't flash the whole screen on bell
(cuss visible-bell nil)
;; Instead, flash the mode line
(cuss ring-bell-function #'flash-mode-line)
(defun flash-mode-line ()
(invert-face 'mode-line)
(run-with-timer 0.2 nil #'invert-face 'mode-line))
#+end_src
t*** Minibuffer
**** Keep the cursor away from the minibuffer prompt
#+begin_src emacs-lisp
(cuss minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
#+end_src
*** Tabs
**** Tab names should be current buffer + a count of windows
@ -237,20 +199,352 @@ and have made a custom fringe bitmap.
#+begin_src emacs-lisp
(cuss visual-line-fringe-indicators '(left-curly-arrow nil))
#+end_src
;; And make the `left-curly-arrow' indicator less distracting.
***** Customize fringe bitmaps
****** Curly arrows (continuation lines)
#+begin_src emacs-lisp
(define-fringe-bitmap 'left-curly-arrow
[#b11000000
#b01100000
#b00110000
#b00011000])
(define-fringe-bitmap 'right-curly-arrow
[#b00011000
#b00110000
#b01100000
#b11000000])
#+end_src
****** Arrows (truncation lines)
#+begin_src emacs-lisp
(define-fringe-bitmap 'left-arrow
[#b00000000
#b01010100
#b01010100
#b00000000])
(define-fringe-bitmap 'right-arrow
[#b00000000
#b00101010
#b00101010
#b00000000])
#+end_src
*** Windows
**** Winner mode
I don't really /use/ winner-mode as of yet, but it seems like a really
good thing to have. It lets you move between window configurations
with =C-c <-/->=.
#+begin_src emacs-lisp
(when (fboundp 'winner-mode)
(winner-mode +1))
#+end_src
**** Switch windows, or buffers if there's only one
from [[https://www.reddit.com/r/emacs/comments/kz347f/what_parts_of_your_config_do_you_like_best/gjlnp2c/][u/astoff1]].
#+begin_src emacs-lisp
(defun other-window-or-buffer ()
"Switch to the other window, or previous buffer."
(interactive)
(if (eq (count-windows) 1)
(switch-to-buffer nil)
(other-window 1)))
#+end_src
*** Buffers
**** Startup buffers
I don't want to see Emacs's splash screen, and I want the =*scratch*=
buffer to have a little message.
#+begin_src emacs-lisp
(cuss inhibit-startup-screen t
"Don't show the startup buffer.")
(cuss initial-buffer-choice t
"Start with *scratch*.")
(cuss initial-scratch-message
(concat ";; Hello, " (nth 0 (split-string user-full-name)) "!\n"
";; Happy hacking ..."))
#+end_src
**** Immortal =*scratch*= buffer
I don't want to accidentally kill the =*scratch*= buffer.
#+begin_src emacs-lisp
(defun immortal-scratch ()
(if (eq (current-buffer) (get-buffer "*scratch*"))
(progn (bury-buffer)
nil)
t))
(add-hook 'kill-buffer-query-functions #'immortal-scratch)
#+end_src
**** Uniquify buffers
I like the =forward= style, which uniquifies buffers by including path
elements up the tree until the names are unique.
#+begin_src emacs-lisp
(require 'uniquify)
(cuss uniquify-buffer-name-style 'forward)
#+end_src
**** Kill buffers more smarter-ly
#+begin_src emacs-lisp
(defun kill-a-buffer (&optional prefix)
"Kill buffers and windows sanely.
`kill-a-buffer' works based on the prefix argument as follows:
- 0 => kill the CURRENT buffer and window
- 4 (C-u) => kill the OTHER window and its buffer
- 16 (C-u C-u) => kill ALL OTHER buffers and windows
Prompt iff there are unsaved changes."
(interactive "P")
(pcase (or (car prefix) 0)
(0 (kill-current-buffer)
(unless (one-window-p) (delete-window)))
(4 (other-window 1)
(kill-current-buffer)
(unless (one-window-p) (delete-window)))
(16 (mapc #'kill-buffer (delq (current-buffer) (buffer-list)))
(delete-other-windows))))
#+end_src
*** Fonts
**** Function: =set-face-from-alternatives=
To be honest, this might be better off using =cussface=, but that's
another story for another day.
#+begin_src emacs-lisp
(defun set-face-from-alternatives (face frame &rest fontspecs)
"Set FACE on FRAME from first available font from FONTSPECS.
FACE and FRAME work the same as with `set-face-attribute'."
(catch :return
(dolist (spec fontspecs)
(when-let ((found (find-font (apply #'font-spec spec))))
(set-face-attribute face frame :font found)
(throw :return found)))))
#+end_src
**** Add a hook to setup fonts after the first window focus change
Of course, I only need to setup the fonts on a graphical session.
#+begin_src emacs-lisp
(when (display-graphic-p)
(add-function :before after-focus-change-function #'acdw/setup-fonts))
#+end_src
**** Setup my fonts
Notice that this function removes itself from
=after-focus-change-function=, since ideally you'll only need to set
the fonts once.
#+begin_src emacs-lisp
(defun acdw/setup-fonts ()
"Setup fonts.
This has to happen after the frame is setup for the first time,
so it should be added to `after-focus-change-function'. It
removes itself."
(set-face-from-alternatives 'default nil
'(:family "Input Mono"
:slant normal
:weight normal
:height 110)
'(:family "Consolas"
:slant normal
:weight normal
:height 100))
;; `fixed-pitch' should just inherit from `default'
(set-face-attribute 'fixed-pitch nil :inherit 'default)
(set-face-from-alternatives 'variable-pitch nil
'(:family "Input Sans"
:slant normal
:weight normal)
'(:family "Georgia"
:slant normal
:weight normal))
(remove-function after-focus-change-function #'acdw/setup-fonts))
#+end_src
**** Underlines
#+begin_src emacs-lisp
(cuss x-underline-at-descent-line t)
#+end_src
** Interactivity
*** Dialogs and alerts
**** Don't use a dialog box
#+begin_src emacs-lisp
(cuss use-dialog-box nil)
#+end_src
**** Yes or no questions
#+begin_src emacs-lisp
(fset 'yes-or-no-p #'y-or-n-p)
#+end_src
**** The Bell
#+begin_src emacs-lisp
;; Don't flash the whole screen on bell
(cuss visible-bell nil)
;; Instead, flash the mode line
(cuss ring-bell-function #'flash-mode-line)
(defun flash-mode-line ()
(invert-face 'mode-line)
(run-with-timer 0.2 nil #'invert-face 'mode-line))
#+end_src
t*** Minibuffer
*** Minibuffer
**** Keep the cursor away from the minibuffer prompt
#+begin_src emacs-lisp
(cuss minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
#+end_src
**** Enable recursive minibuffer
#+begin_src emacs-lisp
(cuss enable-recursive-minibuffers t)
#+end_src
**** Show how deep the minibuffer goes in the modeline
#+begin_src emacs-lisp
(minibuffer-depth-indicate-mode +1)
#+end_src
*** Completing-read
**** Shadow file names
When typing =~= or =/= in the file-selection dialog, Emacs "pretends"
that you've typed them at the beginning of the line. By default,
however, it only /fades out/ the previous contents of the line. I
want to /hide/ those contents.
#+begin_src emacs-lisp
(cuss file-name-shadow-properties '(invisible t))
(file-name-shadow-mode +1)
#+end_src
**** Ignore case
#+begin_src emacs-lisp
(cuss completion-ignore-case t)
(cuss read-buffer-completion-ignore-case t)
(cuss read-file-name-completion-ignore-case t)
#+end_src
** Persistence
*** Minibuffer history
The =savehist= package saves the minibuffer history between sessions.
It can also save some other variables alongside the minibuffer
history. Since storage is cheap, I'm also going to keep all my
history.
#+begin_src emacs-lisp
(require 'savehist)
(cuss savehist-additional-variables
'(kill-ring
search-ring
regexp-search-ring))
;; Don't truncate history
(cuss history-length t)
;; Delete history duplicates
(cuss history-delete-duplicates t)
(savehist-mode +1)
#+end_src
*** File places
The =saveplace= package saves where I've been in the files I've
visited, so I can return back to them.
#+begin_src emacs-lisp
(require 'saveplace)
;; Forget the place in unreadable files
(cuss save-place-forget-unreadable-files t)
(save-place-mode +1)
#+end_src
*** Recent files
#+begin_src emacs-lisp
(require 'recentf)
;; Limit the number of items in the recentf menu
(cuss recentf-max-menu-items 100)
;; But not the number of items in the actual list
(cuss recentf-max-saved-items nil)
(recentf-mode +1)
#+end_src
**** Save the recentf list periodically
#+begin_src emacs-lisp
(defun acdw/maybe-save-recentf ()
"Save `recentf-file every five minutes, but only when out of focus."
(defvar recentf--last-save (time-convert nil 'integer)
"When we last ran `recentf-save-list'.")
(when (> (time-convert (time-since recentf--last-save) 'integer)
(* 60 5))
(setq recentf--last-save (time-convert nil 'integer))
(acdw/when-unfocused #'recentf-save-list)))
(add-function :after after-focus-change-function #'acdw/maybe-save-recentf)
#+end_src
** Files
*** Encoding
* System-specific
I use both Linux (at home) and Windows (at work). To make Emacs
@ -286,7 +580,7 @@ settings and written some ancillary scripts.
**** em
:PROPERTIES:
:header-args: :tangle-mode (identity #o755) :tangle bin/em
:header-args: :tangle-mode (identity #o755) :tangle bin/em :mkdirp yes
:END:
Here's a wrapper script that'll start =emacs --daemon= if there isn't
@ -302,7 +596,7 @@ your =$PATH= somewhere.
**** emacsclient.desktop
:PROPERTIES:
:header-args: :tangle bin/emacsclient.desktop
:header-args: :tangle bin/emacsclient.desktop :mkdirp yes
:END:
I haven't really tested this yet, but it should allow me to open other
@ -338,7 +632,7 @@ section come from [[https://github.com/termitereform/JunkPile/blob/master/emacs-
*** Scripts
:PROPERTIES:
:header-args: :noweb tangle
:header-args: :noweb tangle :mkdirp yes
:END:
**** Common variables

View File

@ -7,21 +7,21 @@
;; I use =straight.el= instead.
;; [[file:config.org::*Disable loading of =package.el=][Disable loading of =package.el=:1]]
;; [[file:~/.emacs.d/config.org::*Disable loading of =package.el=][Disable loading of =package.el=:1]]
(setq package-enable-at-startup nil)
;; Disable loading of =package.el=:1 ends here
;; Don't resize the frame when loading fonts
;; [[file:config.org::*Don't resize the frame when loading fonts][Don't resize the frame when loading fonts:1]]
;; [[file:~/.emacs.d/config.org::*Don't resize the frame when loading fonts][Don't resize the frame when loading fonts:1]]
(setq frame-inhibit-implied-resize t)
;; Don't resize the frame when loading fonts:1 ends here
;; Resize frame by pixels
;; [[file:config.org::*Resize frame by pixels][Resize frame by pixels:1]]
;; [[file:~/.emacs.d/config.org::*Resize frame by pixels][Resize frame by pixels:1]]
(setq frame-resize-pixelwise t)
;; Resize frame by pixels:1 ends here
@ -35,7 +35,7 @@
;; what I have for now.
;; [[file:config.org::*Shoe-horned from elsewhere in =config.org=][Shoe-horned from elsewhere in =config.org=:1]]
;; [[file:~/.emacs.d/config.org::*Shoe-horned from elsewhere in =config.org=][Shoe-horned from elsewhere in =config.org=:1]]
(add-to-list 'default-frame-alist
'(tool-bar-lines . 0))

View File

@ -5,7 +5,7 @@
;; Prefer newer files to older files
;; [[file:config.org::*Prefer newer files to older files][Prefer newer files to older files:1]]
;; [[file:~/.emacs.d/config.org::*Prefer newer files to older files][Prefer newer files to older files:1]]
(setq load-prefer-newer t)
;; Prefer newer files to older files:1 ends here
@ -16,7 +16,7 @@
;; directly from Org if it's newer.
;; [[file:config.org::*Load the config][Load the config:1]]
;; [[file:~/.emacs.d/config.org::*Load the config][Load the config:1]]
(let* (;; Speed up init
(gc-cons-threshold most-positive-fixnum)
(file-name-handler-alist nil)