X-Git-Url: https://git.shemshak.org/~bandali/configs/blobdiff_plain/8b1a2f3244208cebd3dc595d8e7027bb9c5c3625..679463c61523f4eed0ab40468e9504166863e4ac:/init.el diff --git a/init.el b/init.el index f8f755a..184ae64 100644 --- a/init.el +++ b/init.el @@ -19,8 +19,7 @@ ;; GNU Emacs configuration of Amin Bandali, computer scientist, ;; Free Software activist, and GNU maintainer & webmaster. Packages -;; are installed through GNU Guix for a fully reproducible setup. -;; Before switching to Guix, I used straight.el, and before that Borg. +;; are installed through using Borg for a fully reproducible setup. ;; Over the years, I've taken inspiration from configurations of many ;; great people. Some that I can remember off the top of my head are: @@ -107,14 +106,6 @@ ;;; Package management -;; No package.el (for emacs 26 and before) -(when (version< emacs-version "27") - (setq package-enable-at-startup nil) - ;; (package-initialize) - ) -;; for emacs 27 and later, we use early-init.el. see -;; https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=24acb31c04b4048b85311d794e600ecd7ce60d3b - (progn ; `borg' (add-to-list 'load-path (expand-file-name "lib/borg" user-emacs-directory)) @@ -182,16 +173,12 @@ ;; start up emacs server. see ;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html#Emacs-Server (use-package server - :defer 0.4 + :defer 0.5 :config (or (server-running-p) (server-mode))) ;;; Useful utilities -;; useful libraries -(require 'cl-lib) -(require 'subr-x) - (defmacro b/setq-every (value &rest vars) "Set all the variables from VARS to value VALUE." (declare (indent defun) (debug t)) @@ -216,7 +203,7 @@ (defun b/add-elisp-section () (interactive) (insert "\n") - (previous-line) + (forward-line -1) (insert "\n \n;;; ")) ;; (defvar b/fill-column 47 @@ -279,7 +266,7 @@ For disabling the behaviour for certain buffers and/or modes." indent-tabs-mode nil tab-width 4 ;; cursor shape - cursor-type 'bar) + cursor-type t) ;; unicode support (comment @@ -377,7 +364,7 @@ For disabling the behaviour for certain buffers and/or modes." (display-time-mode) :custom (display-time-default-load-average nil) - (display-time-format "%a %b %-e %-l:%M%P") + (display-time-format " %a %b %-e %-l:%M%P") (display-time-mail-icon '(image :type xpm :file "gnus/gnus-pointer.xpm" :ascent center)) (display-time-use-mail-icon t)) @@ -386,7 +373,7 @@ For disabling the behaviour for certain buffers and/or modes." :config (display-battery-mode) :custom - (battery-mode-line-format " %p%% %t")) + (battery-mode-line-format "%p%% %t")) (use-package fringe :demand @@ -473,9 +460,7 @@ For disabling the behaviour for certain buffers and/or modes." :config ;; ask for GPG passphrase in minibuffer ;; this will fail if gpg>=2.1 is not available - (if (version< "27" emacs-version) - (setq epg-pinentry-mode 'loopback) - (setq epa-pinentry-mode 'loopback)) + (setq epg-pinentry-mode 'loopback) :custom (epg-gpg-program (executable-find "gpg"))) @@ -510,6 +495,10 @@ For disabling the behaviour for certain buffers and/or modes." ("C-c e u" . emacs-uptime) ("C-c e v" . emacs-version) + ("C-c f ." . find-file) + ("C-c f d" . find-name-dired) + ("C-c f l" . find-library) + ("C-c F m" . make-frame-command) ("C-c F d" . delete-frame) ("C-c F D" . server-edit) @@ -517,6 +506,8 @@ For disabling the behaviour for certain buffers and/or modes." ("C-S-h C" . describe-char) ("C-S-h F" . describe-face) + ("C-c x" . execute-extended-command) + ("C-x k" . b/kill-current-buffer) ("C-x K" . kill-buffer) ("C-x s" . save-buffer) @@ -543,108 +534,18 @@ For disabling the behaviour for certain buffers and/or modes." ;;; Essential packages +(add-to-list + 'load-path + (expand-file-name + (convert-standard-filename "lisp") user-emacs-directory)) + (when b/exwm-p (require 'bandali-exwm)) -(use-package org - :config - (setq org-src-tab-acts-natively t - org-src-preserve-indentation nil - org-edit-src-content-indentation 0 - org-link-email-description-format "Email %c: %s" ; %.30s - org-highlight-latex-and-related '(entities) - org-use-speed-commands t - org-startup-folded 'content - org-catch-invisible-edits 'show-and-error - org-log-done 'time) - (when (version< org-version "9.3") - (setq org-email-link-description-format - org-link-email-description-format)) - (add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp") t) - (add-to-list 'org-modules 'org-habit) - :bind - (("C-c a o a" . org-agenda) - :map org-mode-map - ("M-L" . org-insert-last-stored-link) - ("M-O" . org-toggle-link-display)) - :hook ((org-mode . org-indent-mode) - (org-mode . auto-fill-mode) - (org-mode . flyspell-mode)) - :custom - (org-pretty-entities t) - (org-agenda-files '("~/usr/org/todos/personal.org" - "~/usr/org/todos/habits.org" - "~/src/git/masters-thesis/todo.org")) - (org-agenda-start-on-weekday 0) - (org-agenda-time-leading-zero t) - (org-habit-graph-column 44) - (org-latex-packages-alist '(("" "listings") ("" "color"))) - :custom-face - '(org-block-begin-line ((t (:foreground "#5a5b5a" :background "#1d1f21")))) - '(org-block ((t (:background "#1d1f21")))) - '(org-latex-and-related ((t (:foreground "#b294bb"))))) - -(use-package ox-latex - :after ox - :config - (setq org-latex-listings 'listings - ;; org-latex-prefer-user-labels t - ) - (add-to-list 'org-latex-classes - '("IEEEtran" "\\documentclass[11pt]{IEEEtran}" - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}") - ("\\paragraph{%s}" . "\\paragraph*{%s}") - ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) - t) - (require 'ox-beamer)) - -(use-package ox-extra - :config - (ox-extras-activate '(latex-header-blocks ignore-headlines))) - -;; asynchronous tangle, using emacs-async to asynchronously tangle an -;; org file. closely inspired by -;; https://github.com/dieggsy/dotfiles/tree/cc10edf7701958eff1cd94d4081da544d882a28c/emacs.d#dotfiles -(with-eval-after-load 'org - (defvar b/show-async-tangle-results nil - "Keep *emacs* async buffers around for later inspection.") - - (defvar b/show-async-tangle-time nil - "Show the time spent tangling the file.") - - (defun b/async-babel-tangle () - "Tangle org file asynchronously." - (interactive) - (let* ((file-tangle-start-time (current-time)) - (file (buffer-file-name)) - (file-nodir (file-name-nondirectory file)) - ;; (async-quiet-switch "-q") - (file-noext (file-name-sans-extension file))) - (async-start - `(lambda () - (require 'org) - (org-babel-tangle-file ,file)) - (unless b/show-async-tangle-results - `(lambda (result) - (if result - (message "Tangled %s%s" - ,file-nodir - (if b/show-async-tangle-time - (format " (%.3fs)" - (float-time (time-subtract (current-time) - ',file-tangle-start-time))) - "")) - (message "Tangling %s failed" ,file-nodir)))))))) - -(add-to-list - 'safe-local-variable-values - '(eval add-hook 'after-save-hook #'b/async-babel-tangle 'append 'local)) +(require 'bandali-org) ;; *the* right way to do git (use-package magit - :defer 0.5 :bind (("C-x g" . magit-status) ("C-c g g" . magit-status) ("C-c g b" . magit-blame-addition) @@ -679,253 +580,18 @@ For disabling the behaviour for certain buffers and/or modes." :custom (recentf-max-saved-items 2000)) -;; smart M-x enhancement (needed by counsel for history) -;; (use-package smex) - -(bind-keys - ("C-c f ." . find-file) - ("C-c f d" . find-name-dired) - ("C-c f l" . find-library) - ;; ("C-c f r" . recentf-open-files) - ("C-c x" . execute-extended-command)) - -(comment - (use-package ido - :demand - :bind - (:map ido-common-completion-map - ([escape] . minibuffer-keyboard-quit) - ("DEL" . b/ido-backspace)) - :config - (require 'delsel) - (defun b/ido-backspace () - "Forward to `backward-delete-char'. On error (read-only), quit." - (interactive) - (condition-case nil - (backward-delete-char 1) - (error - (minibuffer-keyboard-quit)))) - (ido-mode 1) - (ido-everywhere 1) - :custom - (ido-enable-flex-matching t) - ;; (ido-enable-regexp t) - ;; (ido-enable-prefix t) - (ido-max-window-height 10) - (ido-use-virtual-buffers t)) - - (use-package ido-vertical-mode - :defer 0.3 - :config - (ido-vertical-mode 1) - :custom - (ido-vertical-define-keys 'C-n-C-p-up-and-down) - (ido-vertical-show-count t)) - - (use-package ido-completing-read+ - :defer 0.3 - :after ido - :config - (ido-ubiquitous-mode 1)) - - (use-package crm-custom - :defer 0.3 - :config - (crm-custom-mode 1)) - - (use-package icomplete - :defer 0.3 - :config - (icomplete-mode 1))) - +;; needed for history for counsel (use-package amx :defer 0.3 :config (amx-mode)) -(use-package ivy - :defer 0.3 - :bind - (:map ivy-minibuffer-map - ([escape] . keyboard-escape-quit) - ([S-up] . ivy-previous-history-element) - ([S-down] . ivy-next-history-element) - ("DEL" . ivy-backward-delete-char)) - :config - (setq ivy-wrap t - ;; ivy-height 14 - ivy-use-virtual-buffers t - ivy-virtual-abbreviate 'abbreviate - ivy-count-format "%d/%d ") - - (defvar b/ivy-ignore-buffer-modes '(magit-mode erc-mode dired-mode)) - (defun b/ivy-ignore-buffer-p (str) - "Return non-nil if str names a buffer with a major mode -derived from one of `b/ivy-ignore-buffer-modes'. - -This function is intended for use with `ivy-ignore-buffers'." - (let* ((buf (get-buffer str)) - (mode (and buf (buffer-local-value 'major-mode buf)))) - (and mode - (apply #'provided-mode-derived-p mode b/ivy-ignore-buffer-modes)))) - (add-to-list 'ivy-ignore-buffers 'b/ivy-ignore-buffer-p) - - (ivy-mode 1) - :custom-face - (ivy-minibuffer-match-face-1 ((t (:background "#eeeeee")))) - (ivy-minibuffer-match-face-2 ((t (:background "#e7e7e7" :weight bold)))) - (ivy-minibuffer-match-face-3 ((t (:background "light goldenrod" :weight semi-bold)))) - (ivy-minibuffer-match-face-4 ((t (:background "misty rose" :weight semi-bold)))) - (ivy-current-match ((((class color) (background light)) - :background "#d7d7d7" :foreground "black") - (((class color) (background dark)) - :background "#65a7e2" :foreground "black")))) - -(use-package swiper - :demand - :after ivy - :bind (("C-S-s" . swiper-isearch))) - -(use-package counsel - :demand - :after ivy - :bind (("C-c f r" . counsel-recentf) - :map minibuffer-local-map - ("C-r" . counsel-minibuffer-history)) - :config - (counsel-mode 1) - (defalias 'locate #'counsel-locate)) - -(comment -(use-package eshell - :defer 0.5 - :commands eshell - :bind ("C-c a s e" . eshell) - :config - (eval-when-compile (defvar eshell-prompt-regexp)) - (defun b/eshell-quit-or-delete-char (arg) - (interactive "p") - (if (and (eolp) (looking-back eshell-prompt-regexp nil)) - (eshell-life-is-too-much) - (delete-char arg))) - - (defun b/eshell-clear () - (interactive) - (let ((inhibit-read-only t)) - (erase-buffer)) - (eshell-send-input)) - - (defun b/eshell-setup () - (make-local-variable 'company-idle-delay) - (defvar company-idle-delay) - (setq company-idle-delay nil) - (bind-keys :map eshell-mode-map - ("C-d" . b/eshell-quit-or-delete-char) - ("C-S-l" . b/eshell-clear) - ("M-r" . counsel-esh-history) - ;; ([tab] . company-complete) - ) - (if (version< "27" emacs-version) - (bind-keys :map eshell-hist-mode-map - ("M-r" . counsel-esh-history)) - (bind-keys :map eshell-mode-map - ("M-r" . counsel-esh-history)))) +;; (require 'bandali-ido) +(require 'bandali-ivy) - (setq - eshell-prompt-regexp "\\(.*\n\\)*[$#] " - eshell-prompt-function - (lambda () - (concat - (propertize (format "%s@%s:" (user-login-name) (system-name)) - 'face 'default) - (propertize (abbreviate-file-name default-directory) - 'face 'font-lock-comment-face) - (propertize "\n" 'face 'default) - (if (= (user-uid) 0) - (propertize "#" 'face 'red) - (propertize "$" 'face 'default)) - (propertize " " 'face 'default)))) - - :hook (eshell-mode . b/eshell-setup) - :custom - (eshell-hist-ignoredups t) - (eshell-input-filter 'eshell-input-filter-initial-space)) +(require 'bandali-eshell) -(use-package ibuffer - :bind - (("C-x C-b" . ibuffer) - :map ibuffer-mode-map - ("P" . ibuffer-backward-filter-group) - ("N" . ibuffer-forward-filter-group) - ("M-p" . ibuffer-do-print) - ("M-n" . ibuffer-do-shell-command-pipe-replace)) - :config - ;; Use human readable Size column instead of original one - (define-ibuffer-column size-h - (:name "Size" :inline t) - (cond - ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0))) - ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0))) - ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0))) - (t (format "%8d" (buffer-size))))) - :custom - (ibuffer-saved-filter-groups - '(("default" - ("dired" (mode . dired-mode)) - ("org" (mode . org-mode)) - ("gnus" - (or - (mode . gnus-group-mode) - (mode . gnus-summary-mode) - (mode . gnus-article-mode) - ;; not really, but... - (mode . message-mode))) - ("web" - (or - ;; (mode . web-mode) - (mode . mhtml-mode) - (mode . css-mode) - (mode . scss-mode) - (mode . js2-mode))) - ("shell" - (or - (mode . eshell-mode) - (mode . shell-mode) - (mode . term-mode))) - ("programming" - (or - (mode . python-mode) - (mode . c-mode) - (mode . c++-mode) - (mode . java-mode) - (mode . emacs-lisp-mode) - (mode . scheme-mode) - (mode . haskell-mode) - (mode . lean-mode) - ;; (mode . go-mode) - (mode . alloy-mode))) - ("tex" - (or - (mode . bibtex-mode) - (mode . latex-mode))) - ("emacs" - (or - (name . "^\\*scratch\\*$") - (name . "^\\*Messages\\*$"))) - ("exwm" (mode . exwm-mode)) - ("erc" (mode . erc-mode))))) - (ibuffer-formats - '((mark modified read-only locked " " - (name 72 72 :left :elide) - " " - (size-h 9 -1 :right) - " " - (mode 16 16 :left :elide) - " " filename-and-process) - (mark " " - (name 16 -1) - " " filename))) - :hook (ibuffer . (lambda () (ibuffer-switch-to-saved-filter-groups "default")))) +(require 'bandali-ibuffer) (use-package outline :disabled @@ -945,58 +611,11 @@ This function is intended for use with `ivy-ignore-buffers'." ("h" . outline-hide-subtree) ("s" . outline-show-subtree))) +(comment (use-package ls-lisp :custom (ls-lisp-dirs-first t)) -(use-package dired - :config - (setq dired-dwim-target t - dired-listing-switches "-alh" - ls-lisp-use-insert-directory-program nil) - - ;; easily diff 2 marked files - ;; https://oremacs.com/2017/03/18/dired-ediff/ - (defun dired-ediff-files () - (interactive) - (require 'dired-aux) - (defvar ediff-after-quit-hook-internal) - (let ((files (dired-get-marked-files)) - (wnd (current-window-configuration))) - (if (<= (length files) 2) - (let ((file1 (car files)) - (file2 (if (cdr files) - (cadr files) - (read-file-name - "file: " - (dired-dwim-target-directory))))) - (if (file-newer-than-file-p file1 file2) - (ediff-files file2 file1) - (ediff-files file1 file2)) - (add-hook 'ediff-after-quit-hook-internal - (lambda () - (setq ediff-after-quit-hook-internal nil) - (set-window-configuration wnd)))) - (error "no more than 2 files should be marked")))) - - (require 'dired-x) - (setq dired-guess-shell-alist-user - '(("\\.pdf\\'" "evince" "zathura" "okular") - ("\\.doc\\'" "libreoffice") - ("\\.docx\\'" "libreoffice") - ("\\.ppt\\'" "libreoffice") - ("\\.pptx\\'" "libreoffice") - ("\\.xls\\'" "libreoffice") - ("\\.xlsx\\'" "libreoffice") - ("\\.flac\\'" "mpv"))) - :bind (:map dired-mode-map - ("b" . dired-up-directory) - ("E" . dired-ediff-files) - ("e" . dired-toggle-read-only) - ("\\" . dired-hide-details-mode) - ("z" . (lambda () - (interactive) - (b/dired-start-process "zathura")))) - :hook (dired-mode . dired-hide-details-mode)) +(require 'bandali-dired) (use-package help :config