mirror of
https://github.com/SqrtMinusOne/dotfiles.git
synced 2025-12-10 19:23:03 +03:00
feat(desktop): EXWM looks usable
This commit is contained in:
parent
851bb9bc97
commit
92f88b798f
13 changed files with 941 additions and 132 deletions
|
|
@ -21,7 +21,7 @@
|
|||
# Show how many messages are currently hidden (because of geometry).
|
||||
indicate_hidden = yes
|
||||
|
||||
# Shrink window if it's smaller than the width. Will be ignored if
|
||||
# Shrink window if its smaller than the width. Will be ignored if
|
||||
# width is 0.
|
||||
shrink = no
|
||||
|
||||
|
|
|
|||
|
|
@ -1,49 +1,14 @@
|
|||
(specifications->manifest
|
||||
'(
|
||||
"xev"
|
||||
"gparted"
|
||||
"gnome-disk-utility"
|
||||
"anydesk"
|
||||
"polkit-gnome"
|
||||
"fontconfig"
|
||||
"qbittorrent"
|
||||
"gnome-font-viewer"
|
||||
"xdg-utils"
|
||||
"telegram-desktop"
|
||||
"keepassxc"
|
||||
"thunar"
|
||||
"xmodmap"
|
||||
"copyq"
|
||||
"feh"
|
||||
"network-manager-applet"
|
||||
"pavucontrol"
|
||||
"ponymix"
|
||||
"light"
|
||||
"arandr"
|
||||
"xprop"
|
||||
"megacmd-1.4"
|
||||
"activitywatch-bin"
|
||||
"xdg-desktop-portal"
|
||||
"flatpak"
|
||||
"zathura-djvu"
|
||||
"zathura-pdf-poppler"
|
||||
"zathura-ps"
|
||||
"zathura"
|
||||
"picom"
|
||||
"keynav"
|
||||
"libnotify"
|
||||
"dunst"
|
||||
"flameshot"
|
||||
"xset"
|
||||
"rofi-pass"
|
||||
"rofimoji"
|
||||
"rofi"
|
||||
"sunwait"
|
||||
"dateutils"
|
||||
"jq"
|
||||
"curl"
|
||||
"bind:utils"
|
||||
"polybar"
|
||||
"python-i3-balance-workspace"
|
||||
"rust-i3-switch-tabs"
|
||||
"i3-gaps"
|
||||
|
|
|
|||
|
|
@ -5,4 +5,8 @@
|
|||
"ffmpeg"
|
||||
"krita"
|
||||
"gimp"
|
||||
"libreoffice"))
|
||||
"libreoffice"
|
||||
"zathura-djvu"
|
||||
"zathura-pdf-mupdf"
|
||||
"zathura-ps"
|
||||
"zathura"))
|
||||
|
|
|
|||
|
|
@ -57,6 +57,13 @@
|
|||
#:start (make-forkexec-constructor '("xsettingsd"))
|
||||
#:stop (make-kill-destructor)))
|
||||
|
||||
(define nm-applet
|
||||
(make <service>
|
||||
#:provides '(nm-applet)
|
||||
#:respawn? #t
|
||||
#:start (make-forkexec-constructor '("nm-applet"))
|
||||
#:stop (make-kill-destructor)))
|
||||
|
||||
(define discord-rich-presence
|
||||
(make <service>
|
||||
#:provides '(discord-rich-presence)
|
||||
|
|
@ -67,7 +74,7 @@
|
|||
(make <service>
|
||||
#:provides '(polkit-gnome)
|
||||
#:respawn? #t
|
||||
#:start (make-forkexec-constructor '("/home/pavel/.guix-extra-profiles/desktop/desktop/libexec/polkit-gnome-authentication-agent-1"))
|
||||
#:start (make-forkexec-constructor '("/home/pavel/.guix-extra-profiles/desktop-misc/desktop-misc/libexec/polkit-gnome-authentication-agent-1"))
|
||||
#:stop (make-kill-destructor)))
|
||||
|
||||
(define xmodmap
|
||||
|
|
@ -103,8 +110,9 @@
|
|||
polkit-gnome
|
||||
vpn
|
||||
davmail
|
||||
xmodmap)
|
||||
xmodmap
|
||||
nm-applet)
|
||||
|
||||
(action 'shepherd 'daemonize)
|
||||
|
||||
(for-each start '(mpd mpd-watcher mcron aw-server aw-watcher-afk aw-watcher-window pulseeffects xsettingsd discord-rich-presence polkit-gnome davmail xmodmap))
|
||||
(for-each start '(mpd mpd-watcher mcron aw-server aw-watcher-afk aw-watcher-window pulseeffects xsettingsd discord-rich-presence polkit-gnome davmail xmodmap nm-applet))
|
||||
|
|
|
|||
301
.emacs.d/desktop.el
Normal file
301
.emacs.d/desktop.el
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
(defun my/exwm-run-polybar ()
|
||||
(call-process "~/bin/polybar.sh"))
|
||||
|
||||
(defun my/exwm-set-wallpaper ()
|
||||
(call-process-shell-command "feh --bg-fill ~/Pictures/wallpaper.jpg"))
|
||||
|
||||
(defun my/exwm-run-shepherd ()
|
||||
(when (string-empty-p (shell-command-to-string "pgrep -u pavel shepherd"))
|
||||
(call-process "shepherd")))
|
||||
|
||||
(defun my/exwm-direction-exists-p (dir)
|
||||
(cl-some (lambda (dir)
|
||||
(let ((win (windmove-find-other-window dir)))
|
||||
(and win (not (window-minibuffer-p win)))))
|
||||
(pcase dir
|
||||
('width '(left right))
|
||||
('height '(up down)))))
|
||||
|
||||
(defun my/exwm-move-window (dir)
|
||||
(let ((other-window (windmove-find-other-window dir))
|
||||
(other-direction (my/exwm-direction-exists-p
|
||||
(pcase dir
|
||||
('up 'width)
|
||||
('down 'width)
|
||||
('left 'height)
|
||||
('right 'height)))))
|
||||
(cond
|
||||
((and other-window (not (window-minibuffer-p other-window)))
|
||||
(window-swap-states (selected-window) other-window))
|
||||
(other-direction
|
||||
(evil-move-window dir)))))
|
||||
|
||||
(use-package transient
|
||||
:straight t)
|
||||
|
||||
(setq my/exwm-resize-value 5)
|
||||
|
||||
(defun my/exwm-resize-window (dir kind &optional value)
|
||||
(unless value
|
||||
(setq value my/exwm-resize-value))
|
||||
(pcase kind
|
||||
('shrink
|
||||
(pcase dir
|
||||
('width
|
||||
(evil-window-decrease-width value))
|
||||
('height
|
||||
(evil-window-decrease-height value))))
|
||||
('grow
|
||||
(pcase dir
|
||||
('width
|
||||
(evil-window-increase-width value))
|
||||
('height
|
||||
(evil-window-increase-height value))))))
|
||||
|
||||
(defhydra my/exwm-resize-hydra (:color pink :hint nil :foreign-keys run)
|
||||
"
|
||||
^Resize^
|
||||
_l_: Increase width _h_: Decrease width _j_: Increase height _k_: Decrease height
|
||||
|
||||
_=_: Balance "
|
||||
("h" (lambda () (interactive) (my/exwm-resize-window 'width 'shrink)))
|
||||
("j" (lambda () (interactive) (my/exwm-resize-window 'height 'grow)))
|
||||
("k" (lambda () (interactive) (my/exwm-resize-window 'height 'shrink)))
|
||||
("l" (lambda () (interactive) (my/exwm-resize-window 'width 'grow)))
|
||||
("=" balance-windows)
|
||||
("q" nil "quit" :color blue))
|
||||
|
||||
(defun my/run-in-background (command)
|
||||
(let ((command-parts (split-string command "[ ]+")))
|
||||
(apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))
|
||||
|
||||
(transient-define-prefix my/exwm-apps ()
|
||||
["Apps"
|
||||
("t" "Termnial (Alacritty)" (lambda () (interactive) (my/run-in-background "alacritty")))
|
||||
("b" "Browser (Firefox)" (lambda () (interactive) (my/run-in-background "firefox")))
|
||||
("v" "VK" (lambda () (interactive) (my/run-in-background "vk")))
|
||||
("s" "Slack" (lambda () (interactive) (my/run-in-background "slack-wrapper")))
|
||||
("d" "Discord" (lambda () (interactive) (my/run-in-background "flatpak run com.discordapp.Discord")))
|
||||
("q" "Quit" transient-quit-one)])
|
||||
|
||||
(defun my/exwm-workspace-switch-monitor ()
|
||||
(interactive)
|
||||
(if (plist-get exwm-randr-workspace-monitor-plist exwm-workspace-current-index)
|
||||
(setq exwm-randr-workspace-monitor-plist
|
||||
(map-delete exwm-randr-workspace-monitor-plist exwm-workspace-current-index))
|
||||
(setq exwm-randr-workspace-monitor-plist
|
||||
(plist-put exwm-randr-workspace-monitor-plist
|
||||
exwm-workspace-current-index
|
||||
my/exwm-another-monitor)))
|
||||
(exwm-randr-refresh))
|
||||
|
||||
(defun my/cycle-persp-exwm-buffers (dir)
|
||||
(let* ((current (current-buffer))
|
||||
(ignore-rx (persp--make-ignore-buffer-rx))
|
||||
(exwm-buffers
|
||||
(cl-loop for buf in (persp-current-buffers)
|
||||
if (and (buffer-live-p buf)
|
||||
(eq 'exwm-mode (buffer-local-value 'major-mode buf))
|
||||
(not (string-match-p ignore-rx (buffer-name buf))))
|
||||
collect buf))
|
||||
(current-pos (or (cl-position current exwm-buffers) -1)))
|
||||
(if (seq-empty-p exwm-buffers)
|
||||
(message "No EXWM buffers!")
|
||||
(let* ((next-pos (% (+ current-pos (length exwm-buffers)
|
||||
(if (eq dir 'forward) 1 -1))
|
||||
(length exwm-buffers)))
|
||||
(next-buffer (nth next-pos exwm-buffers)))
|
||||
(switch-to-buffer next-buffer)
|
||||
(message
|
||||
"%s"
|
||||
(mapconcat
|
||||
(lambda (buf)
|
||||
(let ((name (string-replace "EXWM :: " "" (buffer-name buf))))
|
||||
(if (eq (current-buffer) buf)
|
||||
(concat
|
||||
"["
|
||||
(propertize name 'face `(foreground-color . ,(doom-color 'yellow)))
|
||||
"]")
|
||||
(format " %s " name))))
|
||||
exwm-buffers
|
||||
" "))))))
|
||||
|
||||
(use-package pinentry
|
||||
:straight t
|
||||
:after (exwm)
|
||||
:config
|
||||
(setenv "GPG_AGENT_INFO" nil) ;; use emacs pinentry
|
||||
(setq auth-source-debug t)
|
||||
|
||||
(setq epg-gpg-program "gpg2") ;; not necessary
|
||||
(require 'epa-file)
|
||||
(epa-file-enable)
|
||||
(setq epa-pinentry-mode 'loopback)
|
||||
(setq epg-pinentry-mode 'loopback)
|
||||
(pinentry-start)
|
||||
(my/run-in-background "gpgconf --reload gpg-agent"))
|
||||
|
||||
(defun my/exwm-init ()
|
||||
(exwm-workspace-switch 1)
|
||||
|
||||
(my/exwm-run-polybar)
|
||||
(my/exwm-set-wallpaper)
|
||||
(my/exwm-run-shepherd)
|
||||
;; (with-eval-after-load 'perspective
|
||||
;; (my/exwm-setup-perspectives))
|
||||
)
|
||||
|
||||
(defun my/exwm-update-class ()
|
||||
(exwm-workspace-rename-buffer (format "EXWM :: %s" exwm-class-name)))
|
||||
|
||||
(use-package exwm
|
||||
:straight t
|
||||
:config
|
||||
(setq exwm-workspace-number 5)
|
||||
(add-hook 'exwm-init-hook #'my/exwm-init)
|
||||
(add-hook 'exwm-update-class-hook #'my/exwm-update-class)
|
||||
|
||||
(require 'exwm-randr)
|
||||
(exwm-randr-enable)
|
||||
(start-process-shell-command "xrandr" nil "~/bin/scripts/screen-layout")
|
||||
(when (string= (system-name) "indigo")
|
||||
(setq my/exwm-another-monitor "DVI-D-0")
|
||||
(setq exwm-randr-workspace-monitor-plist `(2 ,my/exwm-another-monitor 3 ,my/exwm-another-monitor)))
|
||||
|
||||
(setq exwm-workspace-warp-cursor t)
|
||||
(setq mouse-autoselect-window t)
|
||||
(setq focus-follows-mouse t)
|
||||
|
||||
(setq my/exwm-monitor-workspace '())
|
||||
|
||||
(defun my/exwm-get-current-monitor ()
|
||||
(let* ((info (shell-command-to-string "xdotool getmouselocation --shell | head -n 1"))
|
||||
(coord (string-to-number (substring info 2))))
|
||||
(if (> coord 1920) 1 0)))
|
||||
|
||||
(defun my/exwm-update-current-monitor ()
|
||||
(setf (alist-get (my/exwm-get-current-monitor) my/exwm-monitor-workspace)
|
||||
exwm-workspace-current-index))
|
||||
|
||||
(add-hook 'exwm-workspace-switch-hook
|
||||
#'my/exwm-update-current-monitor)
|
||||
(defun my/exwm-switch-to-other-monitor ()
|
||||
(interactive)
|
||||
(let* ((current (my/exwm-get-current-monitor))
|
||||
(other (seq-some
|
||||
(lambda (m)
|
||||
(and (not (= (car m) current)) (cdr m)))
|
||||
my/exwm-monitor-workspace)))
|
||||
(exwm-workspace-switch other)))
|
||||
(setq exwm-input-prefix-keys
|
||||
`(?\C-x
|
||||
?\C-w
|
||||
?\M-x
|
||||
?\M-u))
|
||||
(defmacro my/app-command (command)
|
||||
`(lambda () (interactive) (my/run-in-background ,command)))
|
||||
|
||||
(general-define-key
|
||||
:keymaps '(exwm-mode-map)
|
||||
"C-q" 'exwm-input-send-next-key
|
||||
"<print>" (my/app-command "flameshot gui")
|
||||
"M-x" 'counsel-M-x
|
||||
"M-SPC" (general-key "SPC"))
|
||||
(setq exwm-input-simulation-keys `((,(kbd "M-w") . ,(kbd "C-w"))
|
||||
(,(kbd "M-c") . ,(kbd "C-c"))))
|
||||
(setq exwm-input-global-keys
|
||||
`(
|
||||
;; Reset to line-mode
|
||||
(,(kbd "s-R") . exwm-reset)
|
||||
|
||||
;; Switch windows
|
||||
(,(kbd "s-<left>"). windmove-left)
|
||||
(,(kbd "s-<right>") . windmove-right)
|
||||
(,(kbd "s-<up>") . windmove-up)
|
||||
(,(kbd "s-<down>") . windmove-down)
|
||||
|
||||
(,(kbd "s-h"). windmove-left)
|
||||
(,(kbd "s-l") . windmove-right)
|
||||
(,(kbd "s-k") . windmove-up)
|
||||
(,(kbd "s-j") . windmove-down)
|
||||
|
||||
;; Moving windows
|
||||
(,(kbd "s-H") . (lambda () (interactive) (my/exwm-move-window 'left)))
|
||||
(,(kbd "s-L") . (lambda () (interactive) (my/exwm-move-window 'right)))
|
||||
(,(kbd "s-K") . (lambda () (interactive) (my/exwm-move-window 'up)))
|
||||
(,(kbd "s-J") . (lambda () (interactive) (my/exwm-move-window 'down)))
|
||||
|
||||
;; Fullscreen
|
||||
(,(kbd "s-f") . exwm-layout-toggle-fullscreen)
|
||||
|
||||
;; Quit
|
||||
(,(kbd "s-Q") . evil-quit)
|
||||
|
||||
;; Split windows
|
||||
(,(kbd "s-s") . evil-window-vsplit)
|
||||
(,(kbd "s-v") . evil-window-hsplit)
|
||||
|
||||
;; Switch perspectives
|
||||
(,(kbd "s-,") . persp-prev)
|
||||
(,(kbd "s-.") . persp-next)
|
||||
|
||||
;; Switch buffers
|
||||
(,(kbd "s-e") . persp-ivy-switch-buffer)
|
||||
|
||||
;; Resize windows
|
||||
(,(kbd "s-r") . my/exwm-resize-hydra/body)
|
||||
|
||||
;; Apps & stuff
|
||||
(,(kbd "s-p") . ,(my/app-command "rofi -modi drun,run -show drun"))
|
||||
(,(kbd "s-;") . my/exwm-apps)
|
||||
(,(kbd "s--") . ,(my/app-command "rofi-pass"))
|
||||
(,(kbd "s-=") . ,(my/app-command "rofimoji"))
|
||||
|
||||
;; Basic controls
|
||||
(,(kbd "<XF86AudioRaiseVolume>") . ,(my/app-command "ponymix increase 5 --max-volume 150"))
|
||||
(,(kbd "<XF86AudioLowerVolume>") . ,(my/app-command "ponymix decrease 5 --max-volume 150"))
|
||||
(,(kbd "<XF86AudioMute>") . ,(my/app-command "ponymix toggle"))
|
||||
|
||||
(,(kbd "<XF86AudioPlay>") . ,(my/app-command "mpc toggle"))
|
||||
(,(kbd "<XF86AudioPause>") . ,(my/app-command "mpc pause"))
|
||||
(,(kbd "<print>") . ,(my/app-command "flameshot gui"))
|
||||
|
||||
;; Switch workspace
|
||||
(,(kbd "s-q") . my/exwm-switch-to-other-monitor)
|
||||
(,(kbd "s-w") . exwm-workspace-switch)
|
||||
(,(kbd "s-W") . exwm-workspace-move-window)
|
||||
(,(kbd "s-<tab>") . my/exwm-workspace-switch-monitor)
|
||||
|
||||
;; Cycle EXWM windows in the current perspective
|
||||
(,(kbd "s-[") . (lambda () (interactive) (my/cycle-persp-exwm-buffers 'backward)))
|
||||
(,(kbd "s-]") . (lambda () (interactive) (my/cycle-persp-exwm-buffers 'forward)))
|
||||
(,(kbd "s-o") . ,(my/app-command "rofi -show window"))
|
||||
|
||||
;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9)
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%d" i)) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-switch-create ,i))))
|
||||
(number-sequence 0 9))))
|
||||
(defvar my/exwm-mode-line-info "")
|
||||
|
||||
(add-to-list 'mode-line-misc-info
|
||||
'(:eval my/exwm-mode-line-info))
|
||||
|
||||
(defun my/exwm-mode-line-info-update ()
|
||||
(setq my/exwm-mode-line-info
|
||||
(concat
|
||||
"["
|
||||
(propertize (funcall exwm-workspace-index-map exwm-workspace-current-index)
|
||||
'face
|
||||
`(foreground-color . ,(doom-color 'yellow)))
|
||||
"]"))
|
||||
(force-mode-line-update))
|
||||
|
||||
(add-hook 'exwm-workspace-switch-hook #'my/exwm-mode-line-info-update)
|
||||
|
||||
(set-frame-parameter (selected-frame) 'alpha '(90 . 90))
|
||||
(add-to-list 'default-frame-alist '(alpha . (90 . 90)))
|
||||
|
||||
(exwm-enable))
|
||||
|
|
@ -243,7 +243,12 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|||
:prefix "SPC"
|
||||
:states '(normal motion emacs))
|
||||
|
||||
(general-def :states '(normal motion emacs) "SPC" nil)
|
||||
(general-def :states '(normal motion emacs)
|
||||
"SPC" nil
|
||||
"M-SPC" (general-key "SPC"))
|
||||
|
||||
(general-def :states '(insert)
|
||||
"M-SPC" (general-key "SPC" :state 'normal))
|
||||
|
||||
(my-leader-def "?" 'which-key-show-top-level)
|
||||
(my-leader-def "E" 'eval-expression)
|
||||
|
|
@ -347,7 +352,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|||
(windmove-do-window-select dir))))
|
||||
|
||||
(defun my/emacs-i3-direction-exists-p (dir)
|
||||
(some (lambda (dir)
|
||||
(cl-some (lambda (dir)
|
||||
(let ((win (windmove-find-other-window dir)))
|
||||
(and win (not (window-minibuffer-p win)))))
|
||||
(pcase dir
|
||||
|
|
@ -960,10 +965,6 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|||
(setq doom-modeline-minor-modes nil)
|
||||
(setq doom-modeline-buffer-state-icon nil))
|
||||
|
||||
(use-package emojify
|
||||
:straight t
|
||||
:if (and (display-graphic-p) (not (or my/lowpower my/is-termux))))
|
||||
|
||||
(use-package ligature
|
||||
:straight (:host github :repo "mickeynp/ligature.el")
|
||||
:if (display-graphic-p)
|
||||
|
|
@ -2299,6 +2300,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|||
:if (not (or my/slow-ssh my/is-termux my/remote-server))
|
||||
:hook (
|
||||
(typescript-mode . lsp)
|
||||
(js-mode . lsp)
|
||||
(vue-mode . lsp)
|
||||
(go-mode . lsp)
|
||||
(svelte-mode . lsp)
|
||||
|
|
@ -2400,6 +2402,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|||
:config
|
||||
|
||||
(setq dap-ui-variable-length 100)
|
||||
(setq dap-auto-show-output nil)
|
||||
(require 'dap-node)
|
||||
(dap-node-setup)
|
||||
|
||||
|
|
@ -2582,7 +2585,14 @@ _r_: Restart frame _uo_: Output _sd_: Down stack frame _bh_: Set
|
|||
:port 9229
|
||||
:outFiles ["${workspaceFolder}/dist/**/*.js"]
|
||||
:sourceMaps t
|
||||
:program "${workspaceFolder}/src/app.ts")))
|
||||
:program "${workspaceFolder}/src/app.ts"))
|
||||
(dap-register-debug-template
|
||||
"Node::Babel"
|
||||
(list :type "node"
|
||||
:request "attach"
|
||||
:name "Node::Attach"
|
||||
:port 9229
|
||||
:program "${workspaceFolder}/dist/bin/www.js")))
|
||||
|
||||
(use-package reformatter
|
||||
:straight t)
|
||||
|
|
@ -3748,7 +3758,7 @@ _r_: Restart frame _uo_: Output _sd_: Down stack frame _bh_: Set
|
|||
(emms-player-simple-regexp
|
||||
"m3u" "ogg" "flac" "mp3" "wav" "mod" "au" "aiff"))
|
||||
;; MPV setup
|
||||
(add-to-list 'emms-player-list 'emms-player-mpv t)
|
||||
(add-to-list 'emms-player-list 'emms-player-mpv)
|
||||
(emms-player-set emms-player-mpv
|
||||
'regex
|
||||
(rx (or (: "https://" (* nonl) "youtube.com" (* nonl))
|
||||
|
|
@ -4098,7 +4108,7 @@ _r_: Restart frame _uo_: Output _sd_: Down stack frame _bh_: Set
|
|||
(message "Sent %d to %d" (or signal 15) (cdr (assoc 'pid app)))))))
|
||||
|
||||
(use-package screenshot
|
||||
:straight (:repo "tecosaur/screenshot" :host github :files ("screenshot.el"))
|
||||
:straight (:repo "tecosaur/screenshot" :host github :files ("screenshot.el") :commit "f8204e82dc0c1158c401735d36a143e6f6d24cf5")
|
||||
:if (display-graphic-p)
|
||||
:commands (screenshot)
|
||||
:init
|
||||
|
|
@ -4118,8 +4128,8 @@ _r_: Restart frame _uo_: Output _sd_: Down stack frame _bh_: Set
|
|||
(my-leader-def "ag" 'guix))
|
||||
|
||||
(use-package pomm
|
||||
;; :straight (:repo "SqrtMinusOne/pomm.el" :host github)
|
||||
:straight (:local-repo "~/Code/Emacs/pomm")
|
||||
:straight (:host github :repo "SqrtMinusOne/pomm.el" :files (:defaults "resources"))
|
||||
;; :straight (:local-repo "~/Code/Emacs/pomm" :files (:defaults "resources"))
|
||||
:init
|
||||
(my-leader-def "ap" #'pomm)
|
||||
:config
|
||||
|
|
@ -4160,6 +4170,8 @@ _r_: Restart frame _uo_: Output _sd_: Down stack frame _bh_: Set
|
|||
"<ORG-ROAM>")
|
||||
((string-match-p (rx bos (+ num) "-" (+ num) "-" (+ num) ".org" eos) name)
|
||||
"<ORG-JOURNAL>")
|
||||
((string-match-p (rx bos "EXWM") name)
|
||||
"<EXWM>")
|
||||
(t name)))
|
||||
|
||||
(defun my/elcord-buffer-details-format-functions ()
|
||||
|
|
|
|||
4
.mailcap
4
.mailcap
|
|
@ -3,7 +3,7 @@ audio/*; mpc add %s
|
|||
image/*; feh %s
|
||||
|
||||
application/msword; /usr/bin/xdg-open %s
|
||||
application/pdf; zathura %s
|
||||
application/postscript ; zathura %s
|
||||
application/pdf; zathura-wrapper %s
|
||||
application/postscript ; zathura-wrapper %s
|
||||
|
||||
text/html; firefox %s
|
||||
|
|
|
|||
4
.profile
4
.profile
|
|
@ -56,8 +56,8 @@ fi
|
|||
# Other package managers:3 ends here
|
||||
|
||||
# [[file:Console.org::*Other package managers][Other package managers:4]]
|
||||
if [ -d "$HOME/.guix-extra-profiles/desktop" ]; then
|
||||
export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop/desktop/etc/fonts"
|
||||
if [ -d "$HOME/.guix-extra-profiles/desktop-misc" ]; then
|
||||
export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop-misc/desktop-misc/etc/fonts"
|
||||
fi
|
||||
# Other package managers:4 ends here
|
||||
|
||||
|
|
|
|||
30
.xsession
Executable file
30
.xsession
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env bash
|
||||
# [[file:Desktop.org::*Xsession][Xsession:1]]
|
||||
# Source .profile
|
||||
. ~/.profile
|
||||
|
||||
# Disable access control for the current user
|
||||
xhost +SI:localuser:$USER
|
||||
|
||||
# Fix for Java applications
|
||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
|
||||
# Apply XResourses
|
||||
xrdb -merge ~/.Xresources
|
||||
|
||||
# Turn off the system bell
|
||||
xset -b
|
||||
|
||||
# Use i3lock as a screen locker
|
||||
xss-lock -- i3lock &
|
||||
|
||||
# Some apps that have to be launched only once.
|
||||
picom &
|
||||
# nm-applet &
|
||||
dunst &
|
||||
copyq &
|
||||
|
||||
# Run the Emacs startup script as a session.
|
||||
# exec dbus-launch --exit-with-session ~/.emacs.d/run-exwm.sh
|
||||
exec dbus-launch --exit-with-session emacs -mm --debug-init -l ~/.emacs.d/desktop.el
|
||||
# Xsession:1 ends here
|
||||
|
|
@ -123,8 +123,8 @@ fi
|
|||
|
||||
Use Guix fontconfig. Necessary for nix apps
|
||||
#+begin_src sh
|
||||
if [ -d "$HOME/.guix-extra-profiles/desktop" ]; then
|
||||
export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop/desktop/etc/fonts"
|
||||
if [ -d "$HOME/.guix-extra-profiles/desktop-misc" ]; then
|
||||
export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop-misc/desktop-misc/etc/fonts"
|
||||
fi
|
||||
#+end_src
|
||||
|
||||
|
|
|
|||
597
Desktop.org
597
Desktop.org
|
|
@ -232,6 +232,441 @@ elif [ "$hostname" = "eminence" ]; then
|
|||
xgamma -gamma 1.25
|
||||
fi
|
||||
#+end_src
|
||||
* EXWM
|
||||
:PROPERTIES:
|
||||
:header-args+: :tangle ~/.emacs.d/desktop.el
|
||||
:END:
|
||||
Settings for [[https://github.com/ch11ng/exwm][Emacs X Window Manager]], a tiling WM implemented in Emacs Lisp.
|
||||
|
||||
References:
|
||||
- [[https://github.com/ch11ng/exwm/wiki][EXWM Wiki]]
|
||||
- [[https://github.com/daviwil/emacs-from-scratch/blob/master/Desktop.org][Emacs From Scratch config]]
|
||||
|
||||
TODO Look at:
|
||||
- https://github.com/ch11ng/exwm/issues/202
|
||||
|
||||
** Xsession
|
||||
First things first, Emacs has to be launched as a window wanager. On a more conventional system I'd create a .desktop file in some system folder that can be seen by a login manager, but in the case of Guix it's a bit more complicated, because all such folders are not meant to be changed manually.
|
||||
|
||||
However, GDM, the login manager that seems to be default on Guix, launches =~/.xsession= on the startup if it's present, which is just fine for my purposes.
|
||||
|
||||
#+begin_src sh :tangle ~/.xsession
|
||||
# Source .profile
|
||||
. ~/.profile
|
||||
|
||||
# Disable access control for the current user
|
||||
xhost +SI:localuser:$USER
|
||||
|
||||
# Fix for Java applications
|
||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
|
||||
# Apply XResourses
|
||||
xrdb -merge ~/.Xresources
|
||||
|
||||
# Turn off the system bell
|
||||
xset -b
|
||||
|
||||
# Use i3lock as a screen locker
|
||||
xss-lock -- i3lock &
|
||||
|
||||
# Some apps that have to be launched only once.
|
||||
picom &
|
||||
# nm-applet &
|
||||
dunst &
|
||||
copyq &
|
||||
|
||||
# Run the Emacs startup script as a session.
|
||||
# exec dbus-launch --exit-with-session ~/.emacs.d/run-exwm.sh
|
||||
exec dbus-launch --exit-with-session emacs -mm --debug-init -l ~/.emacs.d/desktop.el
|
||||
#+end_src
|
||||
** Startup apps
|
||||
Now that Emacs is launched, it is necessary to set up the EXWM-specific parts of config.
|
||||
|
||||
I want to launch some apps from EXWM instead of the Xsession file for two purposes:
|
||||
- the app may need to have the entire desktop environment set up
|
||||
- or it may need to be restarted if Emacs is killed.
|
||||
|
||||
As of now, these are polybar, feh and shepherd:
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/exwm-run-polybar ()
|
||||
(call-process "~/bin/polybar.sh"))
|
||||
|
||||
(defun my/exwm-set-wallpaper ()
|
||||
(call-process-shell-command "feh --bg-fill ~/Pictures/wallpaper.jpg"))
|
||||
|
||||
(defun my/exwm-run-shepherd ()
|
||||
(when (string-empty-p (shell-command-to-string "pgrep -u pavel shepherd"))
|
||||
(call-process "shepherd")))
|
||||
#+end_src
|
||||
** Moving windows
|
||||
My functions for managing windows. I initially wrote these to mimic the i3 behavior for my Emacs + i3 integration, but I want to try to keep them for the EXWM config as well to make the transition less painful.
|
||||
|
||||
A predicate which checks whether there is space in the given direction:
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/exwm-direction-exists-p (dir)
|
||||
(cl-some (lambda (dir)
|
||||
(let ((win (windmove-find-other-window dir)))
|
||||
(and win (not (window-minibuffer-p win)))))
|
||||
(pcase dir
|
||||
('width '(left right))
|
||||
('height '(up down)))))
|
||||
#+end_src
|
||||
|
||||
And a function to move windows with the following behavior:
|
||||
- if there is space in the required directon, move the Emacs window there;
|
||||
- if there is no space in the required direction, but space in two orthogonal directions, move the Emacs window so that there is no more space in the orthogonal directions;
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/exwm-move-window (dir)
|
||||
(let ((other-window (windmove-find-other-window dir))
|
||||
(other-direction (my/exwm-direction-exists-p
|
||||
(pcase dir
|
||||
('up 'width)
|
||||
('down 'width)
|
||||
('left 'height)
|
||||
('right 'height)))))
|
||||
(cond
|
||||
((and other-window (not (window-minibuffer-p other-window)))
|
||||
(window-swap-states (selected-window) other-window))
|
||||
(other-direction
|
||||
(evil-move-window dir)))))
|
||||
#+end_src
|
||||
** Resizing windows
|
||||
Something like this also goes for resizing windows. I'm used to the i3 "mode" for this functionality, and this seems to be a sensible approach.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package transient
|
||||
:straight t)
|
||||
|
||||
(setq my/exwm-resize-value 5)
|
||||
|
||||
(defun my/exwm-resize-window (dir kind &optional value)
|
||||
(unless value
|
||||
(setq value my/exwm-resize-value))
|
||||
(pcase kind
|
||||
('shrink
|
||||
(pcase dir
|
||||
('width
|
||||
(evil-window-decrease-width value))
|
||||
('height
|
||||
(evil-window-decrease-height value))))
|
||||
('grow
|
||||
(pcase dir
|
||||
('width
|
||||
(evil-window-increase-width value))
|
||||
('height
|
||||
(evil-window-increase-height value))))))
|
||||
|
||||
(defhydra my/exwm-resize-hydra (:color pink :hint nil :foreign-keys run)
|
||||
"
|
||||
^Resize^
|
||||
_l_: Increase width _h_: Decrease width _j_: Increase height _k_: Decrease height
|
||||
|
||||
_=_: Balance "
|
||||
("h" (lambda () (interactive) (my/exwm-resize-window 'width 'shrink)))
|
||||
("j" (lambda () (interactive) (my/exwm-resize-window 'height 'grow)))
|
||||
("k" (lambda () (interactive) (my/exwm-resize-window 'height 'shrink)))
|
||||
("l" (lambda () (interactive) (my/exwm-resize-window 'width 'grow)))
|
||||
("=" balance-windows)
|
||||
("q" nil "quit" :color blue))
|
||||
#+end_src
|
||||
** App shortcuts
|
||||
Also, a transient for shortcuts for the most frequent apps.
|
||||
|
||||
I wanted to make the interactive lambda a macro, but this doesn't seem to work the way I expect, so the code has a bit of duplication.
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/run-in-background (command)
|
||||
(let ((command-parts (split-string command "[ ]+")))
|
||||
(apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))
|
||||
|
||||
(transient-define-prefix my/exwm-apps ()
|
||||
["Apps"
|
||||
("t" "Termnial (Alacritty)" (lambda () (interactive) (my/run-in-background "alacritty")))
|
||||
("b" "Browser (Firefox)" (lambda () (interactive) (my/run-in-background "firefox")))
|
||||
("v" "VK" (lambda () (interactive) (my/run-in-background "vk")))
|
||||
("s" "Slack" (lambda () (interactive) (my/run-in-background "slack-wrapper")))
|
||||
("d" "Discord" (lambda () (interactive) (my/run-in-background "flatpak run com.discordapp.Discord")))
|
||||
("q" "Quit" transient-quit-one)])
|
||||
#+end_src
|
||||
** Move workspace to another monitor
|
||||
A function to move the current workspace to another monitor.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/exwm-workspace-switch-monitor ()
|
||||
(interactive)
|
||||
(if (plist-get exwm-randr-workspace-monitor-plist exwm-workspace-current-index)
|
||||
(setq exwm-randr-workspace-monitor-plist
|
||||
(map-delete exwm-randr-workspace-monitor-plist exwm-workspace-current-index))
|
||||
(setq exwm-randr-workspace-monitor-plist
|
||||
(plist-put exwm-randr-workspace-monitor-plist
|
||||
exwm-workspace-current-index
|
||||
my/exwm-another-monitor)))
|
||||
(exwm-randr-refresh))
|
||||
#+end_src
|
||||
** Switch to the opposite monitor
|
||||
Store the information about which workspace is available on which monitor.
|
||||
|
||||
#+begin_src emacs-lisp :noweb-ref exwm-monitor-config :tangle no
|
||||
(setq my/exwm-monitor-workspace '())
|
||||
|
||||
(defun my/exwm-get-current-monitor ()
|
||||
(let* ((info (shell-command-to-string "xdotool getmouselocation --shell | head -n 1"))
|
||||
(coord (string-to-number (substring info 2))))
|
||||
(if (> coord 1920) 1 0)))
|
||||
|
||||
(defun my/exwm-update-current-monitor ()
|
||||
(setf (alist-get (my/exwm-get-current-monitor) my/exwm-monitor-workspace)
|
||||
exwm-workspace-current-index))
|
||||
|
||||
(add-hook 'exwm-workspace-switch-hook
|
||||
#'my/exwm-update-current-monitor)
|
||||
#+end_src
|
||||
|
||||
Switch to the opposite monitor.
|
||||
#+begin_src emacs-lisp :noweb-ref exwm-monitor-config :tangle no
|
||||
(defun my/exwm-switch-to-other-monitor ()
|
||||
(interactive)
|
||||
(let* ((current (my/exwm-get-current-monitor))
|
||||
(other (seq-some
|
||||
(lambda (m)
|
||||
(and (not (= (car m) current)) (cdr m)))
|
||||
my/exwm-monitor-workspace)))
|
||||
(exwm-workspace-switch other)))
|
||||
#+end_src
|
||||
** Switching buffers
|
||||
A single perspective usually has only a handful of EXWM buffers, so here are functions to cycle them
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/cycle-persp-exwm-buffers (dir)
|
||||
(let* ((current (current-buffer))
|
||||
(ignore-rx (persp--make-ignore-buffer-rx))
|
||||
(exwm-buffers
|
||||
(cl-loop for buf in (persp-current-buffers)
|
||||
if (and (buffer-live-p buf)
|
||||
(eq 'exwm-mode (buffer-local-value 'major-mode buf))
|
||||
(not (string-match-p ignore-rx (buffer-name buf))))
|
||||
collect buf))
|
||||
(current-pos (or (cl-position current exwm-buffers) -1)))
|
||||
(if (seq-empty-p exwm-buffers)
|
||||
(message "No EXWM buffers!")
|
||||
(let* ((next-pos (% (+ current-pos (length exwm-buffers)
|
||||
(if (eq dir 'forward) 1 -1))
|
||||
(length exwm-buffers)))
|
||||
(next-buffer (nth next-pos exwm-buffers)))
|
||||
(switch-to-buffer next-buffer)
|
||||
(message
|
||||
"%s"
|
||||
(mapconcat
|
||||
(lambda (buf)
|
||||
(let ((name (string-replace "EXWM :: " "" (buffer-name buf))))
|
||||
(if (eq (current-buffer) buf)
|
||||
(concat
|
||||
"["
|
||||
(propertize name 'face `(foreground-color . ,(doom-color 'yellow)))
|
||||
"]")
|
||||
(format " %s " name))))
|
||||
exwm-buffers
|
||||
" "))))))
|
||||
#+end_src
|
||||
** Keybindings
|
||||
Setting keybindings for EXWM. This actually has to be in the =:config= block of the =use-package= form, that is it has to be run after EXWM is loaded, so I use noweb to put this block in a correct place.
|
||||
|
||||
First, some prefixes for keybindings that are always passed to EXWM instead of the X application in =line-mode=:
|
||||
#+begin_src emacs-lisp :tangle no :noweb-ref exwm-keybindings
|
||||
(setq exwm-input-prefix-keys
|
||||
`(?\C-x
|
||||
?\C-w
|
||||
?\M-x
|
||||
?\M-u))
|
||||
#+end_src
|
||||
|
||||
Also other local keybindings, that are also available only in =line-mode=:
|
||||
#+begin_src emacs-lisp :tangle no :noweb-ref exwm-keybindings
|
||||
(defmacro my/app-command (command)
|
||||
`(lambda () (interactive) (my/run-in-background ,command)))
|
||||
|
||||
(general-define-key
|
||||
:keymaps '(exwm-mode-map)
|
||||
"C-q" 'exwm-input-send-next-key
|
||||
"<print>" (my/app-command "flameshot gui")
|
||||
"M-x" 'counsel-M-x
|
||||
"M-SPC" (general-key "SPC"))
|
||||
#+end_src
|
||||
|
||||
Simulation keys.
|
||||
#+begin_src emacs-lisp :tangle no :noweb-ref exwm-keybindings
|
||||
(setq exwm-input-simulation-keys `((,(kbd "M-w") . ,(kbd "C-w"))
|
||||
(,(kbd "M-c") . ,(kbd "C-c"))))
|
||||
#+end_src
|
||||
|
||||
And keybindings that are available in both =char-mode= and =line-mode=:
|
||||
#+begin_src emacs-lisp :tangle no :noweb-ref exwm-keybindings
|
||||
(setq exwm-input-global-keys
|
||||
`(
|
||||
;; Reset to line-mode
|
||||
(,(kbd "s-R") . exwm-reset)
|
||||
|
||||
;; Switch windows
|
||||
(,(kbd "s-<left>"). windmove-left)
|
||||
(,(kbd "s-<right>") . windmove-right)
|
||||
(,(kbd "s-<up>") . windmove-up)
|
||||
(,(kbd "s-<down>") . windmove-down)
|
||||
|
||||
(,(kbd "s-h"). windmove-left)
|
||||
(,(kbd "s-l") . windmove-right)
|
||||
(,(kbd "s-k") . windmove-up)
|
||||
(,(kbd "s-j") . windmove-down)
|
||||
|
||||
;; Moving windows
|
||||
(,(kbd "s-H") . (lambda () (interactive) (my/exwm-move-window 'left)))
|
||||
(,(kbd "s-L") . (lambda () (interactive) (my/exwm-move-window 'right)))
|
||||
(,(kbd "s-K") . (lambda () (interactive) (my/exwm-move-window 'up)))
|
||||
(,(kbd "s-J") . (lambda () (interactive) (my/exwm-move-window 'down)))
|
||||
|
||||
;; Fullscreen
|
||||
(,(kbd "s-f") . exwm-layout-toggle-fullscreen)
|
||||
|
||||
;; Quit
|
||||
(,(kbd "s-Q") . evil-quit)
|
||||
|
||||
;; Split windows
|
||||
(,(kbd "s-s") . evil-window-vsplit)
|
||||
(,(kbd "s-v") . evil-window-hsplit)
|
||||
|
||||
;; Switch perspectives
|
||||
(,(kbd "s-,") . persp-prev)
|
||||
(,(kbd "s-.") . persp-next)
|
||||
|
||||
;; Switch buffers
|
||||
(,(kbd "s-e") . persp-ivy-switch-buffer)
|
||||
|
||||
;; Resize windows
|
||||
(,(kbd "s-r") . my/exwm-resize-hydra/body)
|
||||
|
||||
;; Apps & stuff
|
||||
(,(kbd "s-p") . ,(my/app-command "rofi -modi drun,run -show drun"))
|
||||
(,(kbd "s-;") . my/exwm-apps)
|
||||
(,(kbd "s--") . ,(my/app-command "rofi-pass"))
|
||||
(,(kbd "s-=") . ,(my/app-command "rofimoji"))
|
||||
|
||||
;; Basic controls
|
||||
(,(kbd "<XF86AudioRaiseVolume>") . ,(my/app-command "ponymix increase 5 --max-volume 150"))
|
||||
(,(kbd "<XF86AudioLowerVolume>") . ,(my/app-command "ponymix decrease 5 --max-volume 150"))
|
||||
(,(kbd "<XF86AudioMute>") . ,(my/app-command "ponymix toggle"))
|
||||
|
||||
(,(kbd "<XF86AudioPlay>") . ,(my/app-command "mpc toggle"))
|
||||
(,(kbd "<XF86AudioPause>") . ,(my/app-command "mpc pause"))
|
||||
(,(kbd "<print>") . ,(my/app-command "flameshot gui"))
|
||||
|
||||
;; Switch workspace
|
||||
(,(kbd "s-q") . my/exwm-switch-to-other-monitor)
|
||||
(,(kbd "s-w") . exwm-workspace-switch)
|
||||
(,(kbd "s-W") . exwm-workspace-move-window)
|
||||
(,(kbd "s-<tab>") . my/exwm-workspace-switch-monitor)
|
||||
|
||||
;; Cycle EXWM windows in the current perspective
|
||||
(,(kbd "s-[") . (lambda () (interactive) (my/cycle-persp-exwm-buffers 'backward)))
|
||||
(,(kbd "s-]") . (lambda () (interactive) (my/cycle-persp-exwm-buffers 'forward)))
|
||||
(,(kbd "s-o") . ,(my/app-command "rofi -show window"))
|
||||
|
||||
;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9)
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%d" i)) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-switch-create ,i))))
|
||||
(number-sequence 0 9))))
|
||||
#+end_src
|
||||
|
||||
** Pinentry
|
||||
The GUI pinentry doesn't work too well with EXWM because of the popup windows, so we will the the built-in Emacs pinentry.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package pinentry
|
||||
:straight t
|
||||
:after (exwm)
|
||||
:config
|
||||
(setenv "GPG_AGENT_INFO" nil) ;; use emacs pinentry
|
||||
(setq auth-source-debug t)
|
||||
|
||||
(setq epg-gpg-program "gpg2") ;; not necessary
|
||||
(require 'epa-file)
|
||||
(epa-file-enable)
|
||||
(setq epa-pinentry-mode 'loopback)
|
||||
(setq epg-pinentry-mode 'loopback)
|
||||
(pinentry-start)
|
||||
(my/run-in-background "gpgconf --reload gpg-agent"))
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-space :tangle ~/.gnupg/gpg-agent.conf
|
||||
default-cache-ttl 3600
|
||||
max-cache-ttl 3600
|
||||
allow-emacs-pinentry
|
||||
allow-loopback-pinentry
|
||||
#+end_src
|
||||
** Modeline
|
||||
Show current workspace in the modeline.
|
||||
|
||||
#+begin_src emacs-lisp :noweb-ref exwm-mode-line-config :tangle no
|
||||
(defvar my/exwm-mode-line-info "")
|
||||
|
||||
(add-to-list 'mode-line-misc-info
|
||||
'(:eval my/exwm-mode-line-info))
|
||||
|
||||
(defun my/exwm-mode-line-info-update ()
|
||||
(setq my/exwm-mode-line-info
|
||||
(concat
|
||||
"["
|
||||
(propertize (funcall exwm-workspace-index-map exwm-workspace-current-index)
|
||||
'face
|
||||
`(foreground-color . ,(doom-color 'yellow)))
|
||||
"]"))
|
||||
(force-mode-line-update))
|
||||
|
||||
(add-hook 'exwm-workspace-switch-hook #'my/exwm-mode-line-info-update)
|
||||
#+end_src
|
||||
** EXWM config
|
||||
And the EXWM config itself.
|
||||
|
||||
#+begin_src emacs-lisp :noweb yes
|
||||
(defun my/exwm-init ()
|
||||
(exwm-workspace-switch 1)
|
||||
|
||||
(my/exwm-run-polybar)
|
||||
(my/exwm-set-wallpaper)
|
||||
(my/exwm-run-shepherd)
|
||||
;; (with-eval-after-load 'perspective
|
||||
;; (my/exwm-setup-perspectives))
|
||||
)
|
||||
|
||||
(defun my/exwm-update-class ()
|
||||
(exwm-workspace-rename-buffer (format "EXWM :: %s" exwm-class-name)))
|
||||
|
||||
(use-package exwm
|
||||
:straight t
|
||||
:config
|
||||
(setq exwm-workspace-number 5)
|
||||
(add-hook 'exwm-init-hook #'my/exwm-init)
|
||||
(add-hook 'exwm-update-class-hook #'my/exwm-update-class)
|
||||
|
||||
(require 'exwm-randr)
|
||||
(exwm-randr-enable)
|
||||
(start-process-shell-command "xrandr" nil "~/bin/scripts/screen-layout")
|
||||
(when (string= (system-name) "indigo")
|
||||
(setq my/exwm-another-monitor "DVI-D-0")
|
||||
(setq exwm-randr-workspace-monitor-plist `(2 ,my/exwm-another-monitor 3 ,my/exwm-another-monitor)))
|
||||
|
||||
(setq exwm-workspace-warp-cursor t)
|
||||
(setq mouse-autoselect-window t)
|
||||
(setq focus-follows-mouse t)
|
||||
|
||||
<<exwm-monitor-config>>
|
||||
<<exwm-keybindings>>
|
||||
<<exwm-mode-line-config>>
|
||||
|
||||
(set-frame-parameter (selected-frame) 'alpha '(90 . 90))
|
||||
(add-to-list 'default-frame-alist '(alpha . (90 . 90)))
|
||||
|
||||
(exwm-enable))
|
||||
#+end_src
|
||||
* i3wm
|
||||
:PROPERTIES:
|
||||
:header-args+: :tangle ./.config/i3/config
|
||||
|
|
@ -800,9 +1235,9 @@ exec "xmodmap ~/.Xmodmap"
|
|||
:header-args+: :tangle ./.config/polybar/config
|
||||
:END:
|
||||
|
||||
| Guix dependency | Description |
|
||||
|------------------+--------------------------|
|
||||
| polybar | statusbar |
|
||||
| Category | Guix dependency | Description |
|
||||
|-----------------+-----------------+-------------|
|
||||
| desktop-polybar | polybar | statusbar |
|
||||
|
||||
[[https://github.com/polybar/polybar][Polybar]] is a nice-looking, WM-agnostic statusbar program.
|
||||
|
||||
|
|
@ -861,7 +1296,7 @@ declare -A BLOCKS=(
|
|||
# Geolocation for some modules
|
||||
export LOC="SPB"
|
||||
|
||||
export IPSTACK_API_KEY=$(pass show My_Online/APIs/ipstack | head -n 1)
|
||||
# export IPSTACK_API_KEY=$(pass show My_Online/APIs/ipstack | head -n 1)
|
||||
|
||||
pkill polybar
|
||||
for m in $(xrandr --query | grep " connected" | cut -d" " -f1); do
|
||||
|
|
@ -976,11 +1411,11 @@ Some of the custom modules below use Org mode noweb to evaluate colors, because
|
|||
If you want to copy something, you can go to the [[file:bin/polybar/][bin/polybar]] folder.
|
||||
|
||||
*** ipstack-vpn
|
||||
| Guix dependency | Description |
|
||||
|-----------------+-------------------------|
|
||||
| bind:utils | Provides dig |
|
||||
| curl | |
|
||||
| jq | util to work with JSONs |
|
||||
| Category | Guix dependency | Description |
|
||||
|-----------------+-----------------+-------------------------|
|
||||
| desktop-polybar | bind:utils | Provides dig |
|
||||
| desktop-polybar | curl | |
|
||||
| desktop-polybar | jq | util to work with JSONs |
|
||||
|
||||
A module to get a country of the current IP and openvpn status. Uses [[https://ipstack.com/][ipstack]] API.
|
||||
|
||||
|
|
@ -1043,9 +1478,9 @@ interval = 1200
|
|||
*** aw-afk
|
||||
Prints out a current uptime and non-AFK time from [[https://github.com/ActivityWatch][ActivityWatch]] server
|
||||
|
||||
| Guix dependency |
|
||||
|-----------------|
|
||||
| dateutils |
|
||||
| Category | Guix dependency |
|
||||
|-----------------+-----------------|
|
||||
| desktop-polybar | dateutils |
|
||||
|
||||
#+begin_src bash :tangle ./bin/polybar/aw_afk.sh :noweb yes
|
||||
afk_event=$(curl -s -X GET "http://localhost:5600/api/0/buckets/aw-watcher-afk_$(hostname)/events?limit=1" -H "accept: application/json")
|
||||
|
|
@ -1083,9 +1518,9 @@ interval = 1
|
|||
format-underline = ${colors.green-lighter}
|
||||
#+end_src
|
||||
*** sun
|
||||
| Guix dependency |
|
||||
|-----------------|
|
||||
| sunwait |
|
||||
| Category | Guix dependency |
|
||||
|-----------------+-----------------|
|
||||
| desktop-polybar | sunwait |
|
||||
|
||||
Prints out the time of sunrise/sunset. Uses [[https://github.com/risacher/sunwait][sunwait]]
|
||||
|
||||
|
|
@ -1372,9 +1807,9 @@ ramp-capacity-4 =
|
|||
#+end_src
|
||||
|
||||
* Rofi
|
||||
| Guix dependency |
|
||||
|-----------------|
|
||||
| rofi |
|
||||
| Category | Guix dependency |
|
||||
|--------------+-----------------|
|
||||
| desktop-rofi | rofi |
|
||||
|
||||
[[https://github.com/davatorium/rofi][rofi]] is another dynamic menu generator. It can act as dmenu replacement but offers a superset of dmenu's features.
|
||||
|
||||
|
|
@ -1581,14 +2016,14 @@ if [[ ! -z $SELECTED ]]; then
|
|||
fi
|
||||
#+end_src
|
||||
*** Emojis
|
||||
| Guix dependency |
|
||||
|-----------------|
|
||||
| rofimoji |
|
||||
| Category | Guix dependency |
|
||||
|--------------+-----------------|
|
||||
| desktop-rofi | python-rofimoji |
|
||||
*** pass
|
||||
| Guix dependency |
|
||||
|-----------------|
|
||||
| rofi-pass |
|
||||
| xset |
|
||||
| Category | Guix dependency |
|
||||
|--------------+-----------------|
|
||||
| desktop-rofi | rofi-pass |
|
||||
| desktop-rofi | xset |
|
||||
|
||||
A nice [[https://github.com/carnager/rofi-pass][pass frontend for Rofi]], which is even packaged for Guix.
|
||||
|
||||
|
|
@ -2130,12 +2565,12 @@ wintypes:
|
|||
};
|
||||
#+end_src
|
||||
* Zathura
|
||||
| Guix dependency |
|
||||
|---------------------|
|
||||
| zathura |
|
||||
| zathura-ps |
|
||||
| zathura-pdf-poppler |
|
||||
| zathura-djvu |
|
||||
| Category | Guix dependency |
|
||||
|----------+---------------------|
|
||||
| office | zathura |
|
||||
| office | zathura-ps |
|
||||
| office | zathura-pdf-mupdf |
|
||||
| office | zathura-djvu |
|
||||
|
||||
[[https://pwmt.org/projects/zathura/][Zathura]] is a pdf viewer with vim-like keybindings. One of my favorite features is an ability to invert the document colors.
|
||||
|
||||
|
|
@ -2150,6 +2585,24 @@ set recolor true
|
|||
map <C-r> set recolor false
|
||||
map <C-R> set recolor true
|
||||
#+end_src
|
||||
|
||||
For some reason zathura doesn't pick up the plugin directory, so I make a wrapper that sets the directory up:
|
||||
#+begin_src bash :tangle ~/bin/zathura-wrapper
|
||||
zathura -p ~/.guix-extra-profiles/office/office/lib/zathura $@
|
||||
#+end_src
|
||||
|
||||
#+begin_src conf-desktop
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Zathura
|
||||
Exec=/home/pavel/bin/zathura-wrapper %U
|
||||
#+end_src
|
||||
|
||||
Add the following like to the =mimeapps.list=
|
||||
#+begin_example
|
||||
application/pdf=zathura-wrapper.desktop
|
||||
#+end_example
|
||||
* Various software
|
||||
This section generates manifests for various desktop software that I'm using.
|
||||
|
||||
|
|
@ -2235,6 +2688,27 @@ LaTeX
|
|||
'(
|
||||
<<packages("latex")>>))
|
||||
#+end_src
|
||||
|
||||
Desktop Misc
|
||||
#+begin_src scheme :tangle .config/guix/manifests/desktop-misc.scm :noweb yes
|
||||
(specifications->manifest
|
||||
'(
|
||||
<<packages("desktop-misc")>>))
|
||||
#+end_src
|
||||
|
||||
Desktop polybar
|
||||
#+begin_src scheme :tangle .config/guix/manifests/desktop-polybar.scm :noweb yes
|
||||
(specifications->manifest
|
||||
'(
|
||||
<<packages("desktop-polybar")>>))
|
||||
#+end_src
|
||||
|
||||
Desktop rofi
|
||||
#+begin_src scheme :tangle .config/guix/manifests/desktop-rofi.scm :noweb yes
|
||||
(specifications->manifest
|
||||
'(
|
||||
<<packages("desktop-rofi")>>))
|
||||
#+end_src
|
||||
** Flatpak
|
||||
A lot of proprietary desktop applications can be installed most easily with flatpak & flathub.
|
||||
|
||||
|
|
@ -2411,6 +2885,15 @@ aw-watcher-window
|
|||
#:start (make-forkexec-constructor '("xsettingsd"))
|
||||
#:stop (make-kill-destructor)))
|
||||
#+end_src
|
||||
** nm-applet
|
||||
#+begin_src scheme
|
||||
(define nm-applet
|
||||
(make <service>
|
||||
#:provides '(nm-applet)
|
||||
#:respawn? #t
|
||||
#:start (make-forkexec-constructor '("nm-applet"))
|
||||
#:stop (make-kill-destructor)))
|
||||
#+end_src
|
||||
** Discord rich presence
|
||||
|
||||
References:
|
||||
|
|
@ -2431,7 +2914,7 @@ Launch an authentication agent. Necessary for stuff like =pkexec=. I suspect I'm
|
|||
(make <service>
|
||||
#:provides '(polkit-gnome)
|
||||
#:respawn? #t
|
||||
#:start (make-forkexec-constructor '("/home/pavel/.guix-extra-profiles/desktop/desktop/libexec/polkit-gnome-authentication-agent-1"))
|
||||
#:start (make-forkexec-constructor '("/home/pavel/.guix-extra-profiles/desktop-misc/desktop-misc/libexec/polkit-gnome-authentication-agent-1"))
|
||||
#:stop (make-kill-destructor)))
|
||||
#+end_src
|
||||
** Xmodmap
|
||||
|
|
@ -2478,7 +2961,8 @@ Register services
|
|||
polkit-gnome
|
||||
vpn
|
||||
davmail
|
||||
xmodmap)
|
||||
xmodmap
|
||||
nm-applet)
|
||||
#+end_src
|
||||
|
||||
Daemonize shepherd
|
||||
|
|
@ -2488,7 +2972,7 @@ Daemonize shepherd
|
|||
|
||||
Run services
|
||||
#+begin_src scheme
|
||||
(for-each start '(mpd mpd-watcher mcron aw-server aw-watcher-afk aw-watcher-window pulseeffects xsettingsd discord-rich-presence polkit-gnome davmail xmodmap))
|
||||
(for-each start '(mpd mpd-watcher mcron aw-server aw-watcher-afk aw-watcher-window pulseeffects xsettingsd discord-rich-presence polkit-gnome davmail xmodmap nm-applet))
|
||||
#+end_src
|
||||
** Sync
|
||||
| Guix dependency |
|
||||
|
|
@ -2497,29 +2981,28 @@ Run services
|
|||
* Guix settings
|
||||
Other desktop programs I use are listed below.
|
||||
|
||||
| Guix dependency | Description |
|
||||
|------------------------+-------------------------------------------|
|
||||
| xprop | Tool to display properties of X windows |
|
||||
| arandr | GUI to xrandr |
|
||||
| light | Control screen brightness |
|
||||
| ponymix | Control PulseAudio CLI |
|
||||
| pavucontrol | Control PulseAudio GUI |
|
||||
| network-manager-applet | Applet to manage network connections |
|
||||
| feh | Image viewer. Used to set background |
|
||||
| copyq | Clipboard manager |
|
||||
| xmodmap | Program to modify keybindings on X server |
|
||||
| thunar | My preferred GUI file manager |
|
||||
| keepassxc | My preferred password manager |
|
||||
| telegram-desktop | telegram client |
|
||||
| xdg-utils | gives xdg-open and stuff |
|
||||
| gnome-font-viewer | view fonts |
|
||||
| qbittorrent | torrent client |
|
||||
| fontconfig | |
|
||||
| polkit-gnome | Polkit authentication agent |
|
||||
| anydesk | Remote desktop software |
|
||||
| gnome-disk-utility | Manage disks |
|
||||
| gparted | Manage partitions |
|
||||
| xev | Test input |
|
||||
| Category | Guix dependency | Description |
|
||||
|--------------+------------------------+-------------------------------------------|
|
||||
| desktop-misc | xprop | Tool to display properties of X windows |
|
||||
| desktop-misc | arandr | GUI to xrandr |
|
||||
| desktop-misc | light | Control screen brightness |
|
||||
| desktop-misc | ponymix | Control PulseAudio CLI |
|
||||
| desktop-misc | pavucontrol | Control PulseAudio GUI |
|
||||
| desktop-misc | network-manager-applet | Applet to manage network connections |
|
||||
| desktop-misc | xmodmap | Program to modify keybindings on X server |
|
||||
| desktop-misc | fontconfig | |
|
||||
| desktop-misc | polkit-gnome | Polkit authentication agent |
|
||||
| desktop-misc | feh | Image viewer. Used to set background |
|
||||
| desktop-misc | copyq | Clipboard manager |
|
||||
| desktop-misc | thunar | My preferred GUI file manager |
|
||||
| desktop-misc | telegram-desktop | telegram client |
|
||||
| desktop-misc | xdg-utils | gives xdg-open and stuff |
|
||||
| desktop-misc | gnome-font-viewer | view fonts |
|
||||
| desktop-misc | qbittorrent | torrent client |
|
||||
| desktop-misc | anydesk | Remote desktop software |
|
||||
| desktop-misc | gnome-disk-utility | Manage disks |
|
||||
| desktop-misc | gparted | Manage partitions |
|
||||
| desktop-misc | xev | Test input |
|
||||
|
||||
#+NAME: packages
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
|
|
|
|||
40
Emacs.org
40
Emacs.org
|
|
@ -710,7 +710,12 @@ Using the =SPC= key as a leader key, like in Doom Emacs or Spacemacs.
|
|||
:prefix "SPC"
|
||||
:states '(normal motion emacs))
|
||||
|
||||
(general-def :states '(normal motion emacs) "SPC" nil)
|
||||
(general-def :states '(normal motion emacs)
|
||||
"SPC" nil
|
||||
"M-SPC" (general-key "SPC"))
|
||||
|
||||
(general-def :states '(insert)
|
||||
"M-SPC" (general-key "SPC" :state 'normal))
|
||||
|
||||
(my-leader-def "?" 'which-key-show-top-level)
|
||||
(my-leader-def "E" 'eval-expression)
|
||||
|
|
@ -902,7 +907,7 @@ For the first part, =window-swap-states= with =windmove-find-other-window= do we
|
|||
So here is a simple predicate which checks whether there is space in the given direction.
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/emacs-i3-direction-exists-p (dir)
|
||||
(some (lambda (dir)
|
||||
(cl-some (lambda (dir)
|
||||
(let ((win (windmove-find-other-window dir)))
|
||||
(and win (not (window-minibuffer-p win)))))
|
||||
(pcase dir
|
||||
|
|
@ -1798,16 +1803,6 @@ References:
|
|||
(setq doom-modeline-buffer-state-icon nil))
|
||||
#+end_src
|
||||
** Font stuff
|
||||
*** Emojis
|
||||
| Note | Type |
|
||||
|------+-----------------------------------------------------------|
|
||||
| TODO | Figure out how to display emojis without prettify symbols |
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package emojify
|
||||
:straight t
|
||||
:if (and (display-graphic-p) (not (or my/lowpower my/is-termux))))
|
||||
#+end_src
|
||||
*** Ligatures
|
||||
Ligature setup for the JetBrainsMono font.
|
||||
#+begin_src emacs-lisp
|
||||
|
|
@ -3687,6 +3682,7 @@ References:
|
|||
:if (not (or my/slow-ssh my/is-termux my/remote-server))
|
||||
:hook (
|
||||
(typescript-mode . lsp)
|
||||
(js-mode . lsp)
|
||||
(vue-mode . lsp)
|
||||
(go-mode . lsp)
|
||||
(svelte-mode . lsp)
|
||||
|
|
@ -3822,6 +3818,7 @@ References:
|
|||
:config
|
||||
|
||||
(setq dap-ui-variable-length 100)
|
||||
(setq dap-auto-show-output nil)
|
||||
(require 'dap-node)
|
||||
(dap-node-setup)
|
||||
|
||||
|
|
@ -4046,7 +4043,14 @@ Some debug templates I frequently use.
|
|||
:port 9229
|
||||
:outFiles ["${workspaceFolder}/dist/**/*.js"]
|
||||
:sourceMaps t
|
||||
:program "${workspaceFolder}/src/app.ts")))
|
||||
:program "${workspaceFolder}/src/app.ts"))
|
||||
(dap-register-debug-template
|
||||
"Node::Babel"
|
||||
(list :type "node"
|
||||
:request "attach"
|
||||
:name "Node::Attach"
|
||||
:port 9229
|
||||
:program "${workspaceFolder}/dist/bin/www.js")))
|
||||
|
||||
#+end_src
|
||||
*** OFF (OFF) TabNine
|
||||
|
|
@ -5520,7 +5524,7 @@ script-opts=ytdl_hook-ytdl_path=yt-dlp
|
|||
It seems a bit strange to keep the MPV config in this file, but I don't use the program outside Emacs.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-to-list 'emms-player-list 'emms-player-mpv t)
|
||||
(add-to-list 'emms-player-list 'emms-player-mpv)
|
||||
#+end_src
|
||||
|
||||
Also a custom regex. My demands for MPV include running =yt-dlp=, so there is a regex that matches youtube.com or some of the video formats.
|
||||
|
|
@ -6003,7 +6007,7 @@ Tecosaur's plugin to make beautiful code screenshots.
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package screenshot
|
||||
:straight (:repo "tecosaur/screenshot" :host github :files ("screenshot.el"))
|
||||
:straight (:repo "tecosaur/screenshot" :host github :files ("screenshot.el") :commit "f8204e82dc0c1158c401735d36a143e6f6d24cf5")
|
||||
:if (display-graphic-p)
|
||||
:commands (screenshot)
|
||||
:init
|
||||
|
|
@ -6036,8 +6040,8 @@ My package for doing Pomodoro timer.
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package pomm
|
||||
;; :straight (:repo "SqrtMinusOne/pomm.el" :host github)
|
||||
:straight (:local-repo "~/Code/Emacs/pomm")
|
||||
:straight (:host github :repo "SqrtMinusOne/pomm.el" :files (:defaults "resources"))
|
||||
;; :straight (:local-repo "~/Code/Emacs/pomm" :files (:defaults "resources"))
|
||||
:init
|
||||
(my-leader-def "ap" #'pomm)
|
||||
:config
|
||||
|
|
@ -6096,6 +6100,8 @@ Some functions to override the displayed message:
|
|||
"<ORG-ROAM>")
|
||||
((string-match-p (rx bos (+ num) "-" (+ num) "-" (+ num) ".org" eos) name)
|
||||
"<ORG-JOURNAL>")
|
||||
((string-match-p (rx bos "EXWM") name)
|
||||
"<EXWM>")
|
||||
(t name)))
|
||||
|
||||
(defun my/elcord-buffer-details-format-functions ()
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ declare -A BLOCKS=(
|
|||
# Geolocation for some modules
|
||||
export LOC="SPB"
|
||||
|
||||
export IPSTACK_API_KEY=$(pass show My_Online/APIs/ipstack | head -n 1)
|
||||
# export IPSTACK_API_KEY=$(pass show My_Online/APIs/ipstack | head -n 1)
|
||||
|
||||
pkill polybar
|
||||
for m in $(xrandr --query | grep " connected" | cut -d" " -f1); do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue