| Guix dependency | +
|---|
| rust-i3-switch-tabs | +
Some keybindings for managing windows.
+emacs-i3-integration is a script to pass some command to Emacs to get a consistent set of keybindings in both i3 and Emacs. Check out the section in Emacs.org for details.
Kill focused windows
-bindsym $mod+Shift+q kill
+bindsym $mod+Shift+q exec emacs-i3-integration kill
Change focus
-bindsym $mod+h focus left
-bindsym $mod+j focus down
-bindsym $mod+k focus up
-bindsym $mod+l focus right
+bindsym $mod+h exec emacs-i3-integration focus left
+bindsym $mod+j exec emacs-i3-integration focus down
+bindsym $mod+k exec emacs-i3-integration focus up
+bindsym $mod+l exec emacs-i3-integration focus right
-bindsym $mod+Left focus left
-bindsym $mod+Down focus down
-bindsym $mod+Up focus up
-bindsym $mod+Right focus right
+bindsym $mod+Left exec emacs-i3-integration focus left
+bindsym $mod+Down exec emacs-i3-integration focus down
+bindsym $mod+Up exec emacs-i3-integration focus up
+bindsym $mod+Right exec emacs-i3-integration focus right
Move windows around
-bindsym $mod+Shift+h move left
-bindsym $mod+Shift+j move down
-bindsym $mod+Shift+k move up
-bindsym $mod+Shift+l move right
+bindsym $mod+Shift+h exec emacs-i3-integration move left
+bindsym $mod+Shift+j exec emacs-i3-integration move down
+bindsym $mod+Shift+k exec emacs-i3-integration move up
+bindsym $mod+Shift+l exec emacs-i3-integration move right
-bindsym $mod+Shift+Left move left
-bindsym $mod+Shift+Down move down
-bindsym $mod+Shift+Up move up
-bindsym $mod+Shift+Right move right
+bindsym $mod+Shift+Left exec emacs-i3-integration move left
+bindsym $mod+Shift+Down exec emacs-i3-integration move down
+bindsym $mod+Shift+Up exec emacs-i3-integration move up
+bindsym $mod+Shift+Right exec emacs-i3-integration move right
Split windows
-bindsym $mod+s split h
-bindsym $mod+v split v
+bindsym $mod+s exec emacs-i3-integration split h
+bindsym $mod+v exec emacs-i3-integration split v
+
Switch tabs
+bindsym $mod+period exec i3-switch-tabs right
+bindsym $mod+comma exec i3-switch-tabs left
Enter fullscreen mode
# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle
+bindsym $mod+c fullscreen toggle global
Changing layout
bindsym $mod+w layout stacking
bindsym $mod+t layout tabbed
-bindsym $mod+e layout toggle split
+bindsym $mod+e exec emacs-i3-integration layout toggle split
Toggle tiling/floating, switch between tiled and floating windows
bindsym $mod+Shift+f floating toggle
bindsym $mod+z focus mode_toggle
@@ -529,10 +546,6 @@
bindsym $mod+Shift+8 move container to workspace $w8
bindsym $mod+Shift+9 move container to workspace $w9
bindsym $mod+Shift+0 move container to workspace $w10
-
-# Cycle workspaces
-bindsym $mod+comma workspace prev
-bindsym $mod+period workspace next
Rules
Rules to automatically assign applications to workspaces and do other stuff, like enable floating.
Most apps can be distinguished by a WM class (you can get one with xprop), but in some cases it doesn’t work, e.g. for terminal applications. In that case rules can be based on a window title, for instance.
@@ -638,32 +651,48 @@ pid=$(xdot
bindsym $mod+g mode "inner gaps"
bindsym $mod+Shift+g mode "outer gaps"
Move & resize windows
-A more or less standard set of keybindings to move & resize floating windows.
-Just be careful to always make a way to return from these new modes, otherwise you’d end up in a rather precarious situation.
-# resize window (you can also use the mouse for that)
-mode "resize" {
- # These bindings trigger as soon as you enter the resize mode
+
+
+
+Guix dependency
+
+
+
+
+python-i3-balance-workspace
+
+
+
+A more or less standard set of keybindings to move & resize floating windows. Just be careful to always make a way to return from these new modes, otherwise you’d end up in a rather precarious situation.
+i3-balance-workspace is a small Python package to balance the i3 windows, but for the Emacs integration I also want this button to balance the Emacs windows, so here is a small script to do just that.
+if [[ $(xdotool getactivewindow getwindowname) =~ ^emacs(:.*)?@.* ]]; then
+ emacsclient -e "(balance-windows)" &
+fi
+i3_balance_workspace
+
mode "resize" {
- bindsym h resize shrink width 10 px or 10 ppt
- bindsym j resize grow height 10 px or 10 ppt
- bindsym k resize shrink height 10 px or 10 ppt
- bindsym l resize grow width 10 px or 10 ppt
+ bindsym h exec emacs-i3-integration resize shrink width 10 px or 10 ppt
+ bindsym j exec emacs-i3-integration resize grow height 10 px or 10 ppt
+ bindsym k exec emacs-i3-integration resize shrink height 10 px or 10 ppt
+ bindsym l exec emacs-i3-integration resize grow width 10 px or 10 ppt
- bindsym Shift+h resize shrink width 100 px or 100 ppt
- bindsym Shift+j resize grow height 100 px or 100 ppt
- bindsym Shift+k resize shrink height 100 px or 100 ppt
- bindsym Shift+l resize grow width 100 px or 100 ppt
+ bindsym Shift+h exec emacs-i3-integration resize shrink width 100 px or 100 ppt
+ bindsym Shift+j exec emacs-i3-integration resize grow height 100 px or 100 ppt
+ bindsym Shift+k exec emacs-i3-integration resize shrink height 100 px or 100 ppt
+ bindsym Shift+l exec emacs-i3-integration resize grow width 100 px or 100 ppt
# same bindings, but for the arrow keys
- bindsym Left resize shrink width 10 px or 10 ppt
- bindsym Down resize grow height 10 px or 10 ppt
- bindsym Up resize shrink height 10 px or 10 ppt
- bindsym Right resize grow width 10 px or 10 ppt
+ bindsym Left exec emacs-i3-integration resize shrink width 10 px or 10 ppt
+ bindsym Down exec emacs-i3-integration resize grow height 10 px or 10 ppt
+ bindsym Up exec emacs-i3-integration resize shrink height 10 px or 10 ppt
+ bindsym Right exec emacs-i3-integration resize grow width 10 px or 10 ppt
- bindsym Shift+Left resize shrink width 100 px or 100 ppt
- bindsym Shift+Down resize grow height 100 px or 100 ppt
- bindsym Shift+Up resize shrink height 100 px or 100 ppt
- bindsym Shift+Right resize grow width 100 px or 100 ppt
+ bindsym Shift+Left exec emacs-i3-integration resize shrink width 100 px or 100 ppt
+ bindsym Shift+Down exec emacs-i3-integration resize grow height 100 px or 100 ppt
+ bindsym Shift+Up exec emacs-i3-integration resize shrink height 100 px or 100 ppt
+ bindsym Shift+Right exec emacs-i3-integration resize grow width 100 px or 100 ppt
+
+ bindsym equal exec i3-emacs-balance-windows
# back to normal: Enter or Escape
bindsym Return mode "default"
@@ -2228,7 +2257,7 @@ clip=both
-Office
+Office & Multimedia
@@ -2249,6 +2278,18 @@ clip=both
office
krita
+
+office
+ffmpeg
+
+
+office
+kdenlive
+
+
+office
+inkscape
+
LaTeX
@@ -2343,6 +2384,10 @@ clip=both
dev
make
+
+dev
+sbcl
+
Manifests
@@ -2730,6 +2775,10 @@ aw-watcher-afk
gparted
Manage partitions
+
+xev
+Test input
+
diff --git a/public/configs/emacs/index.html b/public/configs/emacs/index.html
index 67cac72..561fdf1 100644
--- a/public/configs/emacs/index.html
+++ b/public/configs/emacs/index.html
@@ -121,6 +121,7 @@
- Zoom
+- i3 integration
- Editing helpers
- Visual fill column mode
@@ -461,6 +462,7 @@
- EMMS & mpd Fixes
+- ytel
- EWW
- ERC
- Google Translate
@@ -920,6 +922,110 @@
;; change font size, interactively
(global-set-key (kbd "C-+") 'my/zoom-in)
(global-set-key (kbd "C-=") 'my/zoom-out)
+
i3 integration
+One advantage of EXWM for an Emacs user is that EXWM gives one set of keybindings to manage both Emacs windows and X windows. In every other WM, like my preferred i3wm, two orthogonal keymaps seem to be necessary. But, as both programs are quite customizable, I want to see whether I can replicate at least some part of the EXWM goodness in i3.
+But why not just use EXWM? One key reason is that to my taste (and perhaps on my hardware) EXWM didn’t feel snappy enough. Also, I really like i3’s tree-based layout structure; I feel like it fits my workflow much better than anything else I tried, including the master/stack paradigm of XMonad, for instance.
+One common point of criticism of i3 is that it is not extensible enough, especially compared to WMs that are configured in an actual programing language, like the mentioned XMonad, Qtile, Awesome, etc. But I think i3’s extensibility is underappreciated, although the contents of this section may lie closer to the limits of how far one can go there.
+The basic idea is to launch a normal i3 command with i3-msg in case the current window is not Emacs, otherwise pass that command to Emacs with emacsclient. In Emacs, execute the command if possible, otherwise pass the command back to i3.
+This may seem like a lot of overhead, but I didn’t feel it even in the worst case (i3 -> Emacs -> i3), so at least in that regard, the interaction feels seamless. The only concern is that this command flow is vulnerable to Emacs getting stuck, but it is still much less of a problem than with EXWM.
+One interesting observation here is that Emacs windows and X windows are sort of one-level entities, so I can talk just about “windows”.
+At any rate, we need a script to do the i3 -> Emacs part:
+if [[ $(xdotool getactivewindow getwindowname) =~ ^emacs(:.*)?@.* ]]; then
+ command="(my/emacs-i3-integration \"$@\")"
+ emacsclient -e "$command"
+else
+ i3-msg $@
+fi
+
This script is being run from the i3 configuration.
+For this to work, we need to make sure that Emacs starts a server, so here is an expression to do just that:
+(add-hook 'after-init-hook #'server-start)
+
And here is a simple macro to do the Emacs -> i3 part:
+(defmacro i3-msg (&rest args)
+ `(start-process "emacs-i3-windmove" nil "i3-msg" ,@args))
+
Now we have to handle the required set of i3 commands. It is worth noting here that I’m not trying to implement a general mechanism to apply i3 commands to Emacs, rather I’m implementing a small subset that I use in my i3 configuration and that maps reasonably to the Emacs concepts.
+Also, I use evil-mode and generally configure the software to have vim-style bindings where possible. So if you don’t use evil-mode you’d have to detangle the given functions from evil, but then, I guess, you do not use super+hjkl to manage windows either.
+First, for the focus command I want to move to an Emacs window in the given direction if there is one, otherwise move to an X window in the same direction. Fortunately, i3 and windmove have the same names for directions, so the function is rather straightforward.
+One caveat here is that the minibuffer is always the bottom-most Emacs window, so it is necessary to check for that as well.
+(defun my/emacs-i3-windmove (dir)
+ (let ((other-window (windmove-find-other-window dir)))
+ (if (or (null other-window) (window-minibuffer-p other-window))
+ (i3-msg "focus" (symbol-name dir))
+ (windmove-do-window-select dir))))
+
For the move I want 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;
+- otherwise, move an X window (Emacs frame).
+
+For the first part, window-swap-states with windmove-find-other-window do well enough.
+evil-move-window works well for the second part. By itself it doesn’t behave quite like i3, for instance, (evil-move-window 'right) in a three-column split would move the window from the far left side to the far right side (bypassing center). Hence the combination as described here.
+So here is a simple predicate which checks whether there is space in the given direction.
+(defun my/emacs-i3-direction-exists-p (dir)
+ (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)))))
+
And the implementation of the move command.
+(defun my/emacs-i3-move-window (dir)
+ (let ((other-window (windmove-find-other-window dir))
+ (other-direction (my/emacs-i3-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))
+ (t (i3-msg "move" (symbol-name dir))))))
+
Next on the line are resize grow and resize shrink. evil-window- functions do nicely for this task.
+This function also checks whether there is space to resize in the given direction with the help of the predicate defined above. The command is forwarded back to i3 if there is not.
+(defun my/emacs-i3-resize-window (dir kind value)
+ (if (or (one-window-p)
+ (not (my/emacs-i3-direction-exists-p dir)))
+ (i3-msg "resize" (symbol-name kind) (symbol-name dir)
+ (format "%s px or %s ppt" value value))
+ (setq value (/ value 2))
+ (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)))))))
+
transpose-frame is a package to “transpose” the current frame layout, which behaves someone similar to the layout toggle split command in i3, so I’ll use it as well.
+(use-package transpose-frame
+ :straight t
+ :commands (transpose-frame))
+
Finally, the entrypoint for the Emacs integration. In addition to the commands defined above, it processes split and kill commands and passes every other command back to i3.
+(defun my/emacs-i3-integration (command)
+ (pcase command
+ ((rx bos "focus")
+ (my/emacs-i3-windmove
+ (intern (elt (split-string command) 1))))
+ ((rx bos "move")
+ (my/emacs-i3-move-window
+ (intern (elt (split-string command) 1))))
+ ((rx bos "resize")
+ (my/emacs-i3-resize-window
+ (intern (elt (split-string command) 2))
+ (intern (elt (split-string command) 1))
+ (string-to-number (elt (split-string command) 3))))
+ ("layout toggle split" (transpose-frame))
+ ("split h" (evil-window-split))
+ ("split v" (evil-window-vsplit))
+ ("kill" (evil-quit))
+ (- (i3-msg command))))
Editing helpers
Visual fill column mode
(use-package visual-fill-column
@@ -2901,7 +3007,7 @@ MimeType=x-scheme-handler/org-protocol
("." ,(list (all-the-icons-faicon "circle-o")) nil nil :ascent center))))
Export
General settings
-(setq org-export-backends '(md html latex beamer org))
+;; (setq org-export-backends '(md html latex beamer org))
Hugo
(use-package ox-hugo
:straight t
@@ -4744,6 +4850,35 @@ tag2: value2'
(when alist
(setq alists (cons alist alists)))
alists)))
+
ytel
+ytel is a YouTube (actually Invidious) frontend, which lets one search YouTube (whereas the setup with elfeed just lets one view the pre-defined subscriptions).
+The package doesn’t provide evil bindings, so I define my own.
+(use-package ytel
+ :straight t
+ :commands (ytel)
+ :config
+ (setq ytel-invidious-api-url "https://invidio.xamh.de/")
+ (general-define-key
+ :states '(normal)
+ :keymaps 'ytel-mode-map
+ "q" #'ytel-quit
+ "s" #'ytel-search
+ "L" #'ytel-search-next-page
+ "H" #'ytel-search-previous-page
+ "RET" #'my/ytel-add-emms))
+
And here is the same kind of integration with EMMS as in the elfeed setup:
+(with-eval-after-load 'emms
+ (define-emms-source ytel (video)
+ (let ((track (emms-track
+ 'url (concat "https://www.youtube.com/watch?v="
+ (ytel-video-id video)))))
+ (emms-track-set track 'info-title (ytel-video-title video))
+ (emms-track-set track 'info-artist (ytel-video-author video))
+ (emms-playlist-insert-track track))))
+
+(defun my/ytel-add-emms ()
+ (interactive)
+ (emms-add-ytel (ytel-get-current-video)))
EWW
Emacs built-in web browser. I wonder if anyone actually uses it.
I use it occasionally to open links in elfeed.
diff --git a/public/configs/index.xml b/public/configs/index.xml
index be960c9..078ab7d 100644
--- a/public/configs/index.xml
+++ b/public/configs/index.xml
@@ -26,7 +26,7 @@ if [ -z "$IS_ANDROID" ]; then GUIX_EXTRA_PROFILES=$HOME/.guix-ex
https://sqrtminusone.xyz/configs/desktop/
My general desktop environment configuration.
Parts prefixed with (OFF) are not used, but kept for historic purposes. For some reason GitHub’s org renderer ignores TODO status, hence such a prefix. Round brackets instead of square ones to prevent GitHub’s org renderer from screwing up.
- Table of Contents Global customization Colors Xresources Colors in Xresources Fonts Themes Device-specific settings i3wm General settings Managing windows Workspaces Rules Scratchpad Launch script i3 config Gaps & borders Keybindings Move & resize windows OFF (OFF) Intergration with dmenu Integration with rofi Launching apps & misc keybindings Apps Media controls & brightness Screenshots Colors OFF (OFF) i3blocks Keyboard Layout Autostart Polybar Launching General settings Colors Bar config Modules ipstack-vpn weather aw-afk sun SEP TSEP i3 xkeyboard mpd pulseaudio cpu ram-memory swap-memory network date battery Rofi Theme Scripts Buku bookmarks Man pages pass Flameshot dunst keynav Config Using with picom Picom Shadows Fading Opacity General settings Zathura Various software Browsers Office LaTeX Dev Manifests Flatpak Nix Services Music GNU Mcron ActivityWatch PulseEffects xsettingsd Discord rich presence Polkit Authentication agent Xmodmap VPN Davmail Shepherd config Sync Guix settings Global customization Colors Most of the colors are from the Palenight theme.
+ Table of Contents Global customization Colors Xresources Colors in Xresources Fonts Themes Device-specific settings i3wm General settings Managing windows Workspaces Rules Scratchpad Launch script i3 config Gaps & borders Keybindings Move & resize windows OFF (OFF) Intergration with dmenu Integration with rofi Launching apps & misc keybindings Apps Media controls & brightness Screenshots Colors OFF (OFF) i3blocks Keyboard Layout Autostart Polybar Launching General settings Colors Bar config Modules ipstack-vpn weather aw-afk sun SEP TSEP i3 xkeyboard mpd pulseaudio cpu ram-memory swap-memory network date battery Rofi Theme Scripts Buku bookmarks Man pages pass Flameshot dunst keynav Config Using with picom Picom Shadows Fading Opacity General settings Zathura Various software Browsers Office & Multimedia LaTeX Dev Manifests Flatpak Nix Services Music GNU Mcron ActivityWatch PulseEffects xsettingsd Discord rich presence Polkit Authentication agent Xmodmap VPN Davmail Shepherd config Sync Guix settings Global customization Colors Most of the colors are from the Palenight theme.
-
diff --git a/public/ox-hugo/literate-config.png b/public/ox-hugo/literate-config.png
index 99ee4a0..fd508de 100644
Binary files a/public/ox-hugo/literate-config.png and b/public/ox-hugo/literate-config.png differ
diff --git a/static/ox-hugo/literate-config.png b/static/ox-hugo/literate-config.png
index 99ee4a0..fd508de 100644
Binary files a/static/ox-hugo/literate-config.png and b/static/ox-hugo/literate-config.png differ