💾 Archived View for irek.xyz › emacs.el captured on 2021-12-03 at 14:04:38.
⬅️ Previous capture (2021-11-30)
-=-=-=-=-=-=-
;;; My humble Emacs (28.0.50v) configuration -*- lexical-binding:t -*- ;; Last update: 2021-06-13 ;; ;; This file is more verbose than my actual config. For real thing ;; clone repository with "git clone git://irek.xyz/emacs". ;; ;; For full documentation of variable or function use help commands: ;; "C-h v" (`describe-variable') and "C-h f" (`describe-function'). ;; ;; Place cursor after closing bracket of `info' function and press ;; "C-x C-e" to open Info page. To close it press "q". Examples: ;; ;; (info "(elisp) Comment Tips") ; Read those Info pages to ;; (info "(emacs) Pages) ; understand config better ;;; Why not org-mode config? ;; ;; I've started with few big config files maintained with org-mode in ;; spirit of literate programming. As I got to know Emacs better I ;; have began to reduce init file realizing that instead of another ;; package I can use other workflow or functionality that is build in. ;; ;; My knowledge of help commands grew so the need for writing headings ;; and descriptions become unnecessary. I don't share config between ;; different computers so that makes it simpler too. ;; ;; After few years I ended up with short single elisp file. ;;; early-init.el (info "(emacs) Early Init File") (menu-bar-mode -1) ; Maybe GUI is good for discoverability and fun (tool-bar-mode -1) ; to play around but to me it's useless. Early (scroll-bar-mode -1) ; Init is good place to disable all of that. ;; Defining path to file in this variable will force Emacs "Easy ;; Customization Interface" to use given file for auto generated code ;; instead of your main init config. (setq custom-file (concat user-emacs-directory "custom-file.el")) ;;; init.el (info "(emacs) Init File") ;;;; display-time ;; ;; I don't have `display-time-mode' enabled all the time but when I do ;; I like to have it simple and clean. (setq display-time-24hr-format t) ; Use 24 hours time format (setq display-time-default-load-average nil) ; Hide load average ;;;; calendar (setq calendar-week-start-day 1) ; Start week with Monday (setq calendar-date-style 'iso) ; Use YYYY-MM-DD format ;;;; other random stuff (setq-default indent-tabs-mode nil) ; Use spaces over tabs (setq make-backup-files nil) ; Avoid creating backup files (setq-default create-lockfiles nil) ; I don't care about collisions ; and ".#" files are messy (setq dired-maybe-use-globstar t) ; (info "(emacs) Dired Enter") (setq isearch-lazy-count t) ; Show isearch match number (setq confirm-kill-emacs 'yes-or-no-p) ; Prompt after C-x C-c (setq read-buffer-completion-ignore-case t) ; To switch buffer faster (set-language-environment "UTF-8") ; Try to use UTF-8 (fset 'yes-or-no-p 'y-or-n-p) ; Use y/n prompt instead of yes/no (global-set-key (kbd "<f6>") 'recompile) ; For quick recompile ;; Some commands are disabled so that beginning users cannot use them ;; by accident. I like to enable them to avoid confirmation prompt. (put 'narrow-to-region 'disabled nil) (put 'scroll-left 'disabled nil) (put 'dired-find-alternate-file 'disabled nil) ;;;; minor-modes (global-auto-revert-mode t) ; Reload file after change (pending-delete-mode t) ; Overwrite region by typing (ffap-bindings) ; (info "(emacs) FFAP") ;;;; tab-bar (setq tab-bar-close-last-tab-choice ; Disable tab-bar with C-x t 0 'tab-bar-mode-disable) ; if you have only one tab (setq tab-bar-close-button-show nil) ; Hide GUI close tab button (setq tab-bar-new-button-show nil) ; Hide GUI new tab button ;;;; Version Control (VC) ;; Add "node_modules" directory name to list of excluded directories. ;; When working on JavaScript projects I want to ignore "node_modules" ;; directory through all of the Emacs. This is the best way because ;; `vc-directory-exclusion-list' variable is used by other libraries. ;; Mainly "grep" and "project" libraries. ;; ;; Default value for `grep-find-ignored-directories' is set from this ;; variable and `project-find-file' function use it as well. (add-to-list 'vc-directory-exclusion-list "node_modules") (defun my/log-edit-mode-setup () (ispell-change-dictionary "en") ; Enable flyspell and use "en" (flyspell-mode 1)) ; dictionary in VC log edit mode (add-hook 'log-edit-mode-hook 'my/log-edit-mode-setup) ;;;; shr ;; ;; Library used to render HTML in Emacs. Used mainly by `eww' but ;; also by `rmail' mail reader. ;; Overwrite shr functions to avoid raised text. In eww references to ;; footnotes is often moved slightly up resulting in line height being ;; higher in that line. In my opinion this looks bad. (eval-after-load "shr" (lambda () (defun shr-tag-sup (dom) (let ((start (point))) (shr-generic dom))) (defun shr-tag-sub (dom) (let ((start (point))) (shr-generic dom))))) ;;;; spellcheck toggle (defun my/spellcheck-toggle () ; Enable flyspell-mode and (interactive) ; toggle between "polish" and (flyspell-mode) ; "en" dictionaries using (ispell-change-dictionary ; single binding. (if (string= ispell-local-dictionary "en") "polish" "en") nil)) (global-set-key (kbd "C-c s") 'my/spellcheck-toggle) ;;;; org-mode ;; ;; Because of calendar, diary and appointments Emacs features I don't ;; use org-mode as heavily as I used to. Still there are number of ;; variables I like to set. Mostly for agenda and clocking. (setq org-agenda-diary-file 'diary-file) ; Avoid using org for diary (setq org-use-speed-commands t) ; Be quick or be dead! ;; In practice while you working on something you can invoke agenda ;; with "C-c a" (defined later), see all your tasks and plans, maybe ;; edit something and then (while in agenda buffer) exit with "q" and ;; have all your windows restored to the point before "C-c a". (setq org-agenda-restore-windows-after-quit t) ;; List of directories with org files containing TODO tasks. (setq org-agenda-files '("~/org/" "~/company/")) ;; One custom agenda to plan whole week and second to track current ;; day. While planning the week I like to see not scheduled tasks so ;; I can schedule them if possible. During the day I also like to see ;; them so maybe I can do some more if time allows. (setq org-agenda-custom-commands '(("d" "Daily plan" ((agenda "" ((org-agenda-span 1))) (alltodo "" ((org-agenda-todo-ignore-scheduled t) (org-agenda-todo-ignore-deadlines 'all))))) ("w" "Weekly plan" ((agenda "") (alltodo "" ((org-agenda-todo-ignore-scheduled t))))))) (global-set-key (kbd "C-c a") 'org-agenda) ; Show agenda prompt ;; Show current clocking time instead of sum of all clocked hours, ;; because I work on bigger tasks in 45m intervals. So each time I ;; start clocking I like to begin with 0m and end around 45m. (setq org-clock-mode-line-total 'current) ;; To my surprise summary of all logged time using org-clock feature ;; will take into consideration only "this year". I like to have sum ;; of all clocked hours. (setq org-clock-display-default-range 'untilnow) ;; This will allow you to evaluate shell scripts inside code block. (org-babel-do-load-languages 'org-babel-load-languages '((shell . t))) ;;;; rmail (receiving and reading mails) ;; Mails from current year lives inside "inbox" file. When year ends ;; I rename it (for example to "2020") and create new empty "inbox" ;; file for new year. (setq rmail-file-name "~/rmail/inbox") ; Main rmail inbox file ;; Define mailboxes to fetch mails from. If your "username" contains ;; "@" character then replace it with "%40" because this string can ;; have only single "@" before server domain. (setq rmail-primary-inbox-list '("imaps://username@server.org")) ;; Emacs use it's build in implementation of "movemail" program but ;; version from "mailutils" have more features. (setq rmail-movemail-variant-in-use 'mailutils) (setq rmail-remote-password-required t) ; Ask for pass on first use ;; Enable spam filter and examples of spam rules (setq rmail-use-spam-filter t) (setq rsf-definitions-alist '(((from . "spam-company-name-1") (action . delete-spam)) ((from . "spam-company-name-2") (action . delete-spam)))) ;;;; SMTP (sending mails) ;; ;; To make authentication work with server you need to create or edit ;; "~/.authinfo" file and add line (replace capitalized letters with ;; proper values): ;; ;; machine SERVER_ADDRESS port PORT login LOGIN password PASSWORD ;; Set sending method and mail composer. (setq message-send-mail-function 'message-smtpmail-send-it) (setq mail-user-agent 'message-user-agent) (setq user-mail-address "name@server.org") ; Your mail address (setq smtpmail-smtp-server "mail.server.org") ; mail server address (setq smtpmail-stream-type 'ssl) ; Enable ssl (setq smtpmail-smtp-service 465) ; Port (setq smtpmail-smtp-user user-mail-address) ; My username is my mail ;; Send every outgoing mail to myself by adding "BCC: name@server.org" ;; header to each message so all messages (sent and received) are in ;; "inbox" file. This makes it very easy to read whole conversations ;; and archive sent messages. (setq message-default-headers (concat "BCC: " user-mail-address "\n")) (defun my/message-mode-setup () ; Enable `flyspell-mode' and (ispell-change-dictionary "polish") ; "polish" dictionary in mail (flyspell-mode 1)) ; composer. (add-hook 'message-mode-hook 'my/message-mode-setup) ;;;; changing (toggle) font size ;; ;; I like to toggle between two font sizes. For presentations ;; purposes and sometimes to focus on small file portion. (defvar my/font-size 10.0) (defun my/font-size-toggle () (interactive) (setq my/font-size (if (>= my/font-size 14.0) 10.0 14.0)) (set-frame-font (font-spec :family "Monospace" :weight 'normal :slant 'normal :size my/font-size))) (global-set-key (kbd "<f7>") 'my/font-size-toggle) ;;;; packages ;; ;; Because I don't share my config with different machines I don't use ;; "use-package" package. Also I use few packages and even fewer are ;; configured so this part is short. (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) ;;;; c-mode c-eldoc (add-hook 'c-mode-hook 'c-turn-on-eldoc-mode) ;;;; modus themes ;; ;; I mostly use default theme but when I go dark side then modus is my ;; weapon of choice. (setq modus-themes-hl-line 'accented-background) (setq modus-themes-mode-line 'accented) ;;;; pass (defun my/pass-get-password (password-path) "Get password stored under PASSWORD-PATH in pass (https://www.passwordstore.org/)." (with-temp-buffer (shell-command (format "pass %s | head -1" password-path) (buffer-name)) (string-trim (buffer-string)))) ;;;; circe (irc) https://xkcd.com/1782/ ;; ;; I used to use powerful "erc" for a while and minimalistic "rcirc" ;; for few years. I usually like to stick with build in libraries and ;; packages but "circe" is a great balance between those two. (eval-after-load "circe" (lambda () (require 'circe-color-nicks) ; Load nicks coloring lib (setq circe-color-nicks-everywhere t) ; Color nicks in messages (enable-circe-color-nicks) ; Enable coloring ;; By default your messages are printed with no nick ("> text"). ;; But I like to see my nick in conversations so I can easily ;; search for my messages. (setq circe-format-self-say "<{nick}> {body}") ;; If someone change topic it's not always obvious what exactly ;; was modified. With "{topic-diff}" you will see information ;; about topic change as a diff. (setq circe-format-server-topic "*** Topic change by {userhost}: {topic-diff}") ;; Enable flyspell in chat. Define rules for dictionaries. Here ;; channels that ends with "-pl" will have "polish" dictionary, ;; otherwise use "en". (setq lui-flyspell-p t) (setq lui-flyspell-alist '((".*[\\.-]pl$" "polish") (".*" "en"))) ;; Log messages. Define path, load logging module and enable it. (setq lui-logging-directory "~/.config/emacs/irc-logs") (load "lui-logging" nil t) (enable-lui-logging-globally) ;; Enable tracking. It will show line in place you last read ;; before switching to other buffer so you can continue reading ;; from there. Binding allows to jump to that place directly. (enable-lui-track) (define-key circe-mode-map (kbd "C-c C-a") 'lui-track-jump-to-indicator) ;; Server connection setup. Note that ":pass" uses my function ;; `my/pass-get-password' to get password. As a first argument ;; `circe' pass value of ":host" and that is path under which I ;; have my password. (setq circe-network-options '(("libera" :host "irc.libera.chat" :port 6697 :tls t :nick "irek" :user "irek" :pass my/pass-get-password :reduce-lurker-spam t :channels ("#emacs" "#emacs-circe" "#emacsconf" "#emacs-pl")))) ))