about summary refs log tree commit diff stats
path: root/emacs.d
diff options
context:
space:
mode:
Diffstat (limited to 'emacs.d')
-rw-r--r--emacs.d/bookmarks33
-rw-r--r--emacs.d/brianna-theme.el7
-rw-r--r--emacs.d/early-init.el282
3 files changed, 281 insertions, 41 deletions
diff --git a/emacs.d/bookmarks b/emacs.d/bookmarks new file mode 100644 index 0000000..05ee99e --- /dev/null +++ b/emacs.d/bookmarks
@@ -0,0 +1,33 @@
1;;;; Emacs Bookmark Format Version 1;;;; -*- coding: utf-8; mode: lisp-data -*-
2;;; This format is meant to be slightly human-readable;
3;;; nevertheless, you probably don't want to edit it.
4;;; -*- End Of Bookmark File Format Version Stamp -*-
5(("~elly/pub"
6 (filename . "/sshx:town:/home/elly/pub/")
7 (front-context-string . " /sshx:town:/ho")
8 (rear-context-string)
9 (position . 1)
10 (last-modified 26236 19926 867955 868000))
11("Planet ACDW"
12 (front-context-string . "mars, but with e")
13 (rear-context-string)
14 (position . 1)
15 (last-modified 26235 32833 754178 60000)
16 (location . "https://planet.acdw.net/")
17 (handler . eww-bookmark-jump))
18("CHICKEN API"
19 (front-context-string . "chickadee\n\nIdent")
20 (rear-context-string)
21 (position . 1)
22 (last-modified 26219 43014 969496 46000)
23 (location . "http://api.call-cc.org/5/doc/")
24 (handler . eww-bookmark-jump))
25(#1="set-face-attribute"
26 (position . 1)
27 (last-modified 26219 41950 249141 418000)
28 (help-fn . describe-function--helper)
29 (help-args set-face-attribute "brianna-theme.el")
30 (position . 1)
31 (handler . help-bookmark-jump)
32 (defaults #1# "*Help*"))
33)
diff --git a/emacs.d/brianna-theme.el b/emacs.d/brianna-theme.el index 0b16a41..43223f6 100644 --- a/emacs.d/brianna-theme.el +++ b/emacs.d/brianna-theme.el
@@ -93,12 +93,12 @@
93 '(header-line ((t (:background "lavender" :inherit variable-pitch)))) 93 '(header-line ((t (:background "lavender" :inherit variable-pitch))))
94 '(minibuffer-prompt ((t (:inherit brianna-prompt)))) 94 '(minibuffer-prompt ((t (:inherit brianna-prompt))))
95 '(mode-line ((t (:background "lavender" :inherit variable-pitch)))) 95 '(mode-line ((t (:background "lavender" :inherit variable-pitch))))
96 '(mode-line-active ((t ( :box t :background "light goldenrod" 96 '(mode-line-active ((t ( :box "black" :background "light goldenrod"
97 :inherit mode-line)))) 97 :inherit mode-line))))
98 '(mode-line-inactive ((t ( :box "pale goldenrod" :background "pale goldenrod" 98 '(mode-line-inactive ((t ( :box "pale goldenrod" :background "pale goldenrod"
99 :inherit mode-line)))) 99 :inherit mode-line))))
100 '(tab-bar ((t (:inherit mode-line-inactive)))) 100 '(tab-bar ((t (:inherit mode-line-inactive))))
101 '(tab-bar-tab ((t ( :background "light goldenrod" :box t 101 '(tab-bar-tab ((t ( :weight bold :underline t
102 :inherit variable-pitch)))) 102 :inherit variable-pitch))))
103 '(tab-bar-tab-inactive ((t ( :background "pale goldenrod" 103 '(tab-bar-tab-inactive ((t ( :background "pale goldenrod"
104 :inherit variable-pitch)))) 104 :inherit variable-pitch))))
@@ -165,9 +165,12 @@
165 ;; Sh 165 ;; Sh
166 '(sh-heredoc ((t ( :background "azure" :extend t 166 '(sh-heredoc ((t ( :background "azure" :extend t
167 :inherit font-lock-string-face)))) 167 :inherit font-lock-string-face))))
168 '(sh-quoted-exec ((t ())))
168 ;; Widgets 169 ;; Widgets
169 '(widget-field ((t (:inherit brianna-input-field)))) 170 '(widget-field ((t (:inherit brianna-input-field))))
170 '(widget-single-line-field ((t (:inherit brianna-input-field)))) 171 '(widget-single-line-field ((t (:inherit brianna-input-field))))
172 ;; Whitespace-mode
173 '(whitespace-tab ((t (:foreground "#888"))))
171 ) 174 )
172 175
173(provide-theme 'brianna) 176(provide-theme 'brianna)
diff --git a/emacs.d/early-init.el b/emacs.d/early-init.el index 7374bd1..b2de2f2 100644 --- a/emacs.d/early-init.el +++ b/emacs.d/early-init.el
@@ -10,18 +10,21 @@
10 (vertical-scroll-bars) 10 (vertical-scroll-bars)
11 (horizontal-scroll-bars))) 11 (horizontal-scroll-bars)))
12 12
13(when (getenv "IN_EXWM")
14 (add-to-list 'default-frame-alist '(fullscreen . fullboth)))
15
13(defvar *fonts* 16(defvar *fonts*
14 '((default 17 (let ((fixed "Recursive Mono Casual Static")
15 :family ;;("Recursive Mono Casual Static" "DejaVu Sans Mono") 18 (variable "Recursive Sans Casual Static"))
16 ("Public Sans" "DejaVu Sans") 19 `((default
17 :height 100) 20 :family ,variable
18 (variable-pitch 21 :height 100)
19 :family ("Public Sans" "DejaVu Sans") 22 (variable-pitch
20 :height 1.0) 23 :family ,variable)
21 (fixed-pitch 24 (fixed-pitch
22 :family ("Recursive Mono Casual Static" "DejaVu Sans Mono")) 25 :family ,fixed)
23 (fixed-pitch-serif 26 (fixed-pitch-serif
24 :family ("Recursive Mono Linear Static" "DejaVu Sans Mono")))) 27 :family "Recursive Mono Linear Static"))))
25 28
26(require 'package) 29(require 'package)
27(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) 30(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
@@ -47,24 +50,6 @@
47 (delete-trailing-whitespace (line-end-position) 50 (delete-trailing-whitespace (line-end-position)
48 (point-max)))) 51 (point-max))))
49 52
50(defun run-after-frame-init (func)
51 "Run FUNC after the first frame is initialized.
52If already so, run FUNC immediately."
53 (cond
54 ((daemonp)
55 (add-hook 'server-after-make-frame-hook func)
56 (advice-add func :after (lambda ()
57 (remove-hook 'server-after-make-frame-hook
58 func)
59 (advice-remove func
60 'after-frame-init-removing-advice))
61
62
63 '((name . after-frame-init-removing-advice))))
64 ((not after-init-time)
65 (add-hook 'after-init-hook func))
66 (:else (funcall func))))
67
68(defun first-found-font (&rest cands) 53(defun first-found-font (&rest cands)
69 "Return the first font of CANDS that is installed, or nil." 54 "Return the first font of CANDS that is installed, or nil."
70 (cl-loop with ffl = (font-family-list) 55 (cl-loop with ffl = (font-family-list)
@@ -77,8 +62,7 @@ If already so, run FUNC immediately."
77 ;; Default faces 62 ;; Default faces
78 (cl-loop for (face . spec) in *fonts* 63 (cl-loop for (face . spec) in *fonts*
79 do (set-face-attribute face nil 64 do (set-face-attribute face nil
80 :family (apply #'first-found-font 65 :family (plist-get spec :family)
81 (plist-get spec :family))
82 :height (or (plist-get spec :height) 66 :height (or (plist-get spec :height)
83 'unspecified))) 67 'unspecified)))
84 ;; Specialized fonts 68 ;; Specialized fonts
@@ -171,20 +155,40 @@ With ARG, edit in the other window." file-name)
171 (funcall (if arg #'find-file-other-window #'find-file) 155 (funcall (if arg #'find-file-other-window #'find-file)
172 ,file-name)))) 156 ,file-name))))
173 157
174(defun indent-buffer+ () 158(defun fixup-whitespace ()
175 "Indent the current buffer and (un)`tabify'. 159 "Indent the current buffer and (un)`tabify'.
176Whether it tabifies or untabifies depends on `space-indent-modes'." 160Whether it tabifies or untabifies depends on `space-indent-modes'."
177 (interactive) 161 (interactive)
178 (save-mark-and-excursion 162 (save-mark-and-excursion
179 (indent-region (point-min) (point-max)) 163 (indent-region (point-min) (point-max))
180 (if (apply #'derived-mode-p space-indent-modes) 164 (if indent-tabs-mode
181 (untabify (point-min) (point-max)) 165 (tabify (point-min) (point-max))
182 (tabify (point-min) (point-max))))) 166 (untabify (point-min) (point-max)))
167 (replace-regexp-in-region " $" "" (point-min) (point-max))))
183 168
184(defun package-ensure (pkg) 169(defun package-ensure (pkgspec &optional require)
185 "Install PKG if it's not already installed." 170 "Install PKG if it's not already installed.
186 (unless (package-installed-p pkg) 171REQUIRE means require it after ensuring it's installed."
187 (package-vc-install pkg))) 172 (let ((pkg (if (listp pkgspec) (car pkgspec) pkgspec)))
173 (unless (package-installed-p pkg)
174 (if (symbolp pkgspec)
175 (or (ignore-errors
176 (package-install pkg)
177 t)
178 (ignore-errors
179 (message "Package `%s' not found, refreshing packages" pkg)
180 (package-refresh-contents)
181 (package-install pkg)
182 t)
183 (ignore-errors
184 (message "Package `%s' still not found, trying `%s'"
185 pkg 'pkg-vc-install)
186 (package-vc-install pkgspec)
187 t)
188 (if no-error nil
189 (error "Can't find package: %s" pkg))))
190 (package-vc-install pkgspec))
191 (when require (require pkg))))
188 192
189(defun minibuffer-delete-directory () 193(defun minibuffer-delete-directory ()
190 "Delete the last directory in a file-completing minibuffer." 194 "Delete the last directory in a file-completing minibuffer."
@@ -214,3 +218,203 @@ If ARG is 16, kill emacs without asking about processes."
214 218
215(defun regexp-concat (&rest regexps) 219(defun regexp-concat (&rest regexps)
216 (string-join regexps "\\|")) 220 (string-join regexps "\\|"))
221
222;; There is a bug in M-x finger
223(defun acdw/finger (user host)
224 "Finger USER on HOST.
225This command uses `finger-X.500-host-regexps'
226and `network-connection-service-alist', which see."
227 ;; One of those great interactive statements that's actually
228 ;; longer than the function call! The idea is that if the user
229 ;; uses a string like "pbreton@cs.umb.edu", we won't ask for the
230 ;; host name. If we don't see an "@", we'll prompt for the host.
231 (interactive
232 (let* ((answer (let ((default (ffap-url-at-point)))
233 (read-string (format-prompt "Finger User" default) nil nil default)))
234 (index (string-match (regexp-quote "@") answer)))
235 (if index
236 (list (substring answer 0 index)
237 (substring answer (1+ index)))
238 (list answer
239 (let ((default (ffap-machine-at-point)))
240 (read-string (format-prompt "At Host" default) nil nil default))))))
241 (let* ((user-and-host (concat user "@" host))
242 (process-name (concat "Finger [" user-and-host "]"))
243 (regexps finger-X.500-host-regexps)
244 ) ;; found
245 (and regexps
246 (while (not (string-match (car regexps) host))
247 (setq regexps (cdr regexps))))
248 (when regexps
249 (setq user-and-host user))
250 (run-network-program
251 process-name
252 host
253 (cdr (assoc 'finger network-connection-service-alist))
254 user-and-host)))
255
256(advice-add 'finger :override #'acdw-finger)
257
258(defun hide-minor-mode (mode &optional hook)
259 "Hide MODE from the mode-line.
260HOOK is used to trigger the action, and defaults to MODE-hook."
261 (setf (alist-get mode minor-mode-alist) (list ""))
262 (add-hook (intern (or hook (format "%s-hook" mode)))
263 (lambda () (hide-minor-mode mode))))
264
265(defun switch-to-other-buffer ()
266 "Switch to the `other-buffer'."
267 (interactive)
268 (switch-to-buffer nil))
269
270(defun popup-eshell (arg)
271 "Popup an eshell buffer in the current window."
272 (interactive "P")
273 (let ((dd default-directory))
274 (eshell arg)
275 (unless (equal dd default-directory)
276 (setq default-directory dd)
277 ;; Is this a good idea, really?
278 (eshell-bol)
279 (unless (eolp)
280 (insert "# "))
281 (eshell-send-input))))
282
283(defun vc-jump (arg)
284 "Jump to the current project's VC buffer.
285With ARG, prompt for the directory."
286 (interactive "P")
287 (if arg
288 (let ((current-prefix-arg nil))
289 (call-interactively #'vc-dir))
290 (project-vc-dir)))
291
292(defun custom-show-all-widgets ()
293 "toggle all \"More/Hide\" widgets in the current buffer."
294 ;; From unpackaged
295 (interactive)
296 (widget-map-buttons (lambda (widget _)
297 (pcase (widget-get widget :off)
298 ("More" (widget-apply-action widget)))
299 nil)))
300
301(defun quit-minibuffer ()
302 (interactive)
303 (switch-to-minibuffer)
304 (minibuffer-keyboard-quit))
305
306(defun keyboard-quit* (arg)
307 (interactive "P")
308 (if arg
309 (quit-minibuffer)
310 (keyboard-quit)))
311
312(defun sort-sexps (beg end)
313 "Sort sexps in region.
314Comments stay with the code below."
315 ;; From unpackaged
316 (interactive "r")
317 (cl-flet ((skip-whitespace () (while (looking-at (rx (1+ (or space "\n"))))
318 (goto-char (match-end 0))))
319 (skip-both () (while (cond ((or (nth 4 (syntax-ppss))
320 (ignore-errors
321 (save-excursion
322 (forward-char 1)
323 (nth 4 (syntax-ppss)))))
324 (forward-line 1))
325 ((looking-at (rx (1+ (or space "\n"))))
326 (goto-char (match-end 0)))))))
327 (save-excursion
328 (save-restriction
329 (narrow-to-region beg end)
330 (goto-char beg)
331 (skip-both)
332 (cl-destructuring-bind (sexps markers)
333 (cl-loop do (skip-whitespace)
334 for start = (point-marker)
335 for sexp = (ignore-errors
336 (read (current-buffer)))
337 for end = (point-marker)
338 while sexp
339 ;; Collect the real string, then one used for sorting.
340 collect (cons (buffer-substring (marker-position start)
341 (marker-position end))
342 (save-excursion
343 (goto-char (marker-position start))
344 (skip-both)
345 (buffer-substring (point)
346 (marker-position end))))
347 into sexps
348 collect (cons start end)
349 into markers
350 finally return (list sexps markers))
351 (setq sexps (sort sexps (lambda (a b)
352 (string< (cdr a) (cdr b)))))
353 (cl-loop for (real . sort) in sexps
354 for (start . end) in markers
355 do (progn
356 (goto-char (marker-position start))
357 (insert-before-markers real)
358 (delete-region (point) (marker-position end)))))))))
359
360(defun ^turn-off (mode)
361 "Higher-order function: returns a lambda to turn off MODE."
362 (lambda ()
363 (funcall mode -1)))
364
365(defun ^local-hook (hook fn)
366 "Hook FN to HOOK locally in a lambda.
367Good for adding to an add-hook."
368 (lambda () (add-hook hook fn t)))
369
370(defun ^local-unhook (hook fn)
371 "Remove FN from HOOK locally."
372 (lambda () (remove-hook hook fn t)))
373
374;; This needs to be a macro to take advantage of setf magic
375(defmacro setf/alist (alist key val &optional testfn)
376 `(setf (alist-get ,key ,alist nil nil (or ,testfn #'equal))
377 ,val))
378
379(defun unfill-region (beg end)
380 (interactive "*r")
381 (let ((fill-column most-positive-fixnum))
382 (fill-region beg end)))
383
384(defun unfill-paragraph ()
385 (interactive)
386 (let ((fill-column most-positive-fixnum))
387 (fill-paragraph beg end)))
388
389(defun unfill-buffer ()
390 (interactive)
391 (unfill-region (point-min) (point-max)))
392
393(defun unfill-buffer/force ()
394 (interactive)
395 (let ((buffer-read-only nil))
396 (unfill-buffer)
397 (visual-line-mode t)))
398
399(defmacro after (event &rest body)
400 "Do BODY after EVENT, which can be:
401- A feature
402- A hook -- if it requires arguments they'll be in the list `args'
403- The symbol 'init, which runs on after-init-hook"
404 (declare (indent 1))
405 (let ((lambda-form `(lambda (&rest args) ,@body)))
406 (pcase event
407 (`(timer ,ev) `(run-with-timer ,ev nil ,lambda-form))
408 (`(idle ,ev) `(run-with-idle-timer ,ev nil ,lambda-form))
409 (`(hook ,ev) `(add-hook ',ev ,lambda-form))
410 (`init `(after (hook after-init-hook) ,@body))
411 ((pred numberp) `(after (timer ,event) ,@body))
412 ((pred (lambda (ev)
413 (and (symbolp ev)
414 (or (string-suffix-p "-hook" (symbol-name ev))
415 (string-suffix-p "-function" (symbol-name ev))
416 (string-suffix-p "-functions" (symbol-name ev))))))
417 `(after (hook ,event) ,@body))
418 ((pred symbolp) `(with-eval-after-load ',event ,@body))
419
420 (_ (error "Can't determine event type" event)))))