diff --git a/content/configs/Console.md~ b/content/configs/Console.md~ index 42884da..e0306c5 100644 --- a/content/configs/Console.md~ +++ b/content/configs/Console.md~ @@ -529,6 +529,17 @@ bind -M insert \eb backward-word ``` +### Functions {#functions} + +A small function to open the file with `$EDITOR`. + +```fish +function e + eval $EDITOR $argv +end +``` + + ## Nushell {#nushell} | Guix dependency | diff --git a/content/configs/Desktop.md b/content/configs/Desktop.md index 166d31d..83defa2 100644 --- a/content/configs/Desktop.md +++ b/content/configs/Desktop.md @@ -82,7 +82,7 @@ Parts prefixed with (OFF) are not used, but kept for historic purposes. For some - [Zathura](#zathura) - [Various software](#various-software) - [Browsers](#browsers) - - [Office](#office) + - [Office & Multimedia](#office-and-multimedia) - [LaTeX](#latex) - [Dev](#dev) - [Manifests](#manifests) @@ -302,47 +302,60 @@ bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcu ### Managing windows {#managing-windows} +| 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]({{< relref "Emacs" >}}) for details. + Kill focused windows ```vim -bindsym $mod+Shift+q kill +bindsym $mod+Shift+q exec emacs-i3-integration kill ``` Change focus ```vim -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 ```vim -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 ```vim -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 + +```vim +bindsym $mod+period exec i3-switch-tabs right +bindsym $mod+comma exec i3-switch-tabs left ``` Enter fullscreen mode @@ -350,6 +363,7 @@ Enter fullscreen mode ```vim # enter fullscreen mode for the focused container bindsym $mod+f fullscreen toggle +bindsym $mod+c fullscreen toggle global ``` Changing layout @@ -357,7 +371,7 @@ Changing layout ```vim 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 @@ -428,10 +442,6 @@ bindsym $mod+Shift+7 move container to workspace $w7 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 ``` @@ -575,35 +585,46 @@ bindsym $mod+Shift+g mode "outer gaps" ### Move & resize windows {#move-and-resize-windows} -A more or less standard set of keybindings to move & resize floating windows. +| Guix dependency | +|-----------------------------| +| python-i3-balance-workspace | -Just be careful to always make a way to return from these new modes, otherwise you'd end up in a rather precarious situation. +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](https://github.com/atreyasha/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. + +```bash +if [[ $(xdotool getactivewindow getwindowname) =~ ^emacs(:.*)?@.* ]]; then + emacsclient -e "(balance-windows)" & +fi +i3_balance_workspace +``` ```vim -# resize window (you can also use the mouse for that) mode "resize" { - # These bindings trigger as soon as you enter the resize mode - 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" @@ -2333,13 +2354,16 @@ This section generates manifests for various desktop software that I'm using. | browsers | firefox | -### Office {#office} +### Office & Multimedia {#office-and-multimedia} | Category | Guix dependency | |----------|-----------------| | office | libreoffice | | office | gimp | | office | krita | +| office | ffmpeg | +| office | kdenlive | +| office | inkscape | ### LaTeX {#latex} @@ -2370,6 +2394,7 @@ This section generates manifests for various desktop software that I'm using. | dev | libfaketime | | dev | hugo-extended | | dev | make | +| dev | sbcl | ### Manifests {#manifests} @@ -2756,6 +2781,7 @@ Other desktop programs I use are listed below. | anydesk | Remote desktop software | | gnome-disk-utility | Manage disks | | gparted | Manage partitions | +| xev | Test input | ```emacs-lisp diff --git a/content/configs/Emacs.md b/content/configs/Emacs.md index ca55e84..4b03fff 100644 --- a/content/configs/Emacs.md +++ b/content/configs/Emacs.md @@ -49,6 +49,7 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept - [xref](#xref) - [Folding](#folding) - [Zoom](#zoom) + - [i3 integration](#i3-integration) - [Editing helpers](#editing-helpers) - [Visual fill column mode](#visual-fill-column-mode) - [smartparens](#smartparens) @@ -256,6 +257,7 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept - [Fetching lyrics](#fetching-lyrics) - [Some keybindings](#some-keybindings) - [EMMS & mpd Fixes](#emms-and-mpd-fixes) + - [ytel](#ytel) - [EWW](#eww) - [ERC](#erc) - [Google Translate](#google-translate) @@ -948,6 +950,161 @@ Evil does a pretty good job of uniting these two in the set of vim-like keybindi ``` +### i3 integration {#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](https://i3wm.org), 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](https://xmonad.org/)​, 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](http://www.qtile.org/), [Awesome](https://awesomewm.org/), 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: + +```bash +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]({{< relref "Desktop" >}}). + +For this to work, we need to make sure that Emacs starts a server, so here is an expression to do just that: + +```emacs-lisp +(add-hook 'after-init-hook #'server-start) +``` + +And here is a simple macro to do the Emacs -> i3 part: + +```emacs-lisp +(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](https://github.com/emacs-evil/evil) 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. + +```emacs-lisp +(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. + +```emacs-lisp +(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. + +```emacs-lisp +(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. + +```emacs-lisp +(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](https://github.com/emacsorphanage/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. + +```emacs-lisp +(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. + +```emacs-lisp +(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 {#editing-helpers} @@ -3621,7 +3778,7 @@ Categories are broad labels to group agenda items. #### General settings {#general-settings} ```emacs-lisp -(setq org-export-backends '(md html latex beamer org)) +;; (setq org-export-backends '(md html latex beamer org)) ``` @@ -6070,6 +6227,46 @@ The list will be in reverse order." ``` +#### ytel {#ytel} + +[ytel](https://github.com/gRastello/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. + +```emacs-lisp +(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: + +```emacs-lisp +(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 {#eww} Emacs built-in web browser. ~~I wonder if anyone actually uses it.~~ diff --git a/content/configs/Emacs.md~ b/content/configs/Emacs.md~ index b3142cc..ca55e84 100644 --- a/content/configs/Emacs.md~ +++ b/content/configs/Emacs.md~ @@ -107,6 +107,7 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept - [Configuration](#configuration) - [Subterminal](#subterminal) - [Dired integration](#dired-integration) + - [With-editor integration](#with-editor-integration) - [Eshell](#eshell) - [Org Mode](#org-mode) - [Installation & basic settings](#installation-and-basic-settings) @@ -205,8 +206,10 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept - [Meta Lisp](#meta-lisp) - [Emacs Lisp](#emacs-lisp) - [Package Lint](#package-lint) - - [General](#general) + - [General settings](#general-settings) - [Common lisp](#common-lisp) + - [SLIME](#slime) + - [General settings](#general-settings) - [Clojure](#clojure) - [Hy](#hy) - [Scheme](#scheme) @@ -734,7 +737,8 @@ I don't enable the entire package, just the modes I need. comint git-timemachine magit - prodigy))) + prodigy + slime))) ``` @@ -886,6 +890,7 @@ And winner-mode to keep the history of window states. "h" 'previous-buffer "k" 'kill-buffer "b" 'persp-ivy-switch-buffer + "r" 'revert-buffer "u" 'ibuffer) ``` @@ -1562,7 +1567,9 @@ References: (use-package yasnippet :straight t :config - (setq yas-snippet-dirs `(,(concat (expand-file-name user-emacs-directory) "snippets"))) + (setq yas-snippet-dirs + `(,(concat (expand-file-name user-emacs-directory) "snippets") + yasnippet-snippets-dir)) (setq yas-triggers-in-field t) (yas-global-mode 1)) @@ -2486,6 +2493,21 @@ Keybindings: ``` +#### With-editor integration {#with-editor-integration} + +A package used by Magit to use the current Emacs instance as the `$EDITOR`. + +That is, with the help of [this function]({{< relref "Console" >}}), I can just write `e `, edit the file, and then return to the same vterm buffer. No more running vim inside Emacs. + +```emacs-lisp +(use-package with-editor + :straight t + :after (vterm) + :config + (add-hook 'vterm-mode-hook 'with-editor-export-editor)) +``` + + ### Eshell {#eshell} A shell written in Emacs lisp. I don't use it as of now, but keep the config just in case. @@ -3162,7 +3184,7 @@ So, here is a list of queries results of which I want to see in the review templ (todo "DONE"))) ("Attended meetings" closed scheduled (and - (tags "meeting") + (tags-inherited "meeting") (todo "PASSED"))) ("Done project tasks" closed deadline (and @@ -4319,7 +4341,6 @@ Configs for various web development technologies I'm using. | Type | Note | |------|---------------------------------------------------| -| TODO | Do not enable for every Svelte mode | | TODO | make expand div[disabled] as
| My bit of config here: @@ -5008,7 +5029,7 @@ A package that checks for the metadata in Emacs Lisp packages. ``` -##### General {#general} +##### General settings {#general-settings} ```emacs-lisp (add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode) @@ -5019,6 +5040,20 @@ A package that checks for the metadata in Emacs Lisp packages. #### Common lisp {#common-lisp} + +##### SLIME {#slime} + +```emacs-lisp +(use-package slime + :straight t + :config + (setq inferior-lisp-program "sbcl") + (add-hook 'slime-repl-mode 'smartparens-mode)) +``` + + +##### General settings {#general-settings} + ```emacs-lisp (add-hook 'lisp-mode-hook #'aggressive-indent-mode) ;; (add-hook 'emacs-lisp-mode-hook #'smartparens-strict-mode) diff --git a/content/configs/Guix.md~ b/content/configs/Guix.md~ index 0a72480..4e866d0 100644 --- a/content/configs/Guix.md~ +++ b/content/configs/Guix.md~ @@ -20,7 +20,6 @@ References:
Table of Contents
-- [Contents](#contents) - [Profiles](#profiles) - [Activate profiles](#activate-profiles) - [Update profiles](#update-profiles) @@ -49,34 +48,6 @@ References: -## Contents {#contents} - -- [Contents](#contents) -- [Profiles](#profiles) - - [Activate profiles](#activate-profiles) - - [Update profiles](#update-profiles) -- [Channels](#channels) -- [Systems](#systems) - - [Base configuration](#base-configuration) - - [indigo](#indigo) - - [eminence](#eminence) - - [azure](#azure) -- [System installation](#system-installation) - - [Preparation](#preparation) - - [Installation](#installation) - - [After installation](#after-installation) -- [Misc software & notes](#misc-software-and-notes) - - [VPN](#vpn) - - [vpn-start](#vpn-start) - - [vpn-stop](#vpn-stop) - - [flatpak](#flatpak) - - [conda](#conda) - - [Slack](#slack) - - [virt-manager](#virt-manager) - - [wakatime-cli](#wakatime-cli) - - [Manifest](#manifest) - - ## Profiles {#profiles} A profile is a way to group Guix packages. Amongst its advantages, profiles can be defined by manifests, which in turn can be stored in VCS. @@ -535,7 +506,7 @@ Fortunately, David Wilson has made [a repository](https://github.com/SystemCraft When an ISO is there, we have to write it on a USB stick. Run `sudo fdisk -l` to get a list of disks. -The approach in the official instruction is to create a bootable USB with `dd`: +The approach given in the official instruction is to create a bootable USB with `dd`: ```text sudo dd of=/dev/sdxX if= status=progress && sync @@ -553,7 +524,7 @@ Going further, the official instructions for installation & SystemCrafters wiki After the installation, the strategy is as follows. -Set a password for the main user (pavel). Login with openbox to get a tolerable interface because the i3 default config is horrible. +Set a password for the main user (pavel). Login with openbox to get a tolerable interface because i3's default config is horrible. [Connect to the internet](https://guix.gnu.org/en/manual/en/html%5Fnode/Keyboard-Layout-and-Networking-and-Partitioning.html#Keyboard-Layout-and-Networking-and-Partitioning). @@ -600,9 +571,9 @@ Don't forget to install `JetBrainsMono Nerd Font`. | system | openvpn-update-resolve-conf | | system | vpnc | -I'm not sure how to properly spin up VPN on Guix, so here is what I'm doing now, after some trial and error. +I'm not sure how to properly spin up VPN on Guix, so here is what ended I'm doing after some trial and error. -I'm currently using CyberGhost VPN. `~/.vpn` folder stores its OpenVPN config (`openvpn.ovpn`), modified as follows: +I'm using CyberGhost VPN. `~/.vpn` folder stores its OpenVPN config (`openvpn.ovpn`), modified as follows: - paths to `ca`, `cert` and `key` are made absolute @@ -707,9 +678,9 @@ It is packaged for GNU Guix, although the definition has its fair share of worka First, it's impossible to perform `conda init` to patch files like `.bashrc`, because the command is hell-bent on modifying `/gnu/store/`. So I do this manually, look for the `init_conda` procedures in [Console.org]({{< relref "Console" >}}). -Second, base environment root is `/gnu/store`, so don't install anything there. +Second, the base environment has `/gnu/store/...` as a root, so don't install anything there (and don't run `conda` with superuser rights!). -Third, by default it tries to create envronments in `/gnu/store`. I think it's enough to create one environment like this to fix it: +Third, by default it tries to create envronments in `/gnu/store`. It's enough to create one environment like this to fix it: ```sh mkdir -p ~/.conda/envs @@ -723,7 +694,7 @@ Finally, I also want to have an ability to use global npm. Some settings for tha So here is a script to set up conda hooks: ```bash -# Get writable conda envs with npm & without +# Get writable conda envs with npm & without it readarray -t CONDA_ENVS_ALL <<< $(conda env list --json | jq '.envs[]') CONDA_ENVS_NPM=() CONDA_ENVS_NO_NPM=() diff --git a/content/configs/Mail.md~ b/content/configs/Mail.md~ index aca7abe..c8bbe86 100644 --- a/content/configs/Mail.md~ +++ b/content/configs/Mail.md~ @@ -76,6 +76,8 @@ davmail.server=true davmail.mode=Auto davmail.url=https://mail.etu.ru/owa/ +davmail.server.certificate.hash=0C:9E:CF:D3:62:26:DB:FA:F1:EE:36:9D:60:E7:31:71:CF:1F:92:85 + davmail.caldavPort=1080 davmail.imapPort=1143 davmail.ldapPort=1389 diff --git a/public/configs/desktop/index.html b/public/configs/desktop/index.html index 4206d87..ca17033 100644 --- a/public/configs/desktop/index.html +++ b/public/configs/desktop/index.html @@ -174,7 +174,7 @@
  • Various software
    • Browsers
    • -
    • Office
    • +
    • Office & Multimedia
    • LaTeX
    • Dev
    • Manifests
    • @@ -451,39 +451,56 @@ # exit i3 (logs you out of your X session) bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"

      Managing windows

      + + + + + + + + + + + +
      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
      officeffmpeg
      officekdenlive
      officeinkscape

      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
  • +
  • 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 &#34;$IS_ANDROID&#34; ]; 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&rsquo;s org renderer ignores TODO status, hence such a prefix. Round brackets instead of square ones to prevent GitHub&rsquo;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 &amp; borders Keybindings Move &amp; resize windows OFF (OFF) Intergration with dmenu Integration with rofi Launching apps &amp; misc keybindings Apps Media controls &amp; 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 &amp; borders Keybindings Move &amp; resize windows OFF (OFF) Intergration with dmenu Integration with rofi Launching apps &amp; misc keybindings Apps Media controls &amp; 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 &amp; 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