Just so there is a backup

This commit is contained in:
2024-11-18 09:11:55 +02:00
parent 85ecb7b4a0
commit 4984e0a3ed
34 changed files with 1830 additions and 152 deletions
+428 -7
View File
@@ -4,20 +4,22 @@
* Base setup
** Bootstrapping
Partially based on [[https://stackoverflow.com/questions/151945/how-do-i-control-how-emacs-makes-backup-files][this post on StackOverflow]]. Setting backups, external custom file.
#+begin_src emacs-lisp
(setq
vc-follow-symlinks t ;Follow symlinks
;Backup location TODO FIND IF RELEVANT FOR NIX
backup-directory-alist `(("." . "~/.cache/emacs-backups/"))
auto-save-file-name-transforms '((".*" "~/.cache/emacs-backups/" t))
;Backups from https://www.emacswiki.org/emacs/BackupDirectory
backup-directory-alist `(("." . temporary-file-directory))
auto-save-file-name-transforms '((".*" temporary-file-directory t))
backup-by-copying t ;Always copy never link
delete-old-versions t ;Auto delete old backups
kept-new-versions 6 ;Number of versions to keep
kept-old-versions 2
version-control t ;Backups for files
gc-cons-threshold 100000000 ;Setting garbage collection to 100M.
;Garbage collection
gc-cons-threshold 100000000
;Set external cusotm file
custom-file (expand-file-name "custom.el" user-emacs-directory)
)
@@ -276,7 +278,7 @@ Disabling the toolbar, the splash-screen, the menu-bar and the scroll-bar
While we don't actually want fringes (almost at all), some frames use them.
#+begin_src emacs-lisp
(set-face-attribute 'fringe nil :background "LemonChiffon1")
;; (set-face-attribute 'fringe nil :background "LemonChiffon1")
#+end_src
*** Window dividers
@@ -288,6 +290,218 @@ While we don't actually want fringes (almost at all), some frames use them.
(window-divider-mode 1)
#+end_src
*** Tab bar
*** Base
Prettification of tab bar. We only use tab-bar if the version is greater than 27.1.
We also use this section to bind keys.
#+begin_src emacs-lisp
;; If version greater than 27.1
(defun azos/new-tab-and-rename ()
"Created for back compatibility with emacs 27"
(interactive)
(progn
(tab-bar-new-tab)
(call-interactively 'tab-bar-rename-tab)))
(if (version<= "27.1" emacs-version) (progn
(tab-bar-mode 1)
(set-face-attribute 'tab-bar nil
:box t
:background "LightYellow3"
:foreground "DarkSlateGrey"
:font "LiberationMono"
:height 90)
(set-face-attribute 'tab-bar-tab nil
:box '(:color "DarkSlateGrey" :line-width -2)
:background "LightYellow3"
:weight 'bold)
(set-face-attribute 'tab-bar-tab-inactive nil
:background "LightYellow3"
:inherit 'tab-bar)
(define-key azos/global-minor-mode/keymap
(kbd "M-<tab>") 'tab-next)
(define-key azos/global-minor-mode/keymap
(kbd "M-'") 'tab-previous)
(define-key azos/global-minor-mode/keymap
(kbd "M-t r") 'tab-bar-rename-tab)
(define-key azos/global-minor-mode/keymap
(kbd "M-t n") 'tab-next)
(define-key azos/global-minor-mode/keymap
(kbd "M-t p") 'tab-previous)
(define-key azos/global-minor-mode/keymap
(kbd "M-t x") 'tab-bar-close-tab)
(define-key azos/global-minor-mode/keymap
(kbd "M-t c") 'azos/new-tab-and-rename)
(setq tab-bar-close-button-show nil
tab-bar-new-button-show nil
tab-bar-separator (propertize "" 'face
(list :foreground "LightYellow1"
:box '(:color "DarkSlateGrey")))
)
(add-hook 'emacs-startup-hook (lambda () (tab-bar-rename-tab "home" 1)))
))
#+end_src
*** Right Group Display
#+begin_src emacs-lisp
(defvar azos/tab-bar/right-update-group '()
"Functions needed to run to update tab bar")
(defvar azos/tab-bar/right-group '()
"A list of items to be displayed on the right of the tab-bar")
(defun azos/tab-bar/right-group-func ()
"Function that returns a string to be displayed on right of tab-bar"
(concat
tab-bar-separator
(mapconcat 'eval
(remove ""
(mapcar 'funcall azos/tab-bar/right-group))
tab-bar-separator)
tab-bar-separator))
(defun azos/tab-bar/update-func () "Function to update the tab bar"
(progn
(mapc 'funcall azos/tab-bar/right-update-group)
(force-mode-line-update)))
(if (version<= "28.1" emacs-version) (progn
(setq tab-bar-format
'(
tab-bar-format-history
tab-bar-format-tabs
tab-bar-separator
tab-bar-format-add-tab
tab-bar-format-align-right
azos/tab-bar/right-group-func)
tab-bar-auto-width nil)
(define-key azos/global-minor-mode/keymap
(kbd "M-n") 'tab-switch)
;; (if (member system-type '(gnu gnu/linux))
;; (azos/run-timer 'tab-timer 'azos/tab-bar/update-func 5))
;; No auto-update, maybe some other way
))
#+end_src
Let's define a clock for the tab bar
#+begin_src emacs-lisp
(defun azos/tab-bar/get-clock-string () "Get tab bar time string"
(propertize (format-time-string "%a, %b %d %H:%M")
'face '(:background "LightYellow3" :foreground "DarkSlateGrey")))
(defun azos/tab-bar/enable-clock-display ()
"Enables clock display in tab bar"
(cl-pushnew 'azos/tab-bar/get-clock-string
azos/tab-bar/right-group))
#+end_src
By default let's enable the clock display
#+begin_src emacs-lisp
(azos/tab-bar/enable-clock-display)
#+end_src
*** Tab bar addons
**** Battery status in tab bar
#+begin_src emacs-lisp
(defun azos/bat/get-stats () "Gets battery statistics. First value returned
is battery percentage, second one is t if charging"
(let* ((commandout (string-clean-whitespace (shell-command-to-string
"upower -i /org/freedesktop/UPower/devices/DisplayDevice"))))
(list
(string-to-number (progn
(string-match "\\(?:percentage\\:\s+\\)\\([0-9]+\\)" commandout)
(match-string 1 commandout)))
(progn
(string-match "\\(?:state\\:\s+\\)\\([^\s]+\\)" commandout)
(match-string 1 commandout)))
))
(defvar azos/bat/status-string nil "Holds battery string")
(defun azos/bat/set-status-string () "Sets battery-string"
(let* ((bat-stats (azos/bat/get-stats))
(bat-charge-state (nth 1 bat-stats))
(bat-percentage-number
(if (string= bat-charge-state "fully-charged") 100
(nth 0 bat-stats)))
(bat-color (if (<= bat-percentage-number 10) "red3"
(if (<= bat-percentage-number 20) "DarkOrange"
"DarkSlateGrey")))
(bat-weight (if (<= bat-percentage-number 20) 'bold 'normal))
(bat-charge-symbol (if (string= bat-charge-state "charging") ""
(if (string= bat-charge-state "fully-charged") "" ""))))
(setq azos/bat/status-string
(concat
"" bat-charge-symbol " "
(propertize (format "%3d" bat-percentage-number)
'face (list :foreground bat-color
:box (list :color "DarkSlateGrey")))))))
(defun azos/bat/get-status-string () "Get battery string"
(if azos/bat/status-string azos/bat/status-string ""))
(defun azos/bat/enable-tab-display ()
"Enables battery display in tab bar"
(progn
(cl-pushnew 'azos/bat/get-status-string azos/tab-bar/right-group)
(cl-pushnew 'azos/bat/set-status-string azos/tab-bar/right-update-group)
))
#+end_src
**** Network status in tab bar
Code to check for internet connection:
https://emacs.stackexchange.com/questions/7653/elisp-code-to-check-for-internet-connection
#+begin_src emacs-lisp
(defvar azos/network/status-string nil "Holds network status string")
(defun azos/network/get-status-string () "Gets the network status string"
(if azos/network/status-string azos/network/status-string ""))
(defun azos/network/set-status-string-sentinel (process event)
"Sets the network string based on proc run"
(setq azos/network/status-string
(concat
""
(if (= 0 (process-exit-status process))
(propertize "" 'face
(list :foreground "green3"
:background "LightYellow3"
:box (list :color "DarkSlateGrey")))
(propertize "X" 'face
(list :foreground "red3"
:background "LightYellow3"
:box (list :color "DarkSlateGrey")))))))
(defun azos/network/start-test-proc () "Tests whether internet"
(interactive)
(set-process-sentinel
(start-process "wget" nil "wget" "--spider" "--timeout=1"
"www.google.com") 'azos/network/set-status-string-sentinel))
(defun azos/network/enable-tab-display ()
"Enables network display in tab bar"
(progn
(cl-pushnew 'azos/network/get-status-string
azos/tab-bar/right-group)
(cl-pushnew 'azos/network/start-test-proc
azos/tab-bar/right-update-group)
))
#+end_src
*** Easy Prompt
#+begin_src emacs-lisp
@@ -898,9 +1112,216 @@ Taken from: https://github.com/emacs-evil/evil/issues/1288
:around #'azos/org/evil-org-insert-state-in-edit-buffer)
#+end_src
*** Fonts
Fonts
#+begin_src emacs-lisp
;; (set-face-attribute 'org-document-title nil :height 200 :underline t)
#+end_src
*** Inline images
#+begin_src emacs-lisp
(setq org-startup-with-inline-images t)
(defun azos/org/shk-fix-inline-images ()
(when org-inline-image-overlays
(org-redisplay-inline-images)))
(with-eval-after-load 'org
(add-hook 'org-babel-after-execute-hook 'azos/org/shk-fix-inline-images))
#+end_src
*** Snippets
Want to create snippets for latex insertion.
There is one template for inline and one template for standalone latex snippets.
Each template is defind by two templates. One for other langauges and one for standard
input. This is done to toggle back to the original language once done with the
function toggle-input-method.
#+begin_src emacs-lisp
(defun azos/org/toggle-input-method ()
(if current-input-method (toggle-input-method))
)
;Inline
(add-hook 'org-mode-hook (lambda () (progn
(yas-define-snippets 'org-mode (list (list
nil
"\$$1\$$0"
"ORG_LATEX_INLINE_SNIPPET_ENG"
'(not (eval current-input-method))
nil
nil
nil
"C-l"
nil
nil
)))
(yas-define-snippets 'org-mode (list (list
nil
"\$$1\$$0"
"ORG_LATEX_INLINE_SNIPPET_OTHER_LANG"
'(eval current-input-method)
nil
'((unused (azos/org/toggle-input-method))
(yas-after-exit-snippet-hook 'toggle-input-method))
nil
"C-l"
nil
nil
)))
;Not inline
(yas-define-snippets 'org-mode (list (list
nil
"\$\$$1\$\$$0"
"ORG_LATEX_OUTLINE_SNIPPET_ENG"
'(not (eval current-input-method))
nil
nil
nil
"C-S-l"
nil
nil
)))
(yas-define-snippets 'org-mode (list (list
nil
"\$\$$1\$\$$0"
"ORG_LATEX_OUTLINE_SNIPPET_OTHER_LANG"
'(eval current-input-method)
nil
'((unused (azos/org/toggle-input-method))
(yas-after-exit-snippet-hook 'toggle-input-method))
nil
"C-S-l"
nil
nil
)))
)))
#+end_src
Snippet for src blocks
#+begin_src emacs-lisp
(add-hook 'org-mode-hook (lambda () (progn
(yas-define-snippets 'org-mode (list (list
nil
"#+begin_src $1\n$0\n#+end_src"
"ORG_SRC_BLOCK"
nil
nil
nil
nil
"C-c i b"
nil
nil
)))
(yas-define-snippets 'org-mode (list (list
nil
(concat
"#+begin_export latex\n"
"\\begin{english}\n"
"#+end_export\n"
"#+begin_src $1\n"
"$0\n#+end_src\n"
"#+begin_export latex\n"
"\\end{english}\n"
"#+end_export")
"ORG_SRC_ENGLISH_BLOCK"
nil
nil
nil
nil
"C-c i B"
nil
nil
)))
)))
#+end_src
*** Imenu quirks
#+begin_src emacs-lisp
(add-to-list 'org-show-context-detail '(isearch . tree))
(add-to-list 'org-show-context-detail '(default . tree))
#+end_src
** Ibuffer
#+begin_src emacs-lisp
(evil-collection-ibuffer-setup)
(define-key azos/global-minor-mode/keymap
(kbd "C-x C-b") 'ibuffer)
#+end_src
** Dashboard
#+begin_src emacs-lisp
(setq inhibit-startup-screen t)
(use-package dashboard
:config
(add-hook 'after-init-hook
(lambda () (dashboard-insert-startupify-lists)))
(add-hook 'emacs-startup-hook (lambda ()
(switch-to-buffer dashboard-buffer-name)
(goto-char (point-min))
(redisplay)
(run-hooks 'dashboard-after-initialize-hook)))
(add-to-list 'evil-emacs-state-modes 'dashboard-mode)
(setq dashboard-items '((recents . 5)
(bookmarks . 5)
(projects . 5))
dashboard-center-content t
dashboard-banner-logo-title nil
dashboard-set-init-info nil
dashboard-set-footer nil
dashboard-startup-banner 'ascii
dashboard-banner-ascii "azos"))
#+end_src
** VTerm
#+begin_src emacs-lisp
;; (use-package xterm-color :ensure t)
;; (use-package eterm-256color :ensure t
;; :config
;; (add-hook 'term-mode-hook #'eterm-256color-mode)
;; (add-hook 'vterm-mode-hook #'eterm-256color-mode)
;; )
#+end_src
#+begin_src emacs-lisp
(use-package vterm
:if (member system-type '(gnu gnu/linux))
:config
(add-hook 'vterm-mode-hook
(lambda () (setq-local global-hl-line-mode nil)))
(evil-collection-define-key 'normal 'vterm-mode-map
(kbd "p") 'vterm-yank)
(setq vterm-timer-delay 0.01
vterm-term-environment-variable "xterm-256color"))
#+end_src
** Boomkark
#+begin_src emacs-lisp
(use-package bookmark
:straight
(:type built-in)
:config
(evil-collection-bookmark-setup)
)
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-base)
(add-hook 'after-init-hook (lambda () (require 'azos-emacs-base)))
#+end_src
+31
View File
@@ -110,6 +110,12 @@ Integration with flycheck
(kbd "r p") 'run-python)
#+end_src
*** org src block
#+begin_src emacs-lisp
(setq org-babel-python-command "python3")
#+end_src
** Rust
#+begin_src emacs-lisp
@@ -127,8 +133,33 @@ Integration with flycheck
(define-key ein:notebook-mode-map (kbd "C-c C-k") nil)))))
#+end_src
** Python
*** Python version for ORG
#+begin_src emacs-lisp
(require 'ob)
(setq org-babel-python-command "python3")
#+end_src
* ORG
** Async blocks
#+begin_src emacs-lisp
(use-package ob-async
:config
;Setting command of async blocks to Python3
(add-hook 'ob-async-pre-execute-src-block-hook
'(lambda ()
(setq org-babel-python-command "python3")
))
)
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-dev)
(add-hook 'after-init-hook (lambda () (require 'azos-emacs-dev)))
#+end_src
+71 -6
View File
@@ -28,7 +28,7 @@ Binding to startup is 'C-c /'
** Graphviz
#+begin_src emacs-lisp
(use-package graphviz-dot)
(use-package graphviz-dot-mode)
#+end_src
** Markdown
@@ -86,20 +86,15 @@ Creating classes
(defvar anerenv/latex-class-common-header
"[DEFAULT-PACKAGES]
\\usepackage{polyglossia}
\\usepackage{tabularx}
\\usepackage[cache=false]{minted}
\\usepackage{xcolor}
\\usepackage{indentfirst}
\\usepackage{amsfonts}
\\usepackage{transparent}
\\usepackage{amsmath}
\\usepackage{braket}
\\usepackage{dsfont}
\\definecolor{codebg}{rgb}{0.95,0.95,0.95}
\\setdefaultlanguage{english}
\\setlength{\\parindent}{0in}
\\DeclareMathOperator*{\\argmax}{arg\\,max}
\\DeclareMathOperator*{\\argmin}{arg\\,min}
\\newfontfamily\\hebrewfont{LiberationSans}[Script=Hebrew]
@@ -174,8 +169,78 @@ Comments:
(format-time-string "-%Y-%m-%d-%H%M%S") ".docx")))
#+end_src
** Latex previews
We don't want to create ltximg directories all over the place.
Let's store all ltximg previews in tmp directory.
Latex scaling from
https://karthinks.com/software/scaling-latex-previews-in-emacs/
#+begin_src emacs-lisp
(setq org-format-latex-header
"\\documentclass{article}
\\usepackage[usenames]{color}
[PACKAGES]
[DEFAULT-PACKAGES]
\\pagestyle{empty} % do not remove
% The settings below are copied from fullpage.sty
\\setlength{\\textwidth}{\\paperwidth}
\\addtolength{\\textwidth}{-3cm}
\\setlength{\\oddsidemargin}{1.5cm}
\\addtolength{\\oddsidemargin}{-2.54cm}
\\setlength{\\evensidemargin}{\\oddsidemargin}
\\setlength{\\textheight}{\\paperheight}
\\addtolength{\\textheight}{-\\headheight}
\\addtolength{\\textheight}{-\\headsep}
\\addtolength{\\textheight}{-\\footskip}
\\addtolength{\\textheight}{-3cm}
\\setlength{\\topmargin}{1.5cm}
\\addtolength{\\topmargin}{-2.54cm}
\\DeclareMathOperator*{\\argmax}{arg\\,max}
\\DeclareMathOperator*{\\argmin}{arg\\,min}"
)
(setq org-preview-latex-image-directory (concat user-emacs-directory "ltximg/"))
(setq org-latex-create-formula-image-program 'dvisvgm)
(setq org-format-latex-options (plist-put org-format-latex-options :scale 1))
#+end_src
** Presentation
#+begin_src emacs-lisp
(use-package org-present
:config
(add-hook 'org-present-mode-hook (lambda ()
(evil-emacs-state)
(blink-cursor-mode 0)
(org-present-big)
(org-display-inline-images)
(org-present-read-only)
(setq-local global-hl-line-mode nil)
(org-present-hide-cursor)
(olivetti-mode 1)
(display-line-numbers-mode 0)))
(add-hook 'org-present-mode-quit-hook (lambda ()
(org-present-small)
(blink-cursor-mode 1)
(org-remove-inline-images)
(org-present-show-cursor)
(org-present-read-write)
(evil-normal-state)
(setq-local global-hl-line-mode 1)
(olivetti-mode 0)
(display-line-numbers-mode 1)))
)
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-editor)
(add-hook 'after-init-hook (lambda () (require 'azos-emacs-editor)))
#+end_src
+376
View File
@@ -0,0 +1,376 @@
#+title: Aner's Emacs EXWM Configuration
#+property: header-args :results silent
* Base setup
** Require
#+begin_src emacs-lisp
(require 'azos-emacs-station)
(require 'azos-emacs-base)
#+end_src
* EXWM
We execute the following code only if started with EXWM argument
** EXWM Setup
#+begin_src emacs-lisp
(defvar azos/exwm/load-hook nil "Load EXWM hook")
(defun azos/exwm/load-exwm (switch) "Loads EXWM"
(use-package exwm
:ensure t
:config
(require 'exwm)
(require 'exwm-randr)
;Workspaces
(setq exwm-workspace-number 4
exwm-layout-show-all-buffers t
exwm-workspace-show-all-buffers t)
;System tray
(require 'exwm-systemtray)
(setq exwm-systemtray-background-color "LightYellow3")
(exwm-systemtray-enable)
;In EXWM mode, no evil
(add-to-list 'evil-emacs-state-modes 'exwm-mode)
(run-hooks 'azos/exwm/load-hook)
;Enable
(exwm-randr-enable)
(exwm-enable)
))
#+end_src
** Smart buffer naming
#+begin_src emacs-lisp
(add-hook 'azos/exwm/load-hook (lambda () (progn
(add-hook 'exwm-update-class-hook
(lambda ()
(unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(string-prefix-p "qute" exwm-instance-name)
(exwm-workspace-rename-buffer exwm-class-name))))
(add-hook 'exwm-update-title-hook
(lambda ()
(when (or (not exwm-instance-name)
(string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string-prefix-p "qute" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-title))))
(add-hook 'exwm-update-class-hook
(lambda ()
(when (or (not exwm-instance-name)
(string-prefix-p "mpv" exwm-class-name))
(exwm-workspace-rename-buffer (concat "mpv | " exwm-title)))))
)))
#+end_src
** Basic keybindings
Global keybindings can be defined with `exwm-input-global-keys'.
Here are a few examples:
#+begin_src emacs-lisp
(add-hook 'azos/exwm/load-hook (lambda ()
(setq exwm-input-global-keys
`(
;; Bind "s-<f2>" to "slock", a simple X display locker.
([s-f2] . (lambda ()
(interactive)
(start-process "" nil "/usr/bin/slock")))
([s-<tab>] . persp-switch)
;; Bind "s-r" to exit char-mode and fullscreen mode.
([?\s-r] . exwm-reset)
;; Bind "s-w" to switch workspace interactively.
([?\s-w] . exwm-workspace-switch)
;; Bind "s-0" to "s-9" to switch to a workspace by its index.
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))
;; Bind "s-&" to launch applications ('M-&' also works if the output
;; buffer does not bother you).
([?\s-&] . (lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
))))
(defun azos/exwm/take-screenshot ()
(interactive)
(shell-command "flameshot gui")
)
(defun azos/exwm/start-qutebrowser ()
(interactive)
(start-process "qutebrowser" nil "qutebrowser"))
(add-hook 'azos/exwm/load-hook (lambda () (progn
(define-key azos/global-minor-mode/open-keymap
(kbd "q") 'azos/exwm/start-qutebrowser)
(define-key azos/global-minor-mode/keymap
(kbd "<print>") 'azos/exwm/take-screenshot))))
#+end_src
** Better modeline
This currently does nothing and I am not sure why.
#+begin_src emacs-lisp
(defvar azos/exwm/modeline-hash-table (make-hash-table)
"Table to store relative face change cookies in")
(defface azos/exwm/modeline-remap-style
(list (list t (list :background azos/evil-color-insert)))
"Make the backgrounds pop to green")
(defun azos/exwm/input-mode-modeline () "Changes modeline based on input mode"
(let ((currbuff (current-buffer)))
(if (eq exwm--input-mode 'char-mode)
;;line
(let ((remap-cookie (gethash currbuff
azos/exwm/modeline-hash-table)))
(if remap-cookie
(progn
(face-remap-remove-relative remap-cookie)
(remhash currbuff
azos/exwm/modeline-hash-table))))
;;char
(puthash
currbuff
(face-remap-add-relative 'mode-line
'azos/exwm/modeline-remap-style)
azos/exwm/modeline-hash-table)
)))
(add-hook 'exwm-input-input-mode-change-hook 'azos/exwm/input-mode-modeline)
;; (set-face-attribute 'mode-line nil :box nil :background "AliceBlue")
;; (set-face-attribute 'mode-line-inactive nil :box nil :background "LightYellow3")
#+end_src
** RANDR screen settings
Enabling randr. Automatic mapping of randr screens to workspaces.
#+begin_src emacs-lisp
(defun azos/exwm/get-monitor-list ()
(mapcar (lambda (x) (match-string (string-match "^[A-Za-z]+-*[0-9]+" x) x))
(azos/re-seq "^[A-Za-z]+-*[0-9]+ connected"
(shell-command-to-string "xrandr"))))
(defun azos/exwm/add-indexes (list)
(azos/exwm/add-indexes-i list 1)
)
(defun azos/exwm/add-indexes-i (list i)
(if list
(cons i (cons (car list) (azos/exwm/add-indexes-i (cdr list) (+ i 1))))
nil))
(defun azos/exwm/update-randr-monitor-plist ()
(interactive)
(progn
(start-process
"xlayoutdisplay" nil "xlayoutdisplay")
(setq exwm-randr-workspace-monitor-plist
(azos/exwm/add-indexes (azos/exwm/get-monitor-list)))
(exwm-randr-refresh))
)
(add-hook 'azos/exwm/load-hook (lambda () (progn
(add-hook 'exwm-randr-screen-change-hook
'azos/exwm/update-randr-monitor-plist)
(define-key azos/global-minor-mode/keymap
(kbd "s-x") 'azos/exwm/update-randr-monitor-plist))))
#+end_src
** Prefix keys
Sending simulated keys to X windows
#+begin_src emacs-lisp
(add-hook 'azos/exwm/load-hook (lambda () (progn
(setq exwm-input-prefix-keys
'(?\C-x ?\C-u ?\C-h ?\M-x ?\M-& ?\M-: ?\s-d
?\s-m ?\s-r ?\s-s ?\s-q ?\H-l ?\C-w)))))
#+end_src
** Desktop environment
#+begin_src emacs-lisp
(use-package desktop-environment :after exwm)
#+end_src
** Bluetooth
#+begin_src emacs-lisp
(use-package bluetooth :after exwm)
#+end_src
** Pulse
#+begin_src emacs-lisp
(use-package pulseaudio-control :after exwm)
#+end_src
** TODO Dunst
Used to have to run a service 'dunst'. Don't do that now, handled by OS.
** TODO Flameshot
Also Flameshot
** Media keys
https://gist.github.com/ajyoon/5323b999a01dce8db2d4456da1740fe3
#+begin_src emacs-lisp
(add-hook 'azos/exwm/load-hook (lambda () (progn
(dolist (k '(XF86AudioLowerVolume
XF86AudioRaiseVolume
XF86AudioPlay
XF86AudioStop
XF86AudioPrev
XF86AudioNext))
(push k exwm-input-prefix-keys))
(exwm-input-set-key
(kbd "<XF86AudioRaiseVolume>")
(lambda ()
(interactive) (start-process
"pactl" nil "pactl" "set-sink-volume" "0" "+5%")))
(exwm-input-set-key
(kbd "<XF86AudioLowerVolume>")
(lambda ()
(interactive) (start-process
"pactl" nil "pactl" "set-sink-volume" "0" "-5%")))
(exwm-input-set-key
(kbd "<XF86AudioMute>")
(lambda ()
(interactive) (start-process
"pactl" nil "pactl" "set-sink-mute" "0" "toggle")))
(exwm-input-set-key
(kbd "<XF86AudioPlay>")
'desktop-environment-toggle-music)
(exwm-input-set-key
(kbd "<XF86AudioNext>")
'desktop-environment-music-next)
(exwm-input-set-key
(kbd "<XF86AudioPrev>")
'desktop-environment-music-previous)
(exwm-input-set-key
(kbd "<XF86AudioStop>")
'desktop-environment-music-stop)
(exwm-input-set-key
(kbd "<XF86AudioPause>")
'desktop-environment-toggle-music)
(exwm-input-set-key
(kbd "<XF86MonBrightnessUp>")
(lambda ()
(interactive) (start-process
"light" nil "light" "-A" "5")))
(exwm-input-set-key
(kbd "<XF86MonBrightnessDown>")
(lambda ()
(interactive) (start-process
"light" nil "light" "-U" "5")))))
#+end_src
In the event =xbacklight= doesn't work, the following command can be run:
#+begin_example
xrandr --output eDP1 --brightness 0.5
#+end_example
** TODO Input languages
#+begin_src emacs-lisp
(defun azos/exwm/enable-heb ()
(interactive)
(start-process-shell-command "heb" nil
"setxkbmap -layout us,il && setxkbmap -option 'grp:alt_shift_toggle'"))
())
(add-hook 'azos/exwm/load-hook 'azos/exwm/enable-heb)
#+end_src
I think this can be handled by OS
** Dedicated processes
We'd want to be able to quickly map processes (Spotify, etc.) to
keybindings, and have dedicated buffers for them (so they don't reopen).
We first define variables to be used later, and a function that checks, for each
new process, should it be displayed in a new buffer/tab.
#+begin_src emacs-lisp
(defvar azos/exwm/startproc-regex-buffname-list nil
"Match between buffer and tab.")
(defun azos/exwm/startproc-check-for-buff-entry ()
"On new buffer, check if requested to display differently"
(let ((entry (cdr (car (seq-filter
(lambda (e) (string-match (car e) (buffer-name)))
azos/exwm/startproc-regex-buffname-list
)))))
(if entry
(let ((rn (nth 0 entry)) (tn (nth 1 entry)) (buff (current-buffer)))
;; Too much complication for renaming
;; (if requested-name (rename-buffer requested-name))
(progn
(if tn (tab-bar-switch-to-tab tn))
(switch-to-buffer buff)
)))))
(add-hook 'exwm-manage-finish-hook 'azos/exwm/startproc-check-for-buff-entry)
#+end_src
#+begin_src emacs-lisp
(defun azos/exwm/start-proc-dedicated
(name tab-name procregex proc &rest args)
(let ((buff (car (seq-filter (lambda (b
)
(string-match procregex (buffer-name b)))
(buffer-list)))))
(if buff
;; Found buffer, display
(progn
(if tab-name (tab-bar-switch-to-tab tab-name))
(switch-to-buffer buff)
)
;;No known buffer, add entry to alist
(let ((new-entry `(,procregex ,tab-name ,name))) (progn
(add-to-list 'azos/exwm/startproc-regex-buffname-list
new-entry)
(apply 'start-process name nil proc
args))))))
#+end_src
** EXWM Ending
End the execute only if EXWM block.
#+begin_src emacs-lisp
(add-to-list 'command-switch-alist '("--start-exwm" . azos/exwm/load-exwm))
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-exwm)
(add-hook 'after-init-hook (lambda () (require 'azos-emacs-exwm)))
#+end_src
+300
View File
@@ -0,0 +1,300 @@
#+title: Aner's Emacs Station Configuration
#+property: header-args :results silent
* Base setup
** Require
#+begin_src emacs-lisp
(require 'azos-emacs-base)
#+end_src
* Major modes
** Mail
*** General instructions
Due to the fact that setting up email in general is complicated, I'll recap the process here.
Before ANYTHING, setup pass.
https://wiki.archlinux.org/title/Pass
Initialize password
Then for gmail, used
#+begin_src bash :results none :exports code
pass init <ID>
pass insert gmail.com/<username>
#+end_src
It prompted for password, I put it in.
Then setup mbsync properly. The ansible files already take care of that.
Then we setup ~/.mbsyncrc. This file is important and is not linked to repository for security reasons.
https://wiki.archlinux.org/title/isync
Wrote mbsyncrc
Created all directories
Went into gmail settings to allow less secure things.
https://notmuchmail.org/getting-started/
We then RUN notmuch, and notmuch setup for prompt.
Adding emails can be done with notmuch new
*** Config
#+begin_src emacs-lisp
;; (defvar azos/mail/sync-list nil "List of functions with args to sync mail")
;; (defun azos/mail/lieer-sync-func-str (maildir)
;; (concat "cd " maildir " && gmi sync -s"))
;; (defun azos/mail/mbsync-func-str ()
;; "mbsync -a")
;; (defun azos/mail/pre-sync-func-str ()
;; (concat (mapconcat 'eval (mapcar 'apply azos/mail/sync-list) " &\n")
;; "\nwait\n"))
;; (defun azos/mail/sync-notify () (interactive)
;; (let ((command (concat (azos/mail/pre-sync-func-str)
;; "{ if [[ $(notmuch new | grep \"No new mail\") ]]; "
;; "then dunstify -u low \"Synced mail\" ; "
;; "else dunstify \"New mail!\" ; fi ; } || "
;; "dunstify -u critical \"Error syncing mail\"")))
;; (start-process-shell-command "mailsync" "*mailsync*" command)))
;; (defun azos/mail/sync-n-notify ()
;; (let ((command (concat (azos/mail/pre-sync-func-str)
;; "{ if [[ $(notmuch new | grep \"No new mail\") ]]; "
;; "then : ; "
;; "else dunstify \"New mail!\" ; fi ; } || "
;; "dunstify -u critical \"Error syncing mail\"")))
;; (start-process-shell-command "mailsync" "*mailsync*" command)))
;; (defun azos/mail/set-sync-list (sync-list)
;; "Set list of mails and start timer"
;; (progn
;; (setq azos/mail/sync-list sync-list)))
;; ; (azos/run-timer 'mail-sync 'azos/mail/sync-n-notify (* 60 10))))
(use-package notmuch
:straight (:type built-in)
:init
(setq-default
notmuch-hello-sections
'(notmuch-hello-insert-saved-searches
notmuch-hello-insert-alltags)
notmuch-always-prompt-for-sender t
message-sendmail-envelope-from 'header)
:config
(evil-collection-notmuch-setup)
(add-hook 'notmuch-show-mode 'azos/default-variable-pitch)
(setq send-mail-function 'sendmail-send-it
notmuch-search-oldest-first nil
message-cite-style message-cite-style-gmail
message-citation-line-function
'message-insert-formatted-citation-line)
(defun azos/notmuch-archive () "Archive a message" (interactive)
(progn
(evil-collection-notmuch-toggle-tag "arx" "search" 'ignore)
(evil-collection-notmuch-toggle-tag "inbox" "search"
'notmuch-search-next-thread)
))
(defun azos/notmuch-keep () "Mark important message for keeps" (interactive)
(progn
(evil-collection-notmuch-toggle-tag "keep" "search"
'notmuch-search-next-thread)))
(defun azos/notmuch-delete-gmail () "Delete a message, no inbox"
(interactive)
(progn
(evil-collection-notmuch-toggle-tag "deleted" "search" 'ignore)
(evil-collection-notmuch-toggle-tag "trash" "search" 'ignore)
(evil-collection-notmuch-toggle-tag "inbox" "search"
'notmuch-search-next-thread)))
(defun azos/notmuch-toggle-inbox () "Toggles inbox tag" (interactive)
(evil-collection-notmuch-toggle-tag "inbox" "search" 'ignore))
(dolist (state '(normal visual))
(evil-collection-define-key state 'notmuch-search-mode-map
"d" 'azos/notmuch-delete-gmail
"I" 'azos/notmuch-toggle-inbox
"D" 'evil-collection-notmuch-search-toggle-delete
"A" 'azos/notmuch-archive
"K" 'azos/notmuch-keep))
(evil-collection-define-key 'normal 'notmuch-show-mode-map
(kbd "M-j") nil
(kbd "K") nil
(kbd "M-k") nil)
:bind
(:map azos/global-minor-mode/open-keymap
("m" . notmuch))
)
#+end_src
Run this command to make sendmail use the right thing
#+begin_src bash :results none :exports code
sudo ln -s /usr/bin/msmtp /usr/sbin/sendmail
#+end_src
Then we go to
https://wiki.archlinux.org/title/isync
We will do this manually.
*** Signatures
Taken from
https://emacs.stackexchange.com/questions/27759/do-not-automatically-sign-emails-directed-to-mailing-lists-and-such
Thanks to Dan of Stackoverflow.
#+begin_src emacs-lisp
(defvar azos/mail/blacklist-addresses nil
"List of email addresses (as strings) to blacklist for
`mml-secure-message-sign'.")
(defun azos/mail/secure-sign-maybe ()
"Use `mml-secure-message-sign' unless the addressee is in the
`azos/mail/blacklist-addresses'."
(let ((addresses (mapcar (lambda (address)
(when (string-match
"\\(<?\\)\\([^@< ]+@[^@> ]+\\)\\(>?\\)"
address)
(match-string 2 address)))
;; (split-string (message-field-value "To")
;; "," t "[[:blank:]]+"))))
(split-string (concat (message-field-value "To")
", "
(message-field-value "Cc"))
"," t "[[:blank:]]+"))))
;; skip secure signing when an address is blacklisted
(unless (delq nil (mapcar (lambda (address)
(car (member address azos/mail/blacklist-addresses)))
addresses))
(mml-secure-message-sign))))
#+end_src
** Elfeed
MPV from https://www.reddit.com/r/emacs/comments/7usz5q/youtube_subscriptions_using_elfeed_mpv_no_browser/
https://medium.com/emacs/using-elfeed-to-view-videos-6dfc798e51e6
#+begin_src emacs-lisp
(use-package elfeed
:init
(defun azos/elfeed/v-mpv (url)
"Watch a video from URL in MPV"
(start-process "mpv" nil "mpv" url))
(defun azos/elfeed/view-mpv (&optional use-generic-p)
"Youtube-feed link"
(interactive "P")
(let ((entries (elfeed-search-selected)))
(cl-loop for entry in entries
do (elfeed-untag entry 'unread)
when (elfeed-entry-link entry)
do (azos/elfeed/v-mpv it))
(mapc #'elfeed-search-update-entry entries)))
(defun slurp (f)
(with-temp-buffer
(insert-file-contents f)
(buffer-substring-no-properties
(point-min)
(point-max))))
(setq-default elfeed-search-filter "@3-days-ago")
:config
(evil-collection-elfeed-setup)
)
#+end_src
*** Elfeed tube
https://github.com/karthink/elfeed-tube
#+begin_src emacs-lisp
(use-package elfeed-tube
:ensure t ;; or :straight t
:after elfeed
:demand t
:config
;; (setq elfeed-tube-auto-save-p nil) ; default value
;; (setq elfeed-tube-auto-fetch-p t) ; default value
(elfeed-tube-setup)
:bind (:map elfeed-show-mode-map
("F" . elfeed-tube-fetch)
([remap save-buffer] . elfeed-tube-save)
:map elfeed-search-mode-map
("F" . elfeed-tube-fetch)
([remap save-buffer] . elfeed-tube-save)))
(use-package elfeed-tube-mpv
:ensure t ;; or :straight t
:after elfeed-tube
:bind (:map elfeed-show-mode-map
("C-c C-f" . elfeed-tube-mpv-follow-mode)
("C-c C-w" . elfeed-tube-mpv-where)))
#+end_src
** Pass
#+begin_src emacs-lisp
(use-package pass
:bind
(:map azos/global-minor-mode/open-keymap
("p" . 'password-store-copy)))
#+end_src
** Calendar
#+begin_src emacs-lisp
(evil-collection-calendar-setup)
#+end_src
** OpenSCAD
#+begin_src emacs-lisp
(use-package scad-mode)
; Disabling for now
;; (use-package scad-preview
;; :straight '(
;; scad-preview
;; :type git
;; :host github
;; :repo "zk-phi/scad-preview"))
#+end_src
** Kubernetes
#+begin_src emacs-lisp
(use-package kubernetes
:ensure t
:commands (kubernetes-overview))
#+end_src
* Provide
#+begin_src emacs-lisp
(provide 'azos-emacs-station)
(add-hook 'after-init-hook (lambda () (require 'azos-emacs-station)))
#+end_src