From c490bbf4b3d57df111476f76f3a5c8ad2d04fa33 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 14 Dec 2019 13:23:20 +0000 Subject: chore(emacs.d): Import several months of privately tracked changes These changes were made in a fork of my configuration that is not publicly available and detailed history will not be included in this public commit. --- tools/emacs/init.el | 32 +++--- tools/emacs/init/custom.el | 14 +-- tools/emacs/init/desktop.el | 211 ++++++++++++++++++++++++++++++++++++++ tools/emacs/init/functions.el | 130 +++++++---------------- tools/emacs/init/look-and-feel.el | 15 +-- tools/emacs/init/nixos.el | 103 ------------------- tools/emacs/init/settings.el | 1 - 7 files changed, 274 insertions(+), 232 deletions(-) create mode 100644 tools/emacs/init/desktop.el delete mode 100644 tools/emacs/init/nixos.el (limited to 'tools') diff --git a/tools/emacs/init.el b/tools/emacs/init.el index 66d38cd9fcde..ea149550110a 100644 --- a/tools/emacs/init.el +++ b/tools/emacs/init.el @@ -43,7 +43,6 @@ (use-package dash) (use-package dash-functional) -(use-package edit-server :init (edit-server-start)) (use-package gruber-darker-theme) (use-package ht) (use-package hydra) @@ -89,19 +88,19 @@ (use-package dockerfile-mode) -(use-package eglot - :init (defvar rust-eglot-initialized nil) - :hook ((rust-mode . (lambda () - (unless rust-eglot-initialized - (call-interactively #'eglot) - (setq rust-eglot-initialized t)))))) - (use-package erlang :hook ((erlang-mode . (lambda () ;; Don't indent after '>' while I'm writing (local-set-key ">" 'self-insert-command))))) -(use-package go-mode) +(use-package go-mode + :bind (:map go-mode-map ("C-c C-r" . recompile) + :map go-mode-map ("" . company-indent-or-complete-common)) + :hook ((go-mode . (lambda () + (setq tab-width 2) + (setq-local compile-command + (concat "go build " buffer-file-name)))))) + (use-package haskell-mode) (use-package jq-mode @@ -110,6 +109,8 @@ (use-package kotlin-mode :bind (:map kotlin-mode-map ("" . indent-relative))) +(use-package lsp-mode) + (use-package markdown-mode :init (add-to-list 'auto-mode-alist '("\\.txt\\'" . markdown-mode)) @@ -128,10 +129,6 @@ (use-package web-mode) (use-package yaml-mode) -;; -;; EXWM / NixOS related packages -;; - ;; Configure a few basics before moving on to package-specific initialisation. (setq custom-file (concat user-emacs-directory "init/custom.el")) (load custom-file) @@ -142,7 +139,7 @@ (random t) (defun load-other-settings () - (mapc 'require '(nixos + (mapc 'require '(desktop mail-setup look-and-feel functions @@ -152,12 +149,7 @@ term-setup eshell-setup)) (telephone-line-setup) - (ace-window-display-mode) - - (use-package sly - :init (setq inferior-lisp-program (concat (nix-store-path "sbcl") "/bin/sbcl")) - ;;(add-to-list 'company-backends 'sly-company) - )) + (ace-window-display-mode)) ;; Some packages can only be initialised after the rest of the diff --git a/tools/emacs/init/custom.el b/tools/emacs/init/custom.el index 4c92f0d32fc4..a157c7a5fa37 100644 --- a/tools/emacs/init/custom.el +++ b/tools/emacs/init/custom.el @@ -5,28 +5,28 @@ ;; If there is more than one, they won't work right. '(ac-auto-show-menu 0.8) '(ac-delay 0.2) - '(aprila-nixops-path "/home/vincent/projects/langler/nixops") - '(aprila-release-author "Vincent Ambo ") - '(aprila-releases-path "/home/vincent/projects/langler/docs/releases") '(avy-background t) '(cargo-process--custom-path-to-bin "env CARGO_INCREMENTAL=1 cargo") '(cargo-process--enable-rust-backtrace 1) + '(company-auto-complete (quote (quote company-explicit-action-p))) + '(company-idle-delay 0.5) '(custom-enabled-themes (quote (gruber-darker))) '(custom-safe-themes (quote ("d61fc0e6409f0c2a22e97162d7d151dee9e192a90fa623f8d6a071dbf49229c6" "3c83b3676d796422704082049fc38b6966bcad960f896669dfc21a7a37a748fa" "89336ca71dae5068c165d932418a368a394848c3b8881b2f96807405d8c6b5b6" default))) + '(display-time-default-load-average nil) + '(display-time-interval 30) '(elnode-send-file-program "/run/current-system/sw/bin/cat") '(frame-brackground-mode (quote dark)) '(global-auto-complete-mode t) - '(intero-debug nil) - '(intero-global-mode t nil (intero)) - '(intero-package-version "0.1.31") '(kubernetes-commands-display-buffer-function (quote display-buffer)) + '(lsp-gopls-server-path "/home/tazjin/go/bin/gopls") '(magit-log-show-gpg-status t) '(ns-alternate-modifier (quote none)) '(ns-command-modifier (quote control)) '(ns-right-command-modifier (quote meta)) - '(require-final-newline (quote visit-save))) + '(require-final-newline (quote visit-save)) + '(tls-program (quote ("gnutls-cli --x509cafile %t -p %p %h")))) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. diff --git a/tools/emacs/init/desktop.el b/tools/emacs/init/desktop.el new file mode 100644 index 000000000000..dcc35383370a --- /dev/null +++ b/tools/emacs/init/desktop.el @@ -0,0 +1,211 @@ +;; -*- lexical-binding: t; -*- +;; +;; Configure desktop environment settings, including both +;; window-management (EXWM) as well as additional system-wide +;; commands. + +(require 's) +(require 'f) +(require 'dash) +(require 'exwm) +(require 'exwm-config) +(require 'exwm-randr) +(require 'exwm-systemtray) + +(defun pactl (cmd) + (shell-command (concat "pactl " cmd)) + (message "Volume command: %s" cmd)) + +(defun volume-mute () (interactive) (pactl "set-sink-mute @DEFAULT_SINK@ toggle")) +(defun volume-up () (interactive) (pactl "set-sink-volume @DEFAULT_SINK@ +5%")) +(defun volume-down () (interactive) (pactl "set-sink-volume @DEFAULT_SINK@ -5%")) + +(defun brightness-up () + (interactive) + (shell-command "xbacklight -inc 5") + (message "Brightness increased")) + +(defun brightness-down () + (interactive) + (shell-command "xbacklight -dec 5") + (message "Brightness decreased")) + +(defun lock-screen () + (interactive) + ;; A sudoers configuration is in place that lets me execute this + ;; particular command without having to enter a password. + ;; + ;; The reason for things being set up this way is that I want + ;; xsecurelock.service to be started as a system-wide service that + ;; is tied to suspend.target. + (shell-command "/usr/bin/sudo /usr/bin/systemctl start xsecurelock.service")) + +(defun generate-randr-config (primary secondary) + (-flatten `(,(-map (lambda (n) (list n primary)) (number-sequence 1 7)) + (0 secondary) + ,(-map (lambda (n) (list n secondary)) (number-sequence 8 9))))) + +(defun randr-layout-dp1-extend () + "Layout for connecting my X1 Carbon to my screen at home" + + (interactive) + (setq exwm-randr-workspace-monitor-plist (generate-randr-config "DP1-1" "eDP1")) + (exwm-randr-refresh) + (shell-command "xrandr --output DP1-1 --right-of eDP1 --auto --primary")) + +(defun randr-layout-hdmi1-extend () + "Office layout for The Big Screen(tm)" + + (interactive) + (setq exwm-randr-workspace-monitor-plist (generate-randr-config "HDMI1" "eDP1")) + (exwm-randr-refresh) + (shell-command "xrandr --output HDMI1 --dpi 144 --auto --right-of eDP1 --primary")) + +(defun randr-layout-single () + "Laptop screen only!" + + (interactive) + (shell-command "xrandr --output HDMI1 --off") + (shell-command "xrandr --output DP1-1 --off") + (exwm-randr-refresh)) + +(defun set-xkb-layout (layout) + "Set the current X keyboard layout." + + (shell-command (format "setxkbmap %s" layout)) + (message "Set X11 keyboard layout to '%s'" layout)) + +(defun create-window-name () + "Construct window names to be used for EXWM buffers by + inspecting the window's X11 class and title. + + A lot of commonly used applications either create titles that + are too long by default, or in the case of web + applications (such as Cider) end up being constructed in + awkward ways. + + To avoid this issue, some rewrite rules are applied for more + human-accessible titles." + + (pcase (list (or exwm-class-name "unknown") (or exwm-title "unknown")) + ;; In Cider windows, rename the class and keep the workspace/file + ;; as the title. + (`("Google-chrome" ,(and (pred (lambda (title) (s-ends-with? " - Cider" title))) title)) + (format "Cider<%s>" (s-chop-suffix " - Cider" title))) + + ;; Attempt to detect IRCCloud windows via their title, which is a + ;; combination of the channel name and network. + ;; + ;; This is what would often be referred to as a "hack". The regexp + ;; will not work if a network connection buffer is selected in + ;; IRCCloud, but since the title contains no other indication that + ;; we're dealing with an IRCCloud window + (`("Google-chrome" + ,(and (pred (lambda (title) + (s-matches? "^[\*\+]\s#[a-zA-Z0-9/\-]+\s\|\s[a-zA-Z\.]+$" title))) + title)) + (format "IRCCloud<%s>" title)) + + ;; For other Chrome windows, make the title shorter. + (`("Google-chrome" ,title) + (format "Chrome<%s>" (s-truncate 42 (s-chop-suffix " - Google Chrome" title)))) + + ;; Gnome-terminal -> Term + (`("Gnome-terminal" ,title) + ;; fish-shell buffers contain some unnecessary whitespace and + ;; such before the current working directory. This can be + ;; stripped since most of my terminals are fish shells anyways. + (format "Term<%s>" (s-trim-left (s-chop-prefix "fish" title)))) + + ;; For any other application, a name is constructed from the + ;; window's class and name. + (`(,class ,title) (format "%s<%s>" class (s-truncate 12 title))))) + +;; EXWM launch configuration +;; +;; This used to use use-package, but when something breaks use-package +;; it doesn't exactly make debugging any easier. + +(let ((titlef (lambda () + (exwm-workspace-rename-buffer (create-window-name))))) + (add-hook 'exwm-update-class-hook titlef) + (add-hook 'exwm-update-title-hook titlef)) + +(fringe-mode 3) +(exwm-enable) + +;; 's-N': Switch to certain workspace +(setq exwm-workspace-number 10) +(dotimes (i 10) + (exwm-input-set-key (kbd (format "s-%d" i)) + `(lambda () + (interactive) + (exwm-workspace-switch-create ,i)))) + +;; Launch applications / any command with completion (dmenu style!) +(exwm-input-set-key (kbd "s-d") #'counsel-linux-app) +(exwm-input-set-key (kbd "s-x") #'ivy-run-external-command) +(exwm-input-set-key (kbd "s-p") #'ivy-password-store) + +;; Add X11 terminal selector to a key +(exwm-input-set-key (kbd "C-x t") #'counsel-switch-to-terminal) + +;; Toggle between line-mode / char-mode +(exwm-input-set-key (kbd "C-c C-t C-t") #'exwm-input-toggle-keyboard) + +;; Volume keys +(exwm-input-set-key (kbd "") #'volume-mute) +(exwm-input-set-key (kbd "") #'volume-up) +(exwm-input-set-key (kbd "") #'volume-down) + +;; Brightness keys +(exwm-input-set-key (kbd "") #'brightness-down) +(exwm-input-set-key (kbd "") #'brightness-up) +(exwm-input-set-key (kbd "") #'lock-screen) + +;; Keyboard layouts (these are bound separately in Cyrillic +;; because I don't use reverse-im) +;; (-map +;; (lambda (pair) +;; (exwm-input-set-key +;; (kbd (format "s-%s" (cadr pair))) +;; `(lambda () (interactive) (set-xkb-layout ,(car pair))))) +;; '(("de" "k d") +;; ("de" "л в") +;; ("no" "k n") +;; ("no" "л т") +;; ("ru" "k r") +;; ("ru" "л к") +;; ("us" "k u") +;; ("us" "л г"))) + +;; Line-editing shortcuts +(exwm-input-set-simulation-keys + '(([?\C-d] . delete) + ([?\C-w] . ?\C-c))) + +;; Show time & battery status in the mode line +(display-time-mode) +(display-battery-mode) + +;; enable display of X11 system tray within Emacs +(exwm-systemtray-enable) + +;; Configure xrandr (multi-monitor setup) +(setq exwm-randr-workspace-monitor-plist (generate-randr-config "HDMI1" "eDP1")) +(exwm-randr-enable) + +;; Let buffers move seamlessly between workspaces by making them +;; accessible in selectors on all frames. +(setq exwm-workspace-show-all-buffers t) +(setq exwm-layout-show-all-buffers t) + +;; Monitor layouts +;; +;; TODO(tazjin): Desired layout should be inferred based on +;; connected screens - autorandr or something? +(exwm-input-set-key (kbd "s-m d") #'randr-layout-dp1-extend) +(exwm-input-set-key (kbd "s-m h") #'randr-layout-hdmi1-extend) +(exwm-input-set-key (kbd "s-m s") #'randr-layout-single) + +(provide 'desktop) diff --git a/tools/emacs/init/functions.el b/tools/emacs/init/functions.el index 8b96a0e737df..e0bc496a538f 100644 --- a/tools/emacs/init/functions.el +++ b/tools/emacs/init/functions.el @@ -1,59 +1,4 @@ (require 's) -;; A few handy functions I use in init.el (or not, but they're nice to -;; have) - -(defun custom-download-theme (url filename) - "Downloads a theme through HTTP and places it in ~/.emacs.d/themes" - - ;; Ensure the directory exists - (unless (file-exists-p "~/.emacs.d/themes") - (make-directory "~/.emacs.d/themes")) - - ;; Adds the themes folder to the theme load path (if not already - ;; there) - (unless (member "~/.emacs.d/themes" custom-theme-load-path) - (add-to-list 'custom-theme-load-path "~/.emacs.d/themes")) - - ;; Download file if it doesn't exist. - - (let ((file - (concat "~/.emacs.d/themes/" filename))) - (unless (file-exists-p file) - (url-copy-file url file)))) - -(defun custom-download-script (url filename) - "Downloads an Elisp script, places it in ~/.emacs/other and then loads it" - - ;; Ensure the directory exists - (unless (file-exists-p "~/.emacs.d/other") - (make-directory "~/.emacs.d/other")) - - ;; Download file if it doesn't exist. - (let ((file - (concat "~/.emacs.d/other/" filename))) - (unless (file-exists-p file) - (url-copy-file url file)) - - (load file))) - -(defun keychain-password (account &optional keychain) - "Returns the password for the account, by default it's looked up in the Login.keychain but a - different keychain can be specified." - (let ((k (if keychain keychain "Login.keychain"))) - (replace-regexp-in-string - "\n" "" - (shell-command-to-string (concat "security find-generic-password -w -a " - account - " " - k))))) - -;; This clones a git repository to 'foldername in .emacs.d -;; if there isn't already a folder with that name -(defun custom-clone-git (url foldername) - "Clones a git repository to .emacs.d/foldername" - (let ((fullpath (concat "~/.emacs.d/" foldername))) - (unless (file-exists-p fullpath) - (async-shell-command (concat "git clone " url " " fullpath))))) (defun load-file-if-exists (filename) (if (file-exists-p filename) @@ -70,7 +15,6 @@ (goto-line target))) (setq-local display-line-numbers nil))) - (defun untabify-buffer () (interactive) (untabify (point-min) (point-max))) @@ -105,11 +49,6 @@ Including indent-buffer, which should not be called automatically on save." (interactive) (eww "https://blog.fefe.de/")) -;; Open this machines NixOS config -(defun nix-config () - (interactive) - (find-file "/etc/nixos/configuration.nix")) - ;; Open the NixOS man page (defun nixos-man () (interactive) @@ -158,15 +97,23 @@ Including indent-buffer, which should not be called automatically on save." append lsdir into completions finally return (sort completions 'string-lessp))) +(defvar external-command-flag-overrides + '(("google-chrome" . "--force-device-scale-factor=1.4")) + + "This setting lets me add additional flags to specific commands + that are run interactively via `ivy-run-external-command'.") + (defun run-external-command (cmd) - "Execute the specified command and notify the user when it + "Execute the specified command and notify the user when it finishes." - (message "Starting %s..." cmd) - (set-process-sentinel - (start-process-shell-command cmd nil cmd) - (lambda (process event) - (when (string= event "finished\n") - (message "%s process finished." process))))) + (let* ((extra-flags (cdr (assoc cmd external-command-flag-overrides))) + (cmd (if extra-flags (s-join " " (list cmd extra-flags)) cmd))) + (message "Starting %s..." cmd) + (set-process-sentinel + (start-process-shell-command cmd nil cmd) + (lambda (process event) + (when (string= event "finished\n") + (message "%s process finished." process)))))) (defun ivy-run-external-command () "Prompts the user with a list of all installed applications and @@ -235,32 +182,25 @@ Including indent-buffer, which should not be called automatically on save." (inferior-erlang (format "nix-shell --command erl %s" (cdr (project-current))))) -(defun intero-fix-ghci-panic () - "Disable deferring of out of scope variable errors, which - triggers a bug in the interactive Emacs REPL printing a panic - under certain conditions." - - (interactive) - (let* ((root (intero-project-root)) - (package-name (intero-package-name)) - (backend-buffer (intero-buffer 'backend)) - (name (format "*intero:%s:%s:repl*" - (file-name-nondirectory root) - package-name)) - (setting ":set -fno-defer-out-of-scope-variables\n")) - (when (get-buffer name) - (with-current-buffer (get-buffer name) - (goto-char (point-max)) - (let ((process (get-buffer-process (current-buffer)))) - (when process (process-send-string process setting))))))) - -;; Brute-force fix: Ensure the setting is injected every time the REPL -;; is selected. -;; -;; Upstream issue: https://github.com/commercialhaskell/intero/issues/569 -(advice-add 'intero-repl :after (lambda (&rest r) (intero-fix-ghci-panic)) - '((name . intero-panic-fix))) -(advice-add 'intero-repl-load :after (lambda (&rest r) (intero-fix-ghci-panic)) - '((name . intero-panic-fix))) +(defun memespace-region () + "Make a meme out of it." + + (interactive) + (let* ((start (region-beginning)) + (end (region-end)) + (memed + (message + (s-trim-right + (apply #'string + (-flatten + (nreverse + (-reduce-from (lambda (acc x) + (cons (cons x (-repeat (+ 1 (length acc)) 32)) acc)) + '() + (string-to-list (buffer-substring-no-properties start end)))))))))) + + (save-excursion (delete-region start end) + (goto-char start) + (insert memed)))) (provide 'functions) diff --git a/tools/emacs/init/look-and-feel.el b/tools/emacs/init/look-and-feel.el index 9402e09e5620..8f42133fb8a0 100644 --- a/tools/emacs/init/look-and-feel.el +++ b/tools/emacs/init/look-and-feel.el @@ -27,10 +27,6 @@ (font . ,font))) (set-frame-font font t t)) -;; Display battery in mode-line's misc section on adho: -(when (equal "adho" (system-name)) - (setq battery-mode-line-format " %b%p%%") - (display-battery-mode)) ;; Display modeline time in dottime (see https://dotti.me) ;; ;; This is done in a way that initially seems more complicated than @@ -53,7 +49,7 @@ frame. The idea is to not display information like the current time, - load, battery levels in all buffers." + load, battery levels on all buffers." (when (bottom-right-window-p) (telephone-line-raw mode-line-misc-info t))) @@ -81,7 +77,14 @@ '((accent . (telephone-line-major-mode-segment)) (nil . (telephone-line-last-window-segment telephone-line-exwm-workspace-index)) - (highlight . (telephone-line-notmuch-counts)))) + + ;; TODO(tazjin): lets not do this particular thing while I + ;; don't actually run notmuch, there are too many things + ;; that have a dependency on the modeline drawing correctly + ;; (including randr operations!) + ;; + ;; (highlight . (telephone-line-notmuch-counts)) + )) (setq telephone-line-primary-left-separator 'telephone-line-tan-left telephone-line-primary-right-separator 'telephone-line-tan-right diff --git a/tools/emacs/init/nixos.el b/tools/emacs/init/nixos.el deleted file mode 100644 index e384e9b77db8..000000000000 --- a/tools/emacs/init/nixos.el +++ /dev/null @@ -1,103 +0,0 @@ -;; Configure additional settings if this is one of my NixOS machines -;; (i.e. if ExWM is required) -;; -*- lexical-binding: t; -*- - -(require 's) -(require 'f) -(require 'dash) - -(defun pulseaudio-ctl (cmd) - (shell-command (concat "pulseaudio-ctl " cmd)) - (message "Volume command: %s" cmd)) - -(defun volume-mute () (interactive) (pulseaudio-ctl "mute")) -(defun volume-up () (interactive) (pulseaudio-ctl "up")) -(defun volume-down () (interactive) (pulseaudio-ctl "down")) - -(defun brightness-up () - (interactive) - (shell-command "exec light -A 10") - (message "Brightness increased")) - -(defun brightness-down () - (interactive) - (shell-command "exec light -U 10") - (message "Brightness decreased")) - -(defun lock-screen () - (interactive) - (shell-command "screen-lock")) - -(defun generate-randr-config () - (-flatten `(,(-map (lambda (n) (list n "DP2")) (number-sequence 1 7)) - (0 "eDP1") - ,(-map (lambda (n) (list n "eDP1")) (number-sequence 8 9))))) - -(use-package exwm - :hook ((exwm-update-class . (lambda () - ;; Make class name the buffer name - (exwm-workspace-rename-buffer exwm-class-name)))) - :init - (progn - (require 'exwm-config) - - (fringe-mode 3) - - (setq exwm-workspace-number 10) - - ;; 's-r': Reset - (exwm-input-set-key (kbd "s-r") #'exwm-reset) - ;; 's-w': Switch workspace - (exwm-input-set-key (kbd "s-w") #'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)))) - - ;; Launch applications with completion (dmenu style!) - (exwm-input-set-key (kbd "s-d") #'ivy-run-external-command) - (exwm-input-set-key (kbd "s-p") #'ivy-password-store) - (exwm-input-set-key (kbd "C-s-p") '(lambda () - (interactive) - (ivy-password-store "~/.aprila-secrets"))) - - ;; Add Alacritty selector to a key - (exwm-input-set-key (kbd "C-x t") #'counsel-switch-to-alacritty) - - ;; Toggle between line-mode / char-mode - (exwm-input-set-key (kbd "C-c C-t C-t") #'exwm-input-toggle-keyboard) - - ;; Volume keys - (exwm-input-set-key (kbd "") #'volume-mute) - (exwm-input-set-key (kbd "") #'volume-up) - (exwm-input-set-key (kbd "") #'volume-down) - - ;; Brightness keys - (exwm-input-set-key (kbd "") #'brightness-down) - (exwm-input-set-key (kbd "") #'brightness-up) - (exwm-input-set-key (kbd "") #'lock-screen) - - ;; Line-editing shortcuts - (exwm-input-set-simulation-keys - '(([?\C-d] . delete) - ([?\C-w] . ?\C-c))) - - ;; Enable EXWM - (exwm-enable) - - ;; Show time in the mode line - (display-time-mode) - - ;; Configure xrandr when running on laptop - (when (equal (shell-command-to-string "hostname") "adho\n") - (require 'exwm-randr) - (setq exwm-randr-workspace-output-plist (generate-randr-config)) - (exwm-randr-enable)) - - ;; Let buffers move seamlessly between workspaces - (setq exwm-workspace-show-all-buffers t) - (setq exwm-layout-show-all-buffers t))) - -(provide 'nixos) diff --git a/tools/emacs/init/settings.el b/tools/emacs/init/settings.el index 2e4dedc0a535..0bcf73b0e794 100644 --- a/tools/emacs/init/settings.el +++ b/tools/emacs/init/settings.el @@ -13,7 +13,6 @@ ;; Enable support for prescient in ivy & configure it (ivy-prescient-mode) (prescient-persist-mode) -(add-to-list 'ivy-prescient-excluded-commands 'counsel-rg) ;; Move files to trash when deleting (setq delete-by-moving-to-trash t) -- cgit 1.4.1