* .config/git/config: Don't set core.autocrlf = input.
[~bandali/configs] / .emacs.d / init.el
index a04b4c8..f4d7259 100644 (file)
@@ -1,6 +1,6 @@
 ;;; init.el --- bandali's emacs configuration -*- lexical-binding: t -*-
 
 ;;; init.el --- bandali's emacs configuration -*- lexical-binding: t -*-
 
-;; Copyright (C) 2018-2022  Amin Bandali <bandali@gnu.org>
+;; Copyright (c) 2018-2023 Amin Bandali <bandali@gnu.org>
 
 ;; 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
 
 ;; 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
@@ -61,7 +61,7 @@
   ;;    (delight "1.7")
   ;;    (emms "7.7")
   ;;    (rt-liberation "2.4")))
   ;;    (delight "1.7")
   ;;    (emms "7.7")
   ;;    (rt-liberation "2.4")))
-(package-initialize))
+  (package-initialize))
 
 (setq package-archive-upload-base "/ssh:caffeine:~/www/p/elpa")
 
 
 (setq package-archive-upload-base "/ssh:caffeine:~/www/p/elpa")
 
 (when (display-graphic-p)
   ;; (set-frame-font "Source Code Pro-10.5:weight=medium" nil t)
   ;; (set-frame-font "FreeSans" nil t)
 (when (display-graphic-p)
   ;; (set-frame-font "Source Code Pro-10.5:weight=medium" nil t)
   ;; (set-frame-font "FreeSans" nil t)
-  (set-fontset-font t 'arabic "Vazir"))
+  (set-fontset-font t 'arabic "Sahel WOL"))
 
 ;;;; Elisp-level customizations
 
 
 ;;;; Elisp-level customizations
 
 (with-eval-after-load 'time
   (setq
    display-time-default-load-average nil
 (with-eval-after-load 'time
   (setq
    display-time-default-load-average nil
-   display-time-format " %a %b %-e %-l:%M%P"
+   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-mail-icon '(image :type xpm
                                   :file "gnus/gnus-pointer.xpm"
                                   :ascent center)
 
 (run-with-idle-timer 0.1 nil #'require 'battery)
 (with-eval-after-load 'battery
 
 (run-with-idle-timer 0.1 nil #'require 'battery)
 (with-eval-after-load 'battery
-  (setq battery-mode-line-format " %p%% %t")
+  (setq battery-mode-line-format " [%p%% %t]")
   (display-battery-mode))
 
   (display-battery-mode))
 
+(progn ; display system volume in mode-line
+  (defvar b/volume-level 0)
+  (defvar b/volume-mute nil)
+  (defvar b/volume-level-mic 0)
+  (defvar b/volume-mute-mic nil)
+
+  (defun b/volume-get (&optional use-default-source)
+    "Get the default sink volume and mute state.
+If USE-DEFAULT-SOURCE is non-nill, use the default source (e.g. a
+microphone) instead of the default sink."
+    (pcase (split-string   ; expecting: <mute> <volume> (e.g. true 15)
+            (string-trim
+             (shell-command-to-string
+              (mapconcat
+               #'identity
+               `("pamixer"
+                 ,(when use-default-source "--default-source")
+                 "--get-volume"
+                 "--get-mute")
+               " "))))
+      (`(,m ,v)
+       (let ((mute (string= "true" m))
+             (volume (string-to-number v)))
+         `(,mute ,volume)))))
+
+  (defun b/volume-update ()
+    "Update system sound volume as displayed in mode-line."
+    (let ((changed))
+      (pcase (b/volume-get)
+        (`(,mute ,volume)
+         (unless (eq mute b/volume-mute)
+           (setq b/volume-mute mute
+                 changed t))
+         (unless (= volume b/volume-level)
+           (setq b/volume-level volume
+                 changed t))))
+      (pcase (b/volume-get 'mic)
+        (`(,mute ,volume)
+         (unless (eq mute b/volume-mute-mic)
+           (setq b/volume-mute-mic mute
+                 changed t))
+         (unless (= volume b/volume-level-mic)
+           (setq b/volume-level-mic volume
+                 changed t))))
+      (when changed
+        (force-mode-line-update))))
+
+  (defvar b/volume-timer (run-at-time nil 5 #'b/volume-update))
+
+  (setq-default
+   mode-line-format
+   (append
+    mode-line-format
+    '((:eval
+       (format
+        " [%s%%%%%s %s%%%%%s]"
+        (number-to-string b/volume-level)
+        (if b/volume-mute "-" "+")
+        (number-to-string b/volume-level-mic)
+        (if b/volume-mute-mic "-" "+")))))))
+
 ;; (with-eval-after-load 'fringe
 ;;   ;; smaller fringe
 ;;   (fringe-mode '(3 . 1)))
 
 (run-with-idle-timer 0.5 nil #'require 'winner)
 (with-eval-after-load 'winner
 ;; (with-eval-after-load 'fringe
 ;;   ;; smaller fringe
 ;;   (fringe-mode '(3 . 1)))
 
 (run-with-idle-timer 0.5 nil #'require 'winner)
 (with-eval-after-load 'winner
-  (winner-mode 1))
+  (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
 
 (run-with-idle-timer 0.5 nil #'require 'windmove)
 (with-eval-after-load 'windmove
 
 (with-eval-after-load 'ediff
   (setq ediff-window-setup-function 'ediff-setup-windows-plain
 
 (with-eval-after-load 'ediff
   (setq ediff-window-setup-function 'ediff-setup-windows-plain
-        ediff-split-window-function 'split-window-horizontally)
-  (add-hook 'ediff-after-quit-hook-internal #'winner-undo))
+        ediff-split-window-function 'split-window-horizontally))
 
 (with-eval-after-load 'face-remap
   (setq
 
 (with-eval-after-load 'face-remap
   (setq
@@ -418,12 +490,19 @@ Make N (default: 1) copies of the current line or region."
         (dotimes (_ (abs n1))
           (insert text))))))
 
         (dotimes (_ (abs n1))
           (insert text))))))
 
-(defun b/invert-default-face ()
-  "Invert the `default' face (swap its background and foreground).
-Effectively a very simple light/dark theme toggle switch."
-  (interactive)
-  (invert-face 'default (selected-frame))
-  (invert-face 'mode-line (selected-frame)))
+(defun b/invert-default-face (arg)
+  "Invert the `default' and `mode-line' faces for the current frame.
+Swap the background and foreground for the two `default' and
+`mode-line' faces, effectively acting like a simple light/dark
+theme toggle.  If prefix argument ARG is given, invert the faces
+for all frames."
+  (interactive "P")
+  (let ((frame (unless arg
+                 (selected-frame))))
+    (invert-face 'default frame)
+    (invert-face 'mode-line frame))
+  (when (fboundp #'exwm-systemtray--refresh-background-color)
+    (exwm-systemtray--refresh-background-color 'remap)))
 
 (defun b/export-frame ()
   (interactive)
 
 (defun b/export-frame ()
   (interactive)
@@ -484,7 +563,14 @@ Effectively a very simple light/dark theme toggle switch."
  (expand-file-name
   (convert-standard-filename "lisp") user-emacs-directory))
 
  (expand-file-name
   (convert-standard-filename "lisp") user-emacs-directory))
 
-;; (require 'bandali-exwm)
+(when
+    (and
+     (display-graphic-p)
+     ;; we're not running in another WM/DE
+     (not (getenv "XDG_CURRENT_DESKTOP"))
+     (member (system-name) '("chaman" "langa")))
+  (require 'bandali-exwm)
+  (global-set-key (kbd "C-x b") #'exwm-workspace-switch-to-buffer))
 
 (require 'bandali-org)
 
 
 (require 'bandali-org)
 
@@ -861,4 +947,24 @@ Effectively a very simple light/dark theme toggle switch."
 (with-eval-after-load 'ffs
   (global-set-key (kbd "C-c f s") #'ffs))
 
 (with-eval-after-load 'ffs
   (global-set-key (kbd "C-c f s") #'ffs))
 
+(add-to-list 'load-path (b/lisp "debian-el"))
+(run-with-idle-timer 0.5 nil #'require 'debian-el)
+(with-eval-after-load 'debian-el
+  (require 'apt-sources)
+  (require 'apt-utils)
+  (require 'debian-bug)
+  (require 'deb-view)
+  (require 'gnus-BTS)
+  (require 'preseed))
+
+(add-to-list 'load-path (b/lisp "dpkg-dev-el"))
+(run-with-idle-timer 0.5 nil #'require 'dpkg-dev-el)
+(with-eval-after-load 'dpkg-dev-el
+  (require 'debian-changelog-mode)
+  (require 'debian-bts-control)
+  (require 'debian-changelog-mode)
+  (require 'debian-control-mode)
+  (require 'debian-copyright)
+  (require 'readme-debian))
+
 ;;; init.el ends here
 ;;; init.el ends here