[emacs] remove duplicate post-init message and shorten counsel delay
[~bandali/configs] / init.org
CommitLineData
180cab37
AB
1#+title: =aminb='s Literate Emacs Configuration
2#+author: Amin Bandali
3#+babel: :cache yes
4#+property: header-args :tangle yes
5
6* About
7:PROPERTIES:
8:CUSTOM_ID: about
9:END:
10
11This org file is my literate configuration for GNU Emacs, and is
3b98e899
AB
12tangled to [[./init.el][init.el]]. Packages are installed and managed using
13[[https://github.com/emacscollective/borg][Borg]]. Over the years, I've taken inspiration from configurations of
14many different people. Some of the configurations that I can remember
15off the top of my head are:
16
17- [[https://github.com/dieggsy/dotfiles][dieggsy/dotfiles]]: literate Emacs and dotfiles configuration, uses
18 straight.el for managing packages
19- [[https://github.com/dakra/dmacs][dakra/dmacs]]: literate Emacs configuration, using Borg for managing
20 packages
21- [[http://pages.sachachua.com/.emacs.d/Sacha.html][Sacha Chua's literate Emacs configuration]]
22- [[https://github.com/dakrone/eos][dakrone/eos]]
23- Ryan Rix's [[http://doc.rix.si/cce/cce.html][Complete Computing Environment]] ([[http://doc.rix.si/projects/fsem.html][about cce]])
24- [[https://github.com/jwiegley/dot-emacs][jwiegley/dot-emacs]]: nix-based configuration
25- [[https://github.com/wasamasa/dotemacs][wasamasa/dotemacs]]
26- [[https://github.com/hlissner/doom-emacs][Doom Emacs]]
180cab37
AB
27
28I'd like to have a fully reproducible Emacs setup (part of the reason
29why I store my configuration in this repository) but unfortunately out
30of the box, that's not achievable with =package.el=, not currently
31anyway. So, I've opted to use Borg. For what it's worth, I briefly
32experimented with [[https://github.com/raxod502/straight.el][straight.el]], but found that it added about 2 seconds
33to my init time; which is unacceptable for me: I use Emacs as my
34window manager (via EXWM) and coming from bspwm, I'm too used to
35having fast startup times.
36
3b98e899
AB
37** Installation
38
4ae2cd62
AB
39To use this config for your Emacs, first you need to clone this repo,
40then bootstrap Borg, tell Borg to retrieve package submodules, and
41byte-compiled the packages. Something along these lines should work:
42
4b4e432d 43#+begin_src sh :tangle no
4ae2cd62
AB
44git clone https://github.com/aminb/dotfiles ~/.emacs.d
45cd ~/.emacs.d
46make bootstrap-borg
47make tangle-init
48make bootstrap
49make build
50#+end_src
51
180cab37
AB
52* Contents :toc_1:noexport:
53
54- [[#about][About]]
55- [[#header][Header]]
56- [[#initial-setup][Initial setup]]
57- [[#core][Core]]
967b0a82 58- [[#post-initialization][Post initialization]]
180cab37
AB
59- [[#footer][Footer]]
60
61* Header
62:PROPERTIES:
63:CUSTOM_ID: header
64:END:
65
66** First line
67
68#+begin_src emacs-lisp :comments none
69;;; init.el --- Amin Bandali's Emacs config -*- lexical-binding: t ; eval: (view-mode 1)-*-
70#+end_src
71
72Enable =view-mode=, which both makes the file read-only (as a reminder
73that =init.el= is an auto-generated file, not supposed to be edited),
74and provides some convenient key bindings for browsing through the
75file.
76
77** License
78
79#+begin_src emacs-lisp :comments none
80;; Copyright (C) 2018 Amin Bandali <amin@aminb.org>
81
82;; This program is free software: you can redistribute it and/or modify
83;; it under the terms of the GNU General Public License as published by
84;; the Free Software Foundation, either version 3 of the License, or
85;; (at your option) any later version.
86
87;; This program is distributed in the hope that it will be useful,
88;; but WITHOUT ANY WARRANTY; without even the implied warranty of
89;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90;; GNU General Public License for more details.
91
92;; You should have received a copy of the GNU General Public License
93;; along with this program. If not, see <https://www.gnu.org/licenses/>.
94#+end_src
95
96** Commentary
97
98#+begin_src emacs-lisp :comments none
99;;; Commentary:
100
101;; Emacs configuration of Amin Bandali, computer scientist and functional
102;; programmer.
103
104;; THIS FILE IS AUTO-GENERATED FROM `init.org'.
105#+end_src
106
107** Naming conventions
108
109The conventions below were inspired by [[https://github.com/hlissner/doom-emacs][Doom]]'s conventions, found
110[[https://github.com/hlissner/doom-emacs/blob/5dacbb7cb1c6ac246a9ccd15e6c4290def67757c/core/core.el#L3-L17][here]]. Naturally, I use my initials, =ab=, instead of =doom=.
111
112#+begin_src emacs-lisp :comments none
113;; Naming conventions:
114;;
115;; ab-... public variables or non-interactive functions
116;; ab--... private anything (non-interactive), not safe for direct use
117;; ab/... an interactive function; safe for M-x or keybinding
118;; ab:... an evil operator, motion, or command
119;; ab|... a hook function
120;; ab*... an advising function
121;; ab@... a hydra command
122;; ...! a macro
123#+end_src
124
125* Initial setup
126:PROPERTIES:
127:CUSTOM_ID: initial-setup
128:END:
129
130#+begin_src emacs-lisp :comments none
131;;; Code:
132#+end_src
133
134** Emacs initialization
135
136I'd like to do a couple of measurements of Emacs' startup time. First,
137let's see how long Emacs takes to start up, before even loading
138=init.el=, i.e. =user-init-file=:
139
140#+begin_src emacs-lisp
141(defvar ab--before-user-init-time (current-time)
142 "Value of `current-time' when Emacs begins loading `user-init-file'.")
143(message "Loading Emacs...done (%.3fs)"
144 (float-time (time-subtract ab--before-user-init-time
145 before-init-time)))
146#+end_src
147
148Also, temporarily increase ~gc-cons-threshhold~ and
149~gc-cons-percentage~ during startup to reduce garbage collection
150frequency. Clearing the ~file-name-handler-alist~ seems to help reduce
151startup time as well.
152
153#+begin_src emacs-lisp
154(defvar ab--gc-cons-threshold gc-cons-threshold)
155(defvar ab--gc-cons-percentage gc-cons-percentage)
156(defvar ab--file-name-handler-alist file-name-handler-alist)
157(setq gc-cons-threshold (* 400 1024 1024) ; 400 MiB
158 gc-cons-percentage 0.6
159 file-name-handler-alist nil
160 ;; sidesteps a bug when profiling with esup
161 esup-child-profile-require-level 0)
162#+end_src
163
164Of course, we'd like to set them back to their defaults once we're
165done initializing.
166
167#+begin_src emacs-lisp
168(add-hook
169 'after-init-hook
170 (lambda ()
180cab37
AB
171 (setq gc-cons-threshold ab--gc-cons-threshold
172 gc-cons-percentage ab--gc-cons-percentage
173 file-name-handler-alist ab--file-name-handler-alist)))
174#+end_src
175
176Increase the number of lines kept in message logs (the =*Messages*=
177buffer).
178
179#+begin_src emacs-lisp
180(setq message-log-max 20000)
181#+end_src
182
183Optionally, we could suppress some byte compiler warnings like below,
184but for now I've decided to keep them enabled. See documentation for
185~byte-compile-warnings~ for more details.
186
187#+begin_src emacs-lisp
188;; (setq byte-compile-warnings
189;; '(not free-vars unresolved noruntime lexical make-local))
190#+end_src
191
192** Package management
193
194*** No =package.el=
195
196I can do all my package management things with Borg, and don't need
197Emacs' built-in =package.el=. Emacs 27 lets us disable =package.el= in
198the =early-init-file= (see [[https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=24acb31c04b4048b85311d794e600ecd7ce60d3b][here]]).
199
200#+begin_src emacs-lisp :tangle early-init.el
201(setq package-enable-at-startup nil)
202#+end_src
203
204But since Emacs 27 isn't out yet (Emacs 26 is just around the corner
205right now), and even when released it'll be long before most distros
206ship in their repos, I'll still put the old workaround with the
207commented call to ~package-initialize~ here anyway.
208
209#+begin_src emacs-lisp
210(setq package-enable-at-startup nil)
211;; (package-initialize)
212#+end_src
213
214*** Borg
215
216#+begin_quote
217Assimilate Emacs packages as Git submodules
218#+end_quote
219
220[[https://github.com/emacscollective/borg][Borg]] is at the heart of package management of my Emacs setup. In
221short, it creates a git submodule in =lib/= for each package, which
222can then be managed with the help of Magit or other tools.
223
224#+begin_src emacs-lisp
225(setq user-init-file (or load-file-name buffer-file-name)
226 user-emacs-directory (file-name-directory user-init-file))
227(add-to-list 'load-path
228 (expand-file-name "lib/borg" user-emacs-directory))
229(require 'borg)
230(borg-initialize)
231#+end_src
232
233*** =use-package=
234
235#+begin_quote
236A use-package declaration for simplifying your .emacs
237#+end_quote
238
239[[https://github.com/jwiegley/use-package][use-package]] is an awesome utility for managing and configuring
240packages (in our case especially the latter) in a neatly organized way
241and without compromising on performance.
242
243#+begin_src emacs-lisp
244(require 'use-package)
245(if nil ; set to t when need to debug init
246 (setq use-package-verbose t
247 use-package-expand-minimally nil
248 use-package-compute-statistics t
249 debug-on-error t)
250 (setq use-package-verbose nil
251 use-package-expand-minimally t))
252#+end_src
253
254*** Epkg
255
256#+begin_quote
257Browse the Emacsmirror package database
258#+end_quote
259
260Epkg provides access to a local copy of the [[https://emacsmirror.net][Emacsmirror]] package
261database, low-level functions for querying the database, and a
262=package.el=-like user interface for browsing the available packages.
263
264#+begin_src emacs-lisp
265(use-package epkg
266 :defer t)
267#+end_src
268
269** No littering in =~/.emacs.d=
270
271#+begin_quote
272Help keeping ~/.emacs.d clean
273#+end_quote
274
275By default, even for Emacs' built-in packages, the configuration files
276and persistent data are all over the place. Use =no-littering= to help
277contain the mess.
278
279#+begin_src emacs-lisp
280(use-package no-littering
281 :demand t
282 :config
283 (savehist-mode 1)
284 (add-to-list 'savehist-additional-variables 'kill-ring)
285 (save-place-mode 1)
286 (setq auto-save-file-name-transforms
287 `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))))
288#+end_src
289
180cab37
AB
290** Custom file (=custom.el=)
291
292I'm not planning on using the custom file much, but even so, I
293definitely don't want it mixing with =init.el=. So, here; let's give
294it it's own file. While at it, treat themes as safe.
295
296#+begin_src emacs-lisp
297(use-package custom
298 :no-require t
299 :config
300 (setq custom-file (no-littering-expand-etc-file-name "custom.el"))
301 (when (file-exists-p custom-file)
302 (load custom-file))
303 (setf custom-safe-themes t))
304#+end_src
305
306** Better =$PATH= handling
307
308Let's use [[https://github.com/purcell/exec-path-from-shell][exec-path-from-shell]] to make Emacs use the =$PATH= as set up
309in my shell.
310
311#+begin_src emacs-lisp
7538956f
AB
312(use-package exec-path-from-shell
313 :defer 1
314 :init
315 (setq exec-path-from-shell-check-startup-files nil)
316 :config
317 (exec-path-from-shell-initialize)
318 ;; while we're at it, let's fix access to our running ssh-agent
319 (exec-path-from-shell-copy-env "SSH_AGENT_PID")
320 (exec-path-from-shell-copy-env "SSH_AUTH_SOCK"))
180cab37
AB
321#+end_src
322
323** Server
324
325Start server if not already running. Alternatively, can be done by
326issuing =emacs --daemon= in the terminal, which can be automated with
327a systemd service or using =brew services start emacs= on macOS. I use
328Emacs as my window manager (via EXWM), so I always start Emacs on
329login; so starting the server from inside Emacs is good enough for me.
330
331See [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html#Emacs-Server][Using Emacs as a Server]].
332
333#+begin_src emacs-lisp
334(use-package server
335 :config (or (server-running-p) (server-mode)))
336#+end_src
337
e9bcfa30
AB
338** Unicode support
339
340Font stack with better unicode support, around =Ubuntu Mono= and
341=Hack=.
342
343#+begin_src emacs-lisp
344(dolist (ft (fontset-list))
345 (set-fontset-font
346 ft
347 'unicode
348 (font-spec :name "Ubuntu Mono"))
349 (set-fontset-font
350 ft
351 'unicode
352 (font-spec
353 :name "Hack")
354 nil
355 'append)
356 (set-fontset-font
357 ft
358 'unicode
359 (font-spec
360 :name "Symbola monospacified for DejaVu Sans Mono")
361 nil
362 'append))
363#+end_src
364
180cab37
AB
365* Core
366:PROPERTIES:
367:CUSTOM_ID: core
368:END:
369
370** Defaults
371
e602de37
AB
372*** Time and battery in mode-line
373
374Enable displaying time and battery in the mode-line, since I'm not
375using the Xfce panel anymore. Also, I don't need to see the load
376average on a regular basis, so disable that.
377
378#+begin_src emacs-lisp
379(use-package time
380 :ensure nil
381 :init
382 (setq display-time-default-load-average nil)
383 :config
384 (display-time-mode))
385
386(use-package battery
387 :ensure nil
388 :config
389 (display-battery-mode))
390#+end_src
391
180cab37
AB
392*** Smaller fringe
393
2f8102f0
AB
394Might want to set the fringe to a smaller value, especially if using
395EXWM. I'm fine with the default for now.
180cab37
AB
396
397#+begin_src emacs-lisp
2f8102f0 398;; (fringe-mode '(3 . 1))
4b4e432d 399(fringe-mode nil)
180cab37
AB
400#+end_src
401
402*** Disable disabled commands
403
404Emacs disables some commands by default that could persumably be
405confusing for novice users. Let's disable that.
406
407#+begin_src emacs-lisp
408(setq disabled-command-function nil)
409#+end_src
410
411*** Kill-ring
412
413Save what I copy into clipboard from other applications into Emacs'
414kill-ring, which would allow me to still be able to easily access it
415in case I kill (cut or copy) something else inside Emacs before
416yanking (pasting) what I'd originally intended to.
417
418#+begin_src emacs-lisp
419(setq save-interprogram-paste-before-kill t)
420#+end_src
421
422*** Minibuffer
423
424#+begin_src emacs-lisp
425(setq enable-recursive-minibuffers t
426 resize-mini-windows t)
427#+end_src
428
429*** Lazy-person-friendly yes/no prompts
430
431Lazy people would prefer to type fewer keystrokes, especially for yes
432or no questions. I'm lazy.
433
434#+begin_src emacs-lisp
435(defalias 'yes-or-no-p #'y-or-n-p)
436#+end_src
437
438*** Startup screen and =*scratch*=
439
440Firstly, let Emacs know that I'd like to have =*scratch*= as my
441startup buffer.
442
443#+begin_src emacs-lisp
444(setq initial-buffer-choice t)
445#+end_src
446
447Now let's customize the =*scratch*= buffer a bit. First off, I don't
448need the default hint.
449
450#+begin_src emacs-lisp
451(setq initial-scratch-message nil)
452#+end_src
453
454Also, let's use Text mode as the major mode, in case I want to
455customize it (=*scratch*='s default major mode, Fundamental mode,
456can't really be customized).
457
458#+begin_src emacs-lisp
459(setq initial-major-mode 'text-mode)
460#+end_src
461
462Inhibit the buffer list when more than 2 files are loaded.
463
464#+begin_src emacs-lisp
465(setq inhibit-startup-buffer-menu t)
466#+end_src
467
468I don't really need to see the startup screen or echo area message
469either.
470
471#+begin_src emacs-lisp
472(advice-add #'display-startup-echo-area-message :override #'ignore)
473(setq inhibit-startup-screen t
474 inhibit-startup-echo-area-message user-login-name)
475#+end_src
476
477*** More useful frame titles
478
479Show either the file name or the buffer name (in case the buffer isn't
480visiting a file). Borrowed from Emacs Prelude.
481
482#+begin_src emacs-lisp
483(setq frame-title-format
484 '("" invocation-name " - "
485 (:eval (if (buffer-file-name)
486 (abbreviate-file-name (buffer-file-name))
487 "%b"))))
488#+end_src
489
490*** Backups
491
492Emacs' default backup settings aren't that great. Let's use more
493sensible options. See documentation for the ~make-backup-file~
494variable.
495
496#+begin_src emacs-lisp
497(setq backup-by-copying t
498 version-control t)
499#+end_src
500
501** Packages
502
503The packages in this section are absolutely essential to my everyday
504workflow, and they play key roles in how I do my computing. They
505immensely enhance the Emacs experience for me; both using Emacs, and
506customizing it.
507
508*** [[https://github.com/emacscollective/auto-compile][auto-compile]]
509
510#+begin_src emacs-lisp
511(use-package auto-compile
512 :demand t
513 :config
514 (auto-compile-on-load-mode)
515 (auto-compile-on-save-mode)
516 (setq auto-compile-display-buffer nil
517 auto-compile-mode-line-counter t
518 auto-compile-source-recreate-deletes-dest t
519 auto-compile-toggle-deletes-nonlib-dest t
520 auto-compile-update-autoloads t)
521 (add-hook 'auto-compile-inhibit-compile-hook
522 'auto-compile-inhibit-compile-detached-git-head))
523#+end_src
524
525*** TODO [[https://github.com/Kungsgeten/ryo-modal][ryo-modal]]
526
527#+begin_quote
528Roll your own modal mode
529#+end_quote
530
531*** [[https://github.com/ch11ng/exwm][EXWM]] (window manager)
532
45568be1 533#+begin_src emacs-lisp :tangle no
2f8102f0
AB
534(use-package exwm
535 :demand t
536 :config
537 (require 'exwm-config)
26c45764
AB
538
539 ;; Set the initial workspace number.
540 (setq exwm-workspace-number 4)
541
542 ;; Make class name the buffer name, truncating beyond 50 characters
543 (defun exwm-rename-buffer ()
544 (interactive)
545 (exwm-workspace-rename-buffer
546 (concat exwm-class-name ":"
547 (if (<= (length exwm-title) 50) exwm-title
548 (concat (substring exwm-title 0 49) "...")))))
549 (add-hook 'exwm-update-class-hook 'exwm-rename-buffer)
550 (add-hook 'exwm-update-title-hook 'exwm-rename-buffer)
551
552 ;; 's-R': Reset
553 (exwm-input-set-key (kbd "s-R") #'exwm-reset)
554 ;; 's-\': Switch workspace
555 (exwm-input-set-key (kbd "s-\\") #'exwm-workspace-switch)
556 ;; 's-N': Switch to certain workspace
557 (dotimes (i 10)
558 (exwm-input-set-key (kbd (format "s-%d" i))
559 (lambda ()
560 (interactive)
e9bcfa30 561 (exwm-workspace-switch-create i))))
26c45764 562 ;; 's-SPC': Launch application
b46e33ae
AB
563 ;; (exwm-input-set-key
564 ;; (kbd "s-SPC")
565 ;; (lambda (command)
566 ;; (interactive (list (read-shell-command "➜ ")))
567 ;; (start-process-shell-command command nil command)))
26c45764
AB
568
569 (exwm-input-set-key (kbd "M-s-SPC") #'counsel-linux-app)
570
571 ;; Shorten 'C-c C-q' to 'C-q'
572 (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
573
574 ;; Line-editing shortcuts
575 (setq exwm-input-simulation-keys
576 '(;; movement
577 ([?\C-b] . [left])
578 ([?\M-b] . [C-left])
579 ([?\C-f] . [right])
580 ([?\M-f] . [C-right])
581 ([?\C-p] . [up])
582 ([?\C-n] . [down])
583 ([?\C-a] . [home])
584 ([?\C-e] . [end])
585 ([?\M-v] . [prior])
586 ([?\C-v] . [next])
587 ([?\C-d] . [delete])
588 ([?\C-k] . [S-end delete])
b46e33ae
AB
589 ;; cut/copy/paste
590 ;; ([?\C-w] . [?\C-x])
26c45764
AB
591 ([?\M-w] . [?\C-c])
592 ([?\C-y] . [?\C-v])
593 ;; search
594 ([?\C-s] . [?\C-f])))
595
596 ;; Enable EXWM
597 (exwm-enable)
598
599 (add-hook 'exwm-init-hook #'exwm-config--fix/ido-buffer-window-other-frame)
600
2f8102f0
AB
601 (require 'exwm-systemtray)
602 (exwm-systemtray-enable)
26c45764 603
2f8102f0 604 (require 'exwm-randr)
26c45764
AB
605 (exwm-randr-enable)
606
b46e33ae
AB
607 ;; (exwm-input-set-key
608 ;; (kbd "s-<return>")
609 ;; (lambda ()
610 ;; (interactive)
611 ;; (start-process "urxvt" nil "urxvt")))
612
613 ;; (exwm-input-set-key
614 ;; (kbd "s-SPC") ;; rofi doesn't properly launch programs when started from emacs
615 ;; (lambda ()
616 ;; (interactive)
617 ;; (start-process-shell-command "rofi-run" nil "rofi -show run -display-run '> ' -display-window ' 🗔 '")))
618
619 ;; (exwm-input-set-key
620 ;; (kbd "s-/")
621 ;; (lambda ()
622 ;; (interactive)
623 ;; (start-process-shell-command "rofi-win" nil "rofi -show window -display-run '> ' -display-window ' 🗔 '")))
624
625 ;; (exwm-input-set-key
626 ;; (kbd "M-SPC")
627 ;; (lambda ()
628 ;; (interactive)
629 ;; (start-process "rofi-pass" nil "rofi-pass")))
630
631 ;; (exwm-input-set-key
632 ;; (kbd "<XF86AudioMute>")
633 ;; (lambda ()
634 ;; (interactive)
635 ;; (start-process-shell-command "pamixer" nil "pamixer --toggle-mute")))
636
637 ;; (exwm-input-set-key
638 ;; (kbd "<XF86AudioLowerVolume>")
639 ;; (lambda ()
640 ;; (interactive)
641 ;; (start-process-shell-command "pamixer" nil "pamixer --allow-boost --decrease 5")))
642
643 ;; (exwm-input-set-key
644 ;; (kbd "<XF86AudioRaiseVolume>")
645 ;; (lambda ()
646 ;; (interactive)
647 ;; (start-process-shell-command "pamixer" nil "pamixer --allow-boost --increase 5")))
648
649 ;; (exwm-input-set-key
650 ;; (kbd "<XF86AudioPlay>")
651 ;; (lambda ()
652 ;; (interactive)
653 ;; (start-process-shell-command "mpc" nil "mpc toggle")))
654
655 ;; (exwm-input-set-key
656 ;; (kbd "<XF86AudioPrev>")
657 ;; (lambda ()
658 ;; (interactive)
659 ;; (start-process-shell-command "mpc" nil "mpc prev")))
660
661 ;; (exwm-input-set-key
662 ;; (kbd "<XF86AudioNext>")
663 ;; (lambda ()
664 ;; (interactive)
665 ;; (start-process-shell-command "mpc" nil "mpv next")))
666
667 (defun ab--exwm-pasystray ()
668 "A command used to start pasystray."
669 (interactive)
670 (if (executable-find "pasystray")
671 (progn
672 (message "EXWM: starting pasystray ...")
673 (start-process-shell-command "pasystray" nil "pasystray --notify=all"))
674 (message "EXWM: pasystray is not installed, abort!")))
675
676 (add-hook 'exwm-init-hook #'ab--exwm-pasystray)
677
678 (exwm-input-set-key
679 (kbd "s-t")
680 (lambda ()
681 (interactive)
682 (exwm-floating-toggle-floating)))
683
684 (exwm-input-set-key
685 (kbd "s-f")
686 (lambda ()
687 (interactive)
688 (exwm-layout-toggle-fullscreen)))
689
690 (exwm-input-set-key
691 (kbd "s-w")
692 (lambda ()
693 (interactive)
694 (kill-buffer (current-buffer))))
695
26c45764 696 (exwm-input-set-key
b46e33ae 697 (kbd "s-q")
26c45764
AB
698 (lambda ()
699 (interactive)
b46e33ae
AB
700 (exwm-manage--kill-client))))
701#+end_src
702
703**** sxhkdrc
704:PROPERTIES:
705:header-args+: :tangle ~/.config/sxhkd/sxhkdrc :mkdirp yes
706:END:
707
45568be1 708#+begin_src conf :tangle no
b46e33ae
AB
709# terminal emulator
710super + Return
711 urxvt
712
713# program launcher
714super + space
715 rofi -show run -display-run '> ' -display-window ' 🗔 '
716
717# window finder
718super + slash
719 rofi -show window -display-run '> ' -display-window ' 🗔 '
720
721# password manager
722alt + space
723 rofi-pass
724
725# make sxhkd reload its configuration files:
726super + Escape
727 pkill -USR1 -x sxhkd
728
729# volume {up,down}
730XF86Audio{Raise,Lower}Volume
731 pamixer --allow-boost --{in,de}crease 5
732
733# mute
734XF86AudioMute
735 pamixer --toggle-mute
736
737# playback control
738XF86Audio{Play,Prev,Next}
739 mpc {toggle,prev,next}
740
741# Toggle keyboard layout
742# super + F7
743# toggle-layout
744
745# Toggle Xfce presentation mode
746# XF86LaunchB
747# toggle-presentation-mode
748
749# monitor brightness
750XF86MonBrightness{Up,Down}
751 light -{A,U} 5
752
753super + apostrophe
754 rofi-light
180cab37
AB
755#+end_src
756
757*** [[https://orgmode.org/][Org mode]]
758
759#+begin_quote
760Org mode is for keeping notes, maintaining TODO lists, planning
761projects, and authoring documents with a fast and effective plain-text
762system.
763#+end_quote
764
765In short, my favourite way of life.
766
767#+begin_src emacs-lisp
768(setq org-src-tab-acts-natively t
769 org-src-preserve-indentation nil
770 org-edit-src-content-indentation 0)
771#+end_src
772
773*** [[https://magit.vc/][Magit]]
774
775#+begin_quote
776It's Magit! A Git porcelain inside Emacs.
777#+end_quote
778
779Not just how I do git, but /the/ way to do git.
780
781#+begin_src emacs-lisp
782(use-package magit
783 :defer t
784 :bind (("s-g" . magit-status)
785 ("C-x g" . magit-status)
786 ("C-x M-g" . magit-dispatch-popup))
787 :config
788 (magit-add-section-hook 'magit-status-sections-hook
789 'magit-insert-modules
790 'magit-insert-stashes
791 'append))
792#+end_src
793
794*** [[https://github.com/abo-abo/swiper][Ivy]] (and friends)
795
796#+begin_quote
797Ivy - a generic completion frontend for Emacs, Swiper - isearch with
798an overview, and more. Oh, man!
799#+end_quote
800
801There's no way I could top that, so I won't attempt to.
802
803**** Ivy
804
805#+begin_src emacs-lisp
f7752223
AB
806(use-package ivy
807 :bind
808 (:map ivy-minibuffer-map
809 ([escape] . keyboard-escape-quit)
5ad7f83a
AB
810 ;; ("C-j" . ivy-next-line)
811 ;; ("C-k" . ivy-previous-line)
f7752223
AB
812 ([S-up] . ivy-previous-history-element)
813 ([S-down] . ivy-next-history-element)
814 ("DEL" . ivy-backward-delete-char))
815 :config
f6d8e3e4 816 (setq ivy-wrap t)
f7752223 817 (ivy-mode 1))
180cab37
AB
818#+end_src
819
820**** Swiper
821
822#+begin_src emacs-lisp
f7752223
AB
823(use-package swiper
824 :bind (([remap isearch-forward] . swiper)
825 ([remap isearch-backward] . swiper)))
180cab37
AB
826#+end_src
827
828**** Counsel
829
830#+begin_src emacs-lisp
f7752223 831(use-package counsel
3d35bdff 832 :defer 1
f7752223
AB
833 :bind (([remap execute-extended-command] . counsel-M-x)
834 ([remap find-file] . counsel-find-file)
835 ("s-r" . counsel-recentf)
836 :map minibuffer-local-map
837 ("C-r" . counsel-minibuffer-history))
838 :config
839 (counsel-mode 1)
840 (defalias 'locate #'counsel-locate))
180cab37
AB
841#+end_src
842
843* Borg's =layer/essentials=
844
845TODO: break this giant source block down into individual org sections.
846
847#+begin_src emacs-lisp
848(use-package dash
849 :config (dash-enable-font-lock))
850
851(use-package diff-hl
852 :config
853 (setq diff-hl-draw-borders nil)
854 (global-diff-hl-mode)
855 (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh t))
856
857(use-package dired
858 :defer t
859 :config (setq dired-listing-switches "-alh"))
860
861(use-package eldoc
862 :when (version< "25" emacs-version)
863 :config (global-eldoc-mode))
864
865(use-package help
866 :defer t
867 :config (temp-buffer-resize-mode))
868
869(progn ; `isearch'
870 (setq isearch-allow-scroll t))
871
872(use-package lisp-mode
873 :config
874 (add-hook 'emacs-lisp-mode-hook 'outline-minor-mode)
875 (add-hook 'emacs-lisp-mode-hook 'reveal-mode)
876 (defun indent-spaces-mode ()
877 (setq indent-tabs-mode nil))
878 (add-hook 'lisp-interaction-mode-hook #'indent-spaces-mode))
879
880(use-package man
881 :defer t
882 :config (setq Man-width 80))
883
884(use-package paren
885 :config (show-paren-mode))
886
887(use-package prog-mode
888 :config (global-prettify-symbols-mode)
889 (defun indicate-buffer-boundaries-left ()
890 (setq indicate-buffer-boundaries 'left))
891 (add-hook 'prog-mode-hook #'indicate-buffer-boundaries-left))
892
893(use-package recentf
894 :demand t
895 :config (add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?:"))
896
897(use-package savehist
898 :config (savehist-mode))
899
900(use-package saveplace
901 :when (version< "25" emacs-version)
902 :config (save-place-mode))
903
904(use-package simple
905 :config (column-number-mode))
906
907(progn ; `text-mode'
908 (add-hook 'text-mode-hook #'indicate-buffer-boundaries-left))
909
910(use-package tramp
911 :defer t
912 :config
913 (add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:"))
914 (add-to-list 'tramp-default-proxies-alist '("localhost" nil nil))
915 (add-to-list 'tramp-default-proxies-alist
916 (list (regexp-quote (system-name)) nil nil)))
917
918(use-package undo-tree
919 :config
920 (global-undo-tree-mode)
921 (setq undo-tree-mode-lighter ""))
922#+end_src
923
3f0f8d01
AB
924* Programming modes
925
926** Lean mode
927
928#+begin_src emacs-lisp
e9bcfa30
AB
929(use-package lean-mode
930 :bind (:map lean-mode-map
931 ("S-SPC" . company-complete)))
3f0f8d01
AB
932#+end_src
933
180cab37
AB
934* Post initialization
935:PROPERTIES:
967b0a82 936:CUSTOM_ID: post-initialization
180cab37
AB
937:END:
938
939Display how long it took to load the init file.
940
941#+begin_src emacs-lisp
942(message "Loading %s...done (%.3fs)" user-init-file
943 (float-time (time-subtract (current-time)
944 ab--before-user-init-time)))
945#+end_src
946
947* Footer
948:PROPERTIES:
949:CUSTOM_ID: footer
950:END:
951
952#+begin_src emacs-lisp :comments none
953;;; init.el ends here
954#+end_src