:END:
This org file is my literate configuration for GNU Emacs, and is
-tangled to [[./init.el][init.el]]. Packages are installed and managed using [[https://github.com/emacscollective/borg][Borg]].
-
-** Installation
+tangled to [[./init.el][init.el]]. Packages are installed and managed using
+[[https://github.com/emacscollective/borg][Borg]]. Over the years, I've taken inspiration from configurations of
+many different people. Some of the configurations that I can remember
+off the top of my head are:
+
+- [[https://github.com/dieggsy/dotfiles][dieggsy/dotfiles]]: literate Emacs and dotfiles configuration, uses
+ straight.el for managing packages
+- [[https://github.com/dakra/dmacs][dakra/dmacs]]: literate Emacs configuration, using Borg for managing
+ packages
+- [[http://pages.sachachua.com/.emacs.d/Sacha.html][Sacha Chua's literate Emacs configuration]]
+- [[https://github.com/dakrone/eos][dakrone/eos]]
+- Ryan Rix's [[http://doc.rix.si/cce/cce.html][Complete Computing Environment]] ([[http://doc.rix.si/projects/fsem.html][about cce]])
+- [[https://github.com/jwiegley/dot-emacs][jwiegley/dot-emacs]]: nix-based configuration
+- [[https://github.com/wasamasa/dotemacs][wasamasa/dotemacs]]
+- [[https://github.com/hlissner/doom-emacs][Doom Emacs]]
I'd like to have a fully reproducible Emacs setup (part of the reason
why I store my configuration in this repository) but unfortunately out
window manager (via EXWM) and coming from bspwm, I'm too used to
having fast startup times.
+** Installation
+
+To use this config for your Emacs, first you need to clone this repo,
+then bootstrap Borg, tell Borg to retrieve package submodules, and
+byte-compiled the packages. Something along these lines should work:
+
+#+begin_src sh :tangle no
+git clone https://github.com/aminb/dotfiles ~/.emacs.d
+cd ~/.emacs.d
+make bootstrap-borg
+make bootstrap
+make build
+#+end_src
+
* Contents :toc_1:noexport:
- [[#about][About]]
(add-hook
'after-init-hook
(lambda ()
- (let ((elapsed (float-time (time-subtract (current-time)
- ab--before-user-init-time))))
- (message "Loading %s...done (%.3fs) [after-init]"
- user-init-file elapsed))
(setq gc-cons-threshold ab--gc-cons-threshold
gc-cons-percentage ab--gc-cons-percentage
file-name-handler-alist ab--file-name-handler-alist)))
:config (or (server-running-p) (server-mode)))
#+end_src
+** Unicode support
+
+Font stack with better unicode support, around =Ubuntu Mono= and
+=Hack=.
+
+#+begin_src emacs-lisp
+(dolist (ft (fontset-list))
+ (set-fontset-font
+ ft
+ 'unicode
+ (font-spec :name "Ubuntu Mono"))
+ (set-fontset-font
+ ft
+ 'unicode
+ (font-spec :name "DejaVu Sans Mono")
+ nil
+ 'append)
+ ;; (set-fontset-font
+ ;; ft
+ ;; 'unicode
+ ;; (font-spec
+ ;; :name "Symbola monospacified for DejaVu Sans Mono")
+ ;; nil
+ ;; 'append)
+ ;; (set-fontset-font
+ ;; ft
+ ;; #x2115 ; ℕ
+ ;; (font-spec :name "DejaVu Sans Mono")
+ ;; nil
+ ;; 'append)
+ (set-fontset-font
+ ft
+ (cons ?Α ?ω)
+ (font-spec :name "DejaVu Sans Mono" :size 14)
+ nil
+ 'prepend))
+#+end_src
+
* Core
:PROPERTIES:
:CUSTOM_ID: core
** Defaults
+*** Time and battery in mode-line
+
+Enable displaying time and battery in the mode-line, since I'm not
+using the Xfce panel anymore. Also, I don't need to see the load
+average on a regular basis, so disable that.
+
+#+begin_src emacs-lisp
+(use-package time
+ :ensure nil
+ :init
+ (setq display-time-default-load-average nil)
+ :config
+ (display-time-mode))
+
+(use-package battery
+ :ensure nil
+ :config
+ (display-battery-mode))
+#+end_src
+
*** Smaller fringe
-Set fringe to a small value so we don't have big borders in EXWM, but
-can still see the =diff-hl= colors in the fringe.
+Might want to set the fringe to a smaller value, especially if using
+EXWM. I'm fine with the default for now.
#+begin_src emacs-lisp
-(fringe-mode '(3 . 1))
+;; (fringe-mode '(3 . 1))
+(fringe-mode nil)
#+end_src
*** Disable disabled commands
*** [[https://github.com/ch11ng/exwm][EXWM]] (window manager)
-#+begin_src emacs-lisp
-;; (use-package exwm
-;; :config
-;; (require 'exwm-config)
-;; (exwm-config-default)
-;; (require 'exwm-systemtray)
-;; (exwm-systemtray-enable)
-;; (require 'exwm-randr)
-;; (exwm-randr-enable))
+#+begin_src emacs-lisp :tangle no
+(use-package exwm
+ :demand t
+ :config
+ (require 'exwm-config)
+
+ ;; Set the initial workspace number.
+ (setq exwm-workspace-number 4)
+
+ ;; Make class name the buffer name, truncating beyond 50 characters
+ (defun exwm-rename-buffer ()
+ (interactive)
+ (exwm-workspace-rename-buffer
+ (concat exwm-class-name ":"
+ (if (<= (length exwm-title) 50) exwm-title
+ (concat (substring exwm-title 0 49) "...")))))
+ (add-hook 'exwm-update-class-hook 'exwm-rename-buffer)
+ (add-hook 'exwm-update-title-hook 'exwm-rename-buffer)
+
+ ;; 's-R': Reset
+ (exwm-input-set-key (kbd "s-R") #'exwm-reset)
+ ;; 's-\': Switch workspace
+ (exwm-input-set-key (kbd "s-\\") #'exwm-workspace-switch)
+ ;; 's-N': Switch to certain workspace
+ (dotimes (i 10)
+ (exwm-input-set-key (kbd (format "s-%d" i))
+ (lambda ()
+ (interactive)
+ (exwm-workspace-switch-create i))))
+ ;; 's-SPC': Launch application
+ ;; (exwm-input-set-key
+ ;; (kbd "s-SPC")
+ ;; (lambda (command)
+ ;; (interactive (list (read-shell-command "➜ ")))
+ ;; (start-process-shell-command command nil command)))
+
+ (exwm-input-set-key (kbd "M-s-SPC") #'counsel-linux-app)
+
+ ;; Shorten 'C-c C-q' to 'C-q'
+ (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
+
+ ;; Line-editing shortcuts
+ (setq exwm-input-simulation-keys
+ '(;; movement
+ ([?\C-b] . [left])
+ ([?\M-b] . [C-left])
+ ([?\C-f] . [right])
+ ([?\M-f] . [C-right])
+ ([?\C-p] . [up])
+ ([?\C-n] . [down])
+ ([?\C-a] . [home])
+ ([?\C-e] . [end])
+ ([?\M-v] . [prior])
+ ([?\C-v] . [next])
+ ([?\C-d] . [delete])
+ ([?\C-k] . [S-end delete])
+ ;; cut/copy/paste
+ ;; ([?\C-w] . [?\C-x])
+ ([?\M-w] . [?\C-c])
+ ([?\C-y] . [?\C-v])
+ ;; search
+ ([?\C-s] . [?\C-f])))
+
+ ;; Enable EXWM
+ (exwm-enable)
+
+ (add-hook 'exwm-init-hook #'exwm-config--fix/ido-buffer-window-other-frame)
+
+ (require 'exwm-systemtray)
+ (exwm-systemtray-enable)
+
+ (require 'exwm-randr)
+ (exwm-randr-enable)
+
+ ;; (exwm-input-set-key
+ ;; (kbd "s-<return>")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process "urxvt" nil "urxvt")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "s-SPC") ;; rofi doesn't properly launch programs when started from emacs
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "rofi-run" nil "rofi -show run -display-run '> ' -display-window ' 🗔 '")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "s-/")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "rofi-win" nil "rofi -show window -display-run '> ' -display-window ' 🗔 '")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "M-SPC")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process "rofi-pass" nil "rofi-pass")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "<XF86AudioMute>")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "pamixer" nil "pamixer --toggle-mute")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "<XF86AudioLowerVolume>")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "pamixer" nil "pamixer --allow-boost --decrease 5")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "<XF86AudioRaiseVolume>")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "pamixer" nil "pamixer --allow-boost --increase 5")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "<XF86AudioPlay>")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "mpc" nil "mpc toggle")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "<XF86AudioPrev>")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "mpc" nil "mpc prev")))
+
+ ;; (exwm-input-set-key
+ ;; (kbd "<XF86AudioNext>")
+ ;; (lambda ()
+ ;; (interactive)
+ ;; (start-process-shell-command "mpc" nil "mpv next")))
+
+ (defun ab--exwm-pasystray ()
+ "A command used to start pasystray."
+ (interactive)
+ (if (executable-find "pasystray")
+ (progn
+ (message "EXWM: starting pasystray ...")
+ (start-process-shell-command "pasystray" nil "pasystray --notify=all"))
+ (message "EXWM: pasystray is not installed, abort!")))
+
+ (add-hook 'exwm-init-hook #'ab--exwm-pasystray)
+
+ (exwm-input-set-key
+ (kbd "s-t")
+ (lambda ()
+ (interactive)
+ (exwm-floating-toggle-floating)))
+
+ (exwm-input-set-key
+ (kbd "s-f")
+ (lambda ()
+ (interactive)
+ (exwm-layout-toggle-fullscreen)))
+
+ (exwm-input-set-key
+ (kbd "s-w")
+ (lambda ()
+ (interactive)
+ (kill-buffer (current-buffer))))
+
+ (exwm-input-set-key
+ (kbd "s-q")
+ (lambda ()
+ (interactive)
+ (exwm-manage--kill-client))))
+#+end_src
+
+**** sxhkdrc
+:PROPERTIES:
+:header-args+: :tangle ~/.config/sxhkd/sxhkdrc :mkdirp yes
+:END:
+
+#+begin_src conf :tangle no
+# terminal emulator
+super + Return
+ urxvt
+
+# program launcher
+super + space
+ rofi -show run -display-run '> ' -display-window ' 🗔 '
+
+# window finder
+super + slash
+ rofi -show window -display-run '> ' -display-window ' 🗔 '
+
+# password manager
+alt + space
+ rofi-pass
+
+# make sxhkd reload its configuration files:
+super + Escape
+ pkill -USR1 -x sxhkd
+
+# volume {up,down}
+XF86Audio{Raise,Lower}Volume
+ pamixer --allow-boost --{in,de}crease 5
+
+# mute
+XF86AudioMute
+ pamixer --toggle-mute
+
+# playback control
+XF86Audio{Play,Prev,Next}
+ mpc {toggle,prev,next}
+
+# Toggle keyboard layout
+# super + F7
+# toggle-layout
+
+# Toggle Xfce presentation mode
+# XF86LaunchB
+# toggle-presentation-mode
+
+# monitor brightness
+XF86MonBrightness{Up,Down}
+ light -{A,U} 5
+
+super + apostrophe
+ rofi-light
#+end_src
*** [[https://orgmode.org/][Org mode]]
**** Ivy
#+begin_src emacs-lisp
-;; (use-package ivy
-;; :bind
-;; (:map ivy-minibuffer-map
-;; ([escape] . keyboard-escape-quit)
-;; ("C-j" . ivy-next-line)
-;; ("C-k" . ivy-previous-line)
-;; ([S-up] . ivy-previous-history-element)
-;; ([S-down] . ivy-next-history-element)
-;; ("DEL" . ivy-backward-delete-char))
-;; :config
-;; (ivy-mode 1))
+(use-package ivy
+ :bind
+ (:map ivy-minibuffer-map
+ ([escape] . keyboard-escape-quit)
+ ;; ("C-j" . ivy-next-line)
+ ;; ("C-k" . ivy-previous-line)
+ ([S-up] . ivy-previous-history-element)
+ ([S-down] . ivy-next-history-element)
+ ("DEL" . ivy-backward-delete-char))
+ :config
+ (setq ivy-wrap t)
+ (ivy-mode 1))
#+end_src
**** Swiper
#+begin_src emacs-lisp
-;; (use-package swiper
-;; :bind (([remap isearch-forward] . swiper)
-;; ([remap isearch-backward] . swiper)))
+(use-package swiper
+ :bind (([remap isearch-forward] . swiper)
+ ([remap isearch-backward] . swiper)))
#+end_src
**** Counsel
#+begin_src emacs-lisp
-;; (use-package counsel
-;; :bind (([remap execute-extended-command] . counsel-M-x)
-;; ([remap find-file] . counsel-find-file)
-;; ("s-r" . counsel-recentf)
-;; :map minibuffer-local-map
-;; ("C-r" . counsel-minibuffer-history))
-;; :config
-;; (counsel-mode 1)
-;; (defalias 'locate #'counsel-locate))
+(use-package counsel
+ :defer 1
+ :bind (([remap execute-extended-command] . counsel-M-x)
+ ([remap find-file] . counsel-find-file)
+ ("s-r" . counsel-recentf)
+ :map minibuffer-local-map
+ ("C-r" . counsel-minibuffer-history))
+ :config
+ (counsel-mode 1)
+ (defalias 'locate #'counsel-locate))
#+end_src
* Borg's =layer/essentials=
(setq undo-tree-mode-lighter ""))
#+end_src
+* Syntax and spell checking
+#+begin_src emacs-lisp
+(use-package flycheck
+ :hook (prog-mode . flycheck-mode)
+ :config
+ ;; Use the load-path from running Emacs when checking elisp files
+ (setq flycheck-emacs-lisp-load-path 'inherit)
+
+ ;; Only flycheck when I actually save the buffer
+ (setq flycheck-check-syntax-automatically '(mode-enabled save)))
+#+end_src
+* Programming modes
+
+** [[https://github.com/leanprover/lean-mode][Lean]]
+
+#+begin_src emacs-lisp
+(use-package lean-mode
+ :bind (:map lean-mode-map
+ ("S-SPC" . company-complete)))
+#+end_src
+
+** Haskell
+
+*** [[https://github.com/haskell/haskell-mode][haskell-mode]]
+
+#+begin_src emacs-lisp
+(use-package haskell-mode
+ :config
+ (setq haskell-indentation-layout-offset 4
+ haskell-indentation-left-offset 4
+ haskell-indentation-ifte-offset 4))
+#+end_src
+
+*** [[https://github.com/mpickering/hlint-refactor-mode][hlint-refactor]]
+
+Emacs bindings for [[https://github.com/ndmitchell/hlint][hlint]]'s refactor option. This requires the refact
+executable from [[https://github.com/mpickering/apply-refact][apply-refact]].
+
+#+begin_src emacs-lisp
+(use-package hlint-refactor
+ :bind (:map hlint-refactor-mode-map
+ ("C-c l b" . hlint-refactor-refactor-buffer)
+ ("C-c l r" . hlint-refactor-refactor-at-point))
+ :hook (haskell-mode . hlint-refactor-mode))
+#+end_src
+
* Post initialization
:PROPERTIES:
:CUSTOM_ID: post-initialization