;;; bandali-essentials.el --- bandali's essentials -*- lexical-binding: t; -*- ;; Copyright (c) 2018-2025 Amin Bandali ;; Author: Amin Bandali ;; Keywords: files, internal ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; The core essentials of my GNU Emacs setup. ;;; Code: (setq-default ;; Case-sensitive search (and `dabbrev-expand'). ;; case-fold-search nil indent-tabs-mode nil ; always use space for indentation ;; tab-width 4 indicate-buffer-boundaries 'left) (setq ;; line-spacing 3 completion-ignore-case t read-buffer-completion-ignore-case t enable-recursive-minibuffers t resize-mini-windows t message-log-max 20000 mode-line-compact t ;; mouse-autoselect-window t scroll-conservatively 15 scroll-preserve-screen-position 1 ;; I don't feel like randomly jumping out of my chair. ring-bell-function 'ignore) ;; Mode-line compacting for older Emacsen. (when (and (version< emacs-version "28") mode-line-compact) ;; Manually make some `mode-line' spaces smaller. ;; Emacs 28 and above do a terrific job at this out of the box ;; when `mode-line-compact' is set to t (see above)." (setq-default mode-line-format (mapcar (lambda (x) (if (and (stringp x) (or (string= x " ") (string= x " "))) " " x)) mode-line-format) mode-line-buffer-identification (propertized-buffer-identification "%10b"))) ;; Fonts and types. (when (display-graphic-p) (set-fontset-font t 'arabic "Sahel WOL") (let ((emoji-font "Apple Color Emoji")) (when (member emoji-font (font-family-list)) (set-fontset-font t 'emoji `(,emoji-font . "iso10646-1") nil 'prepend))) (with-eval-after-load 'faces (let ((grey "#e7e7e7")) (set-face-attribute 'default nil :font "Source Code Pro Medium-10.5") (set-face-attribute 'fixed-pitch nil :font "Source Code Pro Medium-10.5") (set-face-attribute 'mode-line nil :box '(:line-width 2 :style released-button) :background grey :inherit 'fixed-pitch)))) (when (display-graphic-p) ;; Too easy to accidentally suspend (freeze) Emacs GUI. (b/keymap-global-unset "C-z")) (b/keymap-global-set "C-c e b" #'eval-buffer) (b/keymap-global-set "C-c e r" #'eval-region) (with-eval-after-load 'minibuffer (setopt read-file-name-completion-ignore-case t)) (with-eval-after-load 'files (setopt make-backup-files nil ;; Insert newline at the end of files. ;; require-final-newline t ;; Open read-only file buffers in view-mode, to get `q' for quit. view-read-only t) (add-to-list 'auto-mode-alist '("\\(README.*\\|COMMIT_EDITMSG$\\)" . text-mode)) (add-to-list 'auto-mode-alist '("\\.*rc$" . conf-mode)) (add-to-list 'auto-mode-alist '("\\.bashrc$" . sh-mode))) (b/keymap-global-set "C-c f ." #'find-file) ;; `ffap' (b/keymap-global-set "C-c f p" #'find-file-at-point) ;; `find-func' (b/keymap-global-set "C-c f l" #'find-library) ;; `frame' (b/keymap-global-set "C-c F m" #'make-frame-command) (b/keymap-global-set "C-c F d" #'delete-frame) (with-eval-after-load 'window (setopt split-width-threshold 140)) ;; `novice' (setq disabled-command-function nil) (run-with-idle-timer 0.1 nil #'require 'autorevert) (with-eval-after-load 'autorevert (setopt ;; auto-revert-verbose nil global-auto-revert-non-file-buffers nil) (global-auto-revert-mode 1)) (run-with-idle-timer 0.1 nil #'require 'time) (with-eval-after-load 'time (setopt display-time-default-load-average nil display-time-format " %a %Y-%m-%d %-l:%M%P" display-time-mail-icon '(image :type xpm :file "gnus/gnus-pointer.xpm" :ascent center) display-time-use-mail-icon t zoneinfo-style-world-list `(,@zoneinfo-style-world-list ("Etc/UTC" "UTC") ("Asia/Tehran" "Tehran") ("Australia/Melbourne" "Melbourne"))) (unless (display-graphic-p) (display-time-mode 1))) (b/keymap-global-set "C-c e i" #'emacs-init-time) (b/keymap-global-set "C-c e u" #'emacs-uptime) (defvar b/battery-format "%p%b %t") (run-with-idle-timer 0.1 nil #'require 'battery) (with-eval-after-load 'battery (setopt battery-mode-line-format (format " [%s]" b/battery-format)) ;; (display-battery-mode -1) ) (run-with-idle-timer 0.5 nil #'require 'winner) (with-eval-after-load 'winner (winner-mode 1) (when (featurep 'exwm) ;; prevent a bad interaction between EXWM and winner-mode, where ;; sometimes closing a window (like closing a terminal after ;; entering a GPG password via pinentry-gnome3's floating window) ;; results in a dead frame somewhere and effectively freezes EXWM. (advice-add 'winner-insert-if-new :around (lambda (orig-fun &rest args) ;; only add the frame if it's live (when (frame-live-p (car args)) (apply orig-fun args)))))) (run-with-idle-timer 0.5 nil #'require 'windmove) (with-eval-after-load 'windmove (setopt windmove-wrap-around t) (b/keymap-global-set "M-H" #'windmove-left) (b/keymap-global-set "M-L" #'windmove-right) (b/keymap-global-set "M-K" #'windmove-up) (b/keymap-global-set "M-J" #'windmove-down)) (with-eval-after-load 'isearch (setopt isearch-allow-scroll t isearch-lazy-count t ;; Match non-ASCII variants during search search-default-mode #'char-fold-to-regexp)) ;; `vc' (b/keymap-global-set "C-x v C-=" #'vc-ediff) (with-eval-after-load 'vc-git (setopt ;; vc-git-show-stash 0 vc-git-print-log-follow t)) (with-eval-after-load 'ediff (setopt ediff-window-setup-function #'ediff-setup-windows-plain ediff-split-window-function #'split-window-horizontally)) ;; (with-eval-after-load 'face-remap ;; (setopt ;; ;; Gentler font resizing. ;; text-scale-mode-step 1.05)) (run-with-idle-timer 0.4 nil #'require 'mwheel) (with-eval-after-load 'mwheel (setopt mouse-wheel-scroll-amount '(1 ((shift) . 1)) ; one line at a time mouse-wheel-progressive-speed nil ; don't accelerate scrolling mouse-wheel-follow-mouse t)) ; scroll window under mouse (run-with-idle-timer 0.4 nil #'require 'pixel-scroll) (with-eval-after-load 'pixel-scroll (pixel-scroll-mode 1)) (with-eval-after-load 'epg-config (setopt epg-gpg-program (executable-find "gpg") ;; Ask for GPG passphrase in minibuffer. ;; Will fail if gpg >= 2.1 is not available. epg-pinentry-mode 'loopback)) ;; (with-eval-after-load 'auth-source ;; (setopt ;; auth-sources '("~/.authinfo.gpg") ;; authinfo-hidden ;; (regexp-opt '("password" "client-secret" "token")))) (with-eval-after-load 'info (setq Info-directory-list `(,@Info-directory-list ,(expand-file-name (convert-standard-filename "info/") source-directory) "/usr/share/info/"))) ;; `ielm' (b/keymap-global-set "C-c i" #'ielm) (run-with-idle-timer 0.2 nil #'require 'recentf) (with-eval-after-load 'recentf (setopt recentf-max-saved-items 2000) (recentf-mode 1) (defun b/recentf-open () "Use `completing-read' to \\[find-file] a recent file." (interactive) (find-file (completing-read "Find recent file: " recentf-list))) (b/keymap-global-set "C-c f r" #'b/recentf-open)) (with-eval-after-load 'help (temp-buffer-resize-mode 1) (setopt help-window-select t)) (with-eval-after-load 'help-mode (let ((m help-mode-map)) (b/keymap-set m "p" #'backward-button) (b/keymap-set m "n" #'forward-button) (b/keymap-set m "b" #'help-go-back) (b/keymap-set m "f" #'help-go-forward))) ;; `help-fns' (b/keymap-global-set "C-c h F" #'describe-face) (with-eval-after-load 'doc-view (b/keymap-set doc-view-mode-map "M-RET" #'image-previous-line)) (with-eval-after-load 'man (setopt Man-width 80)) (with-eval-after-load 'shr (setopt shr-max-width 80)) (with-eval-after-load 'mule-cmds (setopt default-input-method "farsi-isiri-9147")) (with-eval-after-load 'tramp (tramp-set-completion-function "ssh" (append (tramp-get-completion-function "ssh") (mapcar (lambda (file) `(tramp-parse-sconfig ,file)) (directory-files "~/.ssh/config.d/" 'full directory-files-no-dot-files-regexp))))) ;; Display Lisp objects at point in the echo area. (with-eval-after-load 'eldoc (setopt eldoc-minor-mode-string " eldoc") (global-eldoc-mode 1)) ;; Highlight matching parens. (run-with-idle-timer 0.2 nil #'require 'paren) (with-eval-after-load 'paren (show-paren-mode 1)) (with-eval-after-load 'simple (setopt ;; See `bandali-gnus' for my Gnus configuration. mail-user-agent 'gnus-user-agent read-mail-command #'gnus ;; Save what I copy into clipboard from other applications into ;; Emacs' kill-ring, which would allow me to still be able to ;; easily access it in case I kill (cut or copy) something else ;; inside Emacs before yanking (pasting) what I'd originally ;; intended to. save-interprogram-paste-before-kill t) (column-number-mode 1) (line-number-mode 1)) (add-hook 'text-mode-hook #'auto-fill-mode) (add-hook 'tex-mode-hook #'auto-fill-mode) ;; Save minibuffer history. (run-with-idle-timer 0.2 nil #'require 'savehist) (with-eval-after-load 'savehist (savehist-mode 1) (add-to-list 'savehist-additional-variables 'kill-ring)) ;; Automatically save place in files. (run-with-idle-timer 0.2 nil #'require 'saveplace nil 'noerror) (with-eval-after-load 'saveplace (save-place-mode 1)) (with-eval-after-load 'flyspell (setopt flyspell-mode-line-string " fly")) (add-hook 'text-mode-hook #'flyspell-mode) (add-hook 'tex-mode-hook #'flyspell-mode) ;; `abbrev' (add-hook 'text-mode-hook #'abbrev-mode) (with-eval-after-load 'eww (setopt eww-download-directory (file-name-as-directory (getenv "XDG_DOWNLOAD_DIR")))) (b/keymap-global-set "C-c e w" #'eww) (run-with-idle-timer 0.2 nil #'require 'display-fill-column-indicator nil 'noerror) (with-eval-after-load 'display-fill-column-indicator (global-display-fill-column-indicator-mode 1)) (when (version<= "30" emacs-version) ;; (package-installed-p 'completion-preview) (with-eval-after-load 'completion-preview (let ((m completion-preview-active-mode-map)) (b/keymap-set m "M-p" #'completion-preview-prev-candidate) (b/keymap-set m "M-n" #'completion-preview-next-candidate) (b/keymap-set m "M-i" #'completion-preview-insert))) (add-hook 'prog-mode-hook #'completion-preview-mode) (add-hook 'text-mode-hook #'completion-preview-mode) (add-hook 'comint-mode-hook #'completion-preview-mode)) ;; `version' (b/keymap-global-set "C-c e v" #'emacs-version) (provide 'bandali-essentials) ;;; bandali-essentials.el ends here