;;; 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
;; (delight "1.7")
;; (emms "7.7")
;; (rt-liberation "2.4")))
-(package-initialize))
+ (package-initialize))
(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)
- (set-fontset-font t 'arabic "Vazir"))
+ (set-fontset-font t 'arabic "Sahel WOL"))
;;;; Elisp-level customizations
(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)
(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))
+(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
- (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
(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
(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)
(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)
(define-key b/boxquote-prefix-map (kbd "M-q") #'boxquote-fill-paragraph)
(define-key b/boxquote-prefix-map (kbd "M-w") #'boxquote-kill-ring-save))
-(add-to-list 'load-path (b/lisp "hl-todo"))
-(run-with-idle-timer 0.5 nil #'require 'hl-todo)
-(with-eval-after-load 'hl-todo
- ;; Highlight TODO in buffers.
- (global-hl-todo-mode))
-
;; `debbugs'
(global-set-key (kbd "C-c D d") #'debbugs-gnu)
(global-set-key (kbd "C-c D b") #'debbugs-gnu-bugs)