diff --git a/org/config/stumpwm.org b/org/config/stumpwm.org
index 063b8d2..adfa986 100644
--- a/org/config/stumpwm.org
+++ b/org/config/stumpwm.org
@@ -3,7 +3,8 @@
#+OPTIONS: auto-id:t
#+HTML_HEAD_EXTRA:
#+HTML_HEAD_EXTRA:
-#+HTML_HEAD_EXTRA:
+#+HTML_HEAD_EXTRA:
+#+property: header-args:emacs-lisp :tangle no :exports results :cache yes :noweb yes
* Introduction
:PROPERTIES:
@@ -140,7 +141,7 @@ Now, we’ll load a couple of my custom files that will be described below:
| modeline.lisp |
#+name: gen-load-files
-#+headers: :tangle no :exports results :wrap src lisp :cache yes
+#+headers: :wrap src lisp
#+begin_src emacs-lisp :var files=first-loaded-files
(mapconcat (lambda (file)
(format "(load \"~/.stumpwm.d/%s\")" (car file)))
@@ -175,23 +176,20 @@ windows.
#+end_src
Next, some modules will be loaded from the ~stumpwm-contrib~ package
-(which is included in ~stumpwm-git~). Here is a short list including a
-short description of what they are for:
+(which is included in ~stumpwm-git~ in the AUR). Here is a short list
+including a short description of what they are for:
#+name: loaded-modules
-| Module Name | Why It Is Loaded |
-|------------------+------------------------------------------------------------|
-| alert-me | Creates notifications, can also create timed notifications |
-| battery-portable | Get information on the battery level of a laptop |
-| beckon | Bring the mouse cursor to the current window |
-| cpu | Get the CPU usage of the computer |
-| end-session | Gracefully end programs when ending user session |
-| globalwindows | Navigate between windows from all workspaces |
-| mem | Get the memory usage of the computer |
-| stump-backlight | Native management of backlight in StumpWM |
-| urgentwindows | Get urgent windows |
+| Module Name | Why It Is Loaded |
+|-----------------+------------------------------------------------------------|
+| alert-me | Creates notifications, can also create timed notifications |
+| beckon | Bring the mouse cursor to the current window |
+| end-session | Gracefully end programs when ending user session |
+| globalwindows | Navigate between windows from all workspaces |
+| stump-backlight | Native management of backlight in StumpWM |
+| urgentwindows | Get urgent windows |
#+name: gen-load-modules
-#+headers: :tangle no :exports results :wrap src lisp :cache yes
+#+headers: :wrap src lisp
#+begin_src emacs-lisp :var modules=loaded-modules
(mapconcat (lambda (module)
(format "(load-module \"%s\")" (car module)))
@@ -199,15 +197,12 @@ short description of what they are for:
"\n")
#+end_src
-#+RESULTS[1978f17a99db4ca68780c378e5e5d9d58f9e08bc]: gen-load-modules
+#+RESULTS[508e36f9747f1da901bbee63582416a8a6ba2c2f]: gen-load-modules
#+begin_src lisp
(load-module "alert-me")
-(load-module "battery-portable")
(load-module "beckon")
-(load-module "cpu")
(load-module "end-session")
(load-module "globalwindows")
-(load-module "mem")
(load-module "stump-backlight")
(load-module "urgentwindows")
#+end_src
@@ -224,17 +219,41 @@ And it’s done! We can now move on to the creation of the other CLisp files.
:CUSTOM_ID: Commands-1wagy001v5j0
:header-args:lisp: :mkdirp :tangle ~/.stumpwm.d/commands.lisp
:END:
-This file is going to be short. The only two custom command I have is
-for Firefox, in order to either invoke a new Firefox window, or raise
-it if it already exists, and for Emacs to invoke the Emacs client or a
-new Emacs instance if the server isn’t running. This is done like so:
+
+The first command I declare in this file is a command that will avoid
+me invoking too many Firefox instances. Either Firefox is not already
+running and an instance is launched, or one already is and we are
+brought to it. This is done like so:
#+begin_src lisp
(defcommand firefox () ()
"Run or raise Firefox."
(run-or-raise "firefox" '(:class "Firefox") t nil))
#+end_src
-And done, next!
+Next, this command will not only close the current window, but it will
+also close the current frame.
+#+begin_src lisp
+ (defcommand delete-window-and-frame () ()
+ "Delete the current frame with its window."
+ (delete-window)
+ (remove-split))
+#+end_src
+
+The two following commands will create a new frame to the right and
+below the current frame respectively, then focus it.
+#+begin_src lisp
+ (defcommand hsplit-and-focus () ()
+ "Create a new frame on the right and focus it."
+ (hsplit)
+ (move-focus :right))
+
+ (defcommand vsplit-and-focus () ()
+ "Create a new frame below and move focus to it."
+ (vsplit)
+ (move-focus :down))
+#+end_src
+
+And done! Next!
* Colors
:PROPERTIES:
@@ -268,7 +287,7 @@ I’ll prefix the variables’ name with ~phundrak-~ just in case it might
conflict with another package I might use in the future, so the CLisp
code looks like so:
#+name: gen-colors
-#+headers: :tangle no :exports results :wrap src lisp :cache yes
+#+headers: :wrap src lisp
#+begin_src emacs-lisp :var colors=nord-colors
(mapconcat (lambda (color)
(format "(defvar phundrak-%s \"%s\")" (car color) (cadr color)))
@@ -337,7 +356,7 @@ format indicated in the manpage of ~date~.
Let’s also indicate how the groupname is displayed.
#+begin_src lisp
- (setf *group-format* " %t ")
+ (setf *group-format* "%t")
#+end_src
The window format should display first its window number, then its
@@ -346,6 +365,30 @@ titled, limited to 30 characters.
(setf *window-format* "%n: %30t")
#+end_src
+Here are some modules that we will load for the modeline:
+#+name: modeline-modules
+| Module Name | Why It Is Loaded |
+|------------------+--------------------------------------------------|
+| battery-portable | Get information on the battery level of a laptop |
+| cpu | Get the CPU usage of the computer |
+| mem | Get the memory usage of the computer |
+
+#+name: gen-load-modeline-modules
+#+headers: :wrap src lisp
+#+begin_src emacs-lisp :var modules=modeline-modules
+ (mapconcat (lambda (module)
+ (format "(load-module \"%s\")" (car module)))
+ modules
+ "\n")
+#+end_src
+
+#+RESULTS[75023085d7c69ae09044826218830e6b678d5959]: gen-load-modeline-modules
+#+begin_src lisp
+(load-module "battery-portable")
+(load-module "cpu")
+(load-module "mem")
+#+end_src
+
We can indicate what to display in our modeline. Be aware the ~^>~
string will align the rest of the string to the right of the modeline.
~%g~ will display the group list, while ~%v~ will display the list of
@@ -354,7 +397,7 @@ highlighted, and ~%u~ will display urgent windows if there are any. ~%d~
on the other hand will display the date in the format set above, while
~%B~ will display the battery level of the laptop.
#+begin_src lisp
- (setf *screen-mode-line-format* (list "%g %v ^> %C | %M | %B | %d"))
+ (setf *screen-mode-line-format* (list "%g %v %u ^> %C | %M | %B | %d"))
#+end_src
This variable as you can see is a list of elements, although here I am
@@ -363,6 +406,15 @@ CLisp code in here that returns some string if the user needs some
code to return data that cannot be easily accesible otherwise. I might
add some at some point, but not today yet.
+For some reason, the ~stumptray~ module does not work for me, I get an
+error saying a certain value is of type ~NIL~ and not of type
+~STUMPWM:MODELINE~. I should investigate this.
+
+** TODO Investigate why ~stumptray~ doesn’t work :noexport:
+:PROPERTIES:
+:CUSTOM_ID: Modeline-Investigate-why-stumptray-doesn-t-work-0juh13g0m6j0
+:END:
+
# Also, let’s enable a system tray.
# #+begin_src lisp
# (load-module "stumptray")
@@ -381,42 +433,36 @@ I’ve been used to ten groups, or workspaces, or tags, since I began
using tiling window managers. I shall then continue this habit. Here
is the list of groups I will be using:
#+name: list-groups
-| Groups |
-|----------|
-| term |
-| emacs |
-| www |
-| files |
-| media |
-| graphics |
-| VMs |
-| games |
-| private |
-| discord |
+| Groups | Number | Windows |
+|---------+--------+----------------------------|
+| [SYS] | 1 | |
+| [DEV] | 2 | Emacs, Virt-manager |
+| [WWW] | 3 | Firefox |
+| [FILES] | 4 | Nemo |
+| [MEDIA] | 5 | Gimp |
+| [SOC] | 6 | Signal, discord, lightcord |
+| [PRIV] | 7 | |
#+name: gen-groups
#+headers: :tangle no :exports none :cache yes
#+begin_src emacs-lisp :var groups=list-groups
- (string-join `(,(format "(grename \"%s\")" (car (car groups)))
- ,@(mapcar (lambda (group)
- (format "(gnewbg \"%s\")" (car group)))
- (cdr groups)))
- "\n")
+ (string-trim (string-join `(,(format "(grename \"%s\")" (car (car groups)))
+ ,@(mapcar (lambda (group)
+ (format "(gnewbg \"%s\")" (car group)))
+ (cdr groups)))
+ "\n")
+ "[[:space:]]*"
+ "[[:space:]]*")
#+end_src
-#+RESULTS[ed2b45d9a542233061373da32e830bd27a68d61b]: gen-groups
-#+begin_example
-(grename "term")
-(gnewbg "emacs")
-(gnewbg "www")
-(gnewbg "files")
-(gnewbg "media")
-(gnewbg "graphics")
-(gnewbg "VMs")
-(gnewbg "games")
-(gnewbg "private")
-(gnewbg "discord")
-#+end_example
+#+RESULTS[caa45af7c6ee092f88acb86d974cf0c9c93b2a3e]: gen-groups
+: (grename "[SYS]")
+: (gnewbg "[DEV]")
+: (gnewbg "[WWW]")
+: (gnewbg "[FILES]")
+: (gnewbg "[MEDIA]")
+: (gnewbg "[SOC]")
+: (gnewbg "[PRIV]")
Groups are specified this way:
#+begin_src lisp
@@ -430,51 +476,46 @@ this will avoid unexpected and hard-to-debug behavior.
(clear-window-placement-rules)
#+end_src
-Now we can define our window placement preferences. For now, all rely
-on the window’s class, so it will be pretty straightforward to write.
-#+name: frame-preferences
-| Window Class | Group |
-|--------------+---------|
-| Emacs | emacs |
-| Firefox | browser |
-| Nemo | files |
-| Gimp | media |
-| Signal | private |
-| lightcord | discord |
-| Steam | games |
-| Virt-manager | VMs |
-
+As you can see in the table [[list-groups]] above, I also indicated my
+window placement preferences. For now, they all rely on the window’s
+class, so it will be pretty straightforward to the corresponding code.
#+name: gen-rules
#+headers: :tangle no :exports results :cache yes :wrap src lisp
-#+begin_src emacs-lisp :var rules=frame-preferences
- (mapconcat (lambda (rule)
- (let ((class (car rule))
- (group (cadr rule)))
- (format "(define-frame-preference \"%s\"
- (nil t t :class \"%s\"))" group class)))
- rules
- "\n")
+#+begin_src emacs-lisp :var rules=list-groups
+ (require 'seq)
+ (let ((output "")
+ (rules (seq-filter (lambda (rule) rule)
+ (mapcar (lambda (line)
+ (let ((classes (caddr line)))
+ (unless (string= "" classes)
+ (cons
+ (split-string classes "," t "[[:space:]]*")
+ (car line)))))
+ rules))))
+ (progn
+ (seq-do (lambda (rule)
+ (let ((classes (car rule))
+ (group (cdr rule)))
+ (dolist (class classes)
+ (setf output (format "%s\n%s"
+ `(define-frame-preference ,(format "\"%s\"" group)
+ (nil t t :class ,(format "\"%s\"" class)))
+ output)))))
+ rules)
+ output))
#+end_src
This can be written this way:
-#+RESULTS[b493d3cb9cae1fc97cdb4eb5dc56c9440fde0b2b]: gen-rules
+#+RESULTS[1c9490c15e3cc7d2c8ed1c508cab844567232afc]: gen-rules
#+begin_src lisp
-(define-frame-preference "emacs"
- (nil t t :class "Emacs"))
-(define-frame-preference "browser"
- (nil t t :class "Firefox"))
-(define-frame-preference "files"
- (nil t t :class "Nemo"))
-(define-frame-preference "media"
- (nil t t :class "Gimp"))
-(define-frame-preference "private"
- (nil t t :class "Signal"))
-(define-frame-preference "discord"
- (nil t t :class "lightcord"))
-(define-frame-preference "games"
- (nil t t :class "Steam"))
-(define-frame-preference "VMs"
- (nil t t :class "Virt-manager"))
+(define-frame-preference "[SOC]" (nil t t :class "lightcord"))
+(define-frame-preference "[SOC]" (nil t t :class "discord"))
+(define-frame-preference "[SOC]" (nil t t :class "Signal"))
+(define-frame-preference "[MEDIA]" (nil t t :class "Gimp"))
+(define-frame-preference "[FILES]" (nil t t :class "Nemo"))
+(define-frame-preference "[WWW]" (nil t t :class "Firefox"))
+(define-frame-preference "[DEV]" (nil t t :class "Virt-manager"))
+(define-frame-preference "[DEV]" (nil t t :class "Emacs"))
#+end_src
* Theme
@@ -511,24 +552,29 @@ again src_lisp[:exports code]{(ql:quickload :clx-truetype)} without an
issue (running it again is necessary to install its dependencies).
Now that this is out of the way, let’s add two lines so we can use TTF
-and OTF fonts:
+fonts:
#+begin_src lisp
(ql:quickload :clx-truetype)
(load-module "ttf-fonts")
#+end_src
+The documentation says we should be able to also use OTF fonts, but so
+far I’ve had no luck loading one. Loading more than one font to use
+some fallback fonts also doesn’t seem to work, unlike specified in the
+documentation (I wanted to use a CJK font, but it doesn’t appear to
+work).
-Something that didn’t click immediately for me (and I think StumpWM’s
-documentation on this could be improved) is that ~set-font~ can be used
-to set either one main font for StumpWM, as one might guess reading
-the documentation --- or you can set a list of them! And this is
-great, since my main font does not support some characters I regularly
-have in my windows’ title, such as CJK characters, emojis and all!
-Here is my list of fonts I want loaded:
+# Something that didn’t click immediately for me (and I think StumpWM’s
+# documentation on this could be improved) is that ~set-font~ can be used
+# to set either one main font for StumpWM, as one might guess reading
+# the documentation --- or you can set a list of them! And this is
+# great, since my main font does not support some characters I regularly
+# have in my windows’ title, such as CJK characters, emojis and all!
+# Here is my list of fonts I want loaded:
#+name: list-fonts
-| Family | Subfamily | Size |
-|-------------+-----------+------|
-| DejaVu Sans | Book | 9 |
-| IPAMincho | Regular | 11 |
+| Family | Subfamily | Size |
+|------------------+-----------+------|
+| DejaVu Sans Mono | Book | 8 |
+# | IPAMincho | Regular | 11 |
#+name: gen-fonts
#+headers: :tangle no :exports results :cache yes :wrap src lisp
@@ -548,10 +594,9 @@ Here is my list of fonts I want loaded:
#+end_src
The code equivalent of this table can be seen below:
-#+RESULTS[054585246a49cd88836d4c5ea1aad66c1bc97f8a]: gen-fonts
+#+RESULTS[ca1ca106ad10eea84a34362acfc543eba559260c]: gen-fonts
#+begin_src lisp
-(set-font `(,(make-instance 'xft:font :family "DejaVu Sans" :subfamily "Book" :size 11 :antialias t)
- ,(make-instance 'xft:font :family "IPAMincho" :subfamily "Regular" :size 11 :antialias t)))
+(set-font `(,(make-instance 'xft:font :family "DejaVu Sans Mono" :subfamily "Book" :size 8 :antialias t)))
#+end_src
*** TODO Font error in modeline with Japanese :noexport:
@@ -691,26 +736,143 @@ Also, let’s enable ~which-key~:
(which-key-mode)
#+end_src
-#+name: keybinds-gen
-#+headers: :tangle no :exports none :cache yes :noweb yes
-#+begin_src emacs-lisp :var map="m" keybinds=frames-float
- (mapconcat (lambda (keybind)
- (format "%s" (let ((key (string-replace "~" "" (car keybind)))
- (function (string-replace "~" "" (cadr keybind))))
- `(define-key ,map
- (kbd ,(format "\"%s\"" key))
- ,(if (string-prefix-p "'" function t)
- function
- (format "\"%s\"" function))))))
- keybinds
- "\n")
+Lastly, before we get more into details, keep in mind that I use the
+[[https://bepo.fr][bépo]] layout, as I often say in my different documents. This means the
+characters found in the numbers’ row when pressing shift are actually
+the numbers themselves. Below are the following characters:
+#+name: number-to-char-table
+| Number | Character |
+|--------+-----------|
+| 1 | ~"~ |
+| 2 | ~«~ |
+| 3 | ~»~ |
+| 4 | ~(~ |
+| 5 | ~)~ |
+| 6 | ~@~ |
+| 7 | ~+~ |
+| 8 | ~-~ |
+| 9 | ~/~ |
+| 0 | ~*~ |
+
+So if you see any weird keybind involving these characters, this is
+because of my layout.
+
+** Applications
+:PROPERTIES:
+:CUSTOM_ID: Keybinds-Applications-2t512k00w5j0
+:END:
+When I speak about applications, I speak about programs and scripts in
+general. With these keymaps, I can launch programs I often have use
+for, but I can also launch some scripts as well as take screenshots.
+
+First, let’s create my ~rofi~ scripts keymap.
+#+name: rofi-scripts
+#+caption: ~*my-rofi-keymap*~
+| Keychord | Function |
+|----------+-----------------------------------------------|
+| ~a~ | ~exec awiki~ |
+| ~r~ | ~exec rofi -combi-modi drun,window -show combi~ |
+| ~s~ | ~exec rofi -show ssh~ |
+| ~p~ | ~exec rofi-pass -t~ |
+| ~P~ | ~exec rofi-pass~ |
+| ~e~ | ~exec rofi-emoji~ |
+| ~m~ | ~exec rofi-mount~ |
+| ~u~ | ~exec rofi-umount~ |
+| ~w~ | ~exec wacom-setup~ |
+| ~y~ | ~exec ytplay~ |
+| ~Y~ | ~exec rofi-ytdl~ |
+
+Here’s the equivalent in Common Lisp.
+#+begin_src lisp
+ (defvar *my-rofi-keymap*
+ (let ((m (make-sparse-keymap)))
+ <>
+ m))
#+end_src
-#+RESULTS[5938b2a6efd9c8b565416f9a687bc0d6a4a5f77e]: keybinds-gen
-: (define-key m (kbd "f") "float-this")
-: (define-key m (kbd "F") "unfloat-this")
-: (define-key m (kbd "u") "unfloat-this")
-: (define-key m (kbd "C-f") "flatten-floats")
+Let’s also create a keymap for screenshots.
+#+name: screenshot-keymap
+#+caption: ~*my-screenshot-keymap*~
+| Keychord | Function |
+|----------+------------------------------------------------------|
+| ~d~ | ~exec scrot -d 3 -e 'mv $f ~/Pictures/Screenshots'~ |
+| ~s~ | ~exec scrot -e 'mv $f ~/Pictures/Screenshots'~ |
+| ~S~ | ~exec scrot -s -e 'mv $f ~/Pictures/Screenshots'~ |
+| ~g~ | ~exec scrot -e 'gimp $f; mv $f ~/Pictures/Screenshots'~ |
+
+Here’s the equivalent in Common Lisp.
+#+begin_src lisp
+ (defvar *my-screenshot-keymap*
+ (let ((m (make-sparse-keymap)))
+ <>
+ m))
+#+end_src
+
+We can now define our applications keymap which will reference both
+the above keymaps.
+#+name: application-keymap
+#+caption: ~*my-applications-keymap*~
+| Keychord | Function |
+|----------+-------------------------|
+| ~b~ | ~firefox~ |
+| ~d~ | ~exec lightcord~ |
+| ~e~ | ~exec emacsclient -c~ |
+| ~g~ | ~exec gimp~ |
+| ~n~ | ~exec nemo~ |
+| ~r~ | ~'*my-rofi-keymap*~ |
+| ~s~ | ~'*my-screenshot-keymap*~ |
+
+This translates to:
+#+begin_src lisp
+ (defvar *my-applications-keymap*
+ (let ((m (make-sparse-keymap)))
+ <>
+ m))
+#+end_src
+
+The application keymap can now be bound to the top map like so:
+#+begin_src lisp
+ (define-key *top-map* (kbd "s-a") '*my-applications-keymap*)
+#+end_src
+
+I will also bind to the top map ~s-RET~ in order to open a new terminal
+window. The screenshot keymap is also bound to the ScreenPrint key.
+#+begin_src lisp
+ (define-key *top-map* (kbd "s-RET") "exec kitty")
+ (define-key *top-map* (kbd "Print") '*my-screenshot-keymap*)
+#+end_src
+
+** End of Session, Powering Off, and the Likes
+:PROPERTIES:
+:CUSTOM_ID: Keybinds-End-of-Session-Powering-Off-and-the-Likes-mgz02z40w5j0
+:END:
+The module ~end-session~ provides functions for gracefully ending the
+user session, powering off, restarting, and suspending the computer.
+It also provides a function that interactively asks what the user
+whishes to do.
+#+name: end-session-keymap
+| Keychord | Function |
+|----------+-------------------|
+| ~q~ | ~end-session~ |
+| ~l~ | ~logout~ |
+| ~s~ | ~suspend-computer~ |
+| ~S~ | ~shutdown-computer~ |
+| ~r~ | ~loadrc~ |
+| ~R~ | ~restart-hard~ |
+| ~C-r~ | ~restart-computer~ |
+
+This translates to:
+#+begin_src lisp
+ (defvar *my-end-session-keymap*
+ (let ((m (make-sparse-keymap)))
+ <>
+ m))
+#+end_src
+
+Which is bound in the root map to ~q~:
+#+begin_src lisp
+ (define-key *root-map* (kbd "q") '*my-end-session-keymap*)
+#+end_src
** Frames and Windows management
:PROPERTIES:
@@ -748,10 +910,8 @@ We can now pass onto ~*my-frames-management-keymap*~. My keybinds are organized
| ~C-t~ | ~exchange-direction down~ |
| ~C-s~ | ~exchange-direction up~ |
| ~C-r~ | ~exchange-direction right~ |
-| ~n~ | ~next~ |
-| ~p~ | ~prev~ |
-| ~/~ | ~hsplit~ |
-| ~-~ | ~vsplit~ |
+| ~/~ | ~hsplit-and-focus~ |
+| ~-~ | ~vsplit-and-focus~ |
| ~h~ | ~hsplit~ |
| ~v~ | ~vsplit~ |
| ~H~ | ~hsplit-equally~ |
@@ -765,9 +925,6 @@ We can now pass onto ~*my-frames-management-keymap*~. My keybinds are organized
| ~i~ | ~info~ |
| ~I~ | ~show-window-properties~ |
| ~m~ | ~meta~ |
-| ~o~ | ~other-window~ |
-| ~q~ | ~delete-window~ |
-| ~Q~ | ~kill-window~ |
| ~s~ | ~sibling~ |
| ~u~ | ~next-urgent~ |
| ~U~ | ~unmaximize~ |
@@ -833,119 +990,113 @@ redefine it:
((kbd "r") "resize-direction right"))
#+end_src
-** Applications
+** Windows management
:PROPERTIES:
-:CUSTOM_ID: Keybinds-Applications-2t512k00w5j0
+:CUSTOM_ID: Keybinds-Windows-management-ylf903j0x5j0
:END:
-When I speak about applications, I speak about programs and scripts in
-general. With these keymaps, I can launch programs I often have use
-for, but I can also launch some scripts as well as take screenshots.
+When it comes to windows management, I will treat them a bit like I do
+with Emacs’ buffers.
-First, let’s create my ~rofi~ scripts keymap.
-#+name: rofi-scripts
-#+caption: ~*my-rofi-keymap*~
-| Keychord | Function |
-|----------+-----------------------------------------------|
-| ~a~ | ~exec awiki~ |
-| ~r~ | ~exec rofi -combi-modi drun,window -show combi~ |
-| ~s~ | ~exec rofi -show ssh~ |
-| ~p~ | ~exec rofi-pass -t~ |
-| ~P~ | ~exec rofi-pass~ |
-| ~e~ | ~exec rofi-emoji~ |
-| ~m~ | ~exec rofi-mount~ |
-| ~u~ | ~exec rofi-umount~ |
-| ~w~ | ~exec wacom-setup~ |
-| ~y~ | ~exec ytplay~ |
-| ~Y~ | ~exec rofi-ytdl~ |
-
-Here’s the equivalent in Common Lisp.
-#+begin_src lisp
- (defvar *my-rofi-keymap*
- (let ((m (make-sparse-keymap)))
- <>
- m))
-#+end_src
-
-Let’s also create a keymap for screenshots.
-#+name: screenshot-keymap
-#+caption: ~*my-screenshot-keymap*~
-| Keychord | Function |
-|----------+------------------------------------------------------|
-| ~d~ | ~exec scrot -d 3 -e 'mv $f ~/Pictures/Screenshots'~ |
-| ~s~ | ~exec scrot -e 'mv $f ~/Pictures/Screenshots'~ |
-| ~S~ | ~exec scrot -s -e 'mv $f ~/Pictures/Screenshots'~ |
-| ~g~ | ~exec scrot -e 'gimp $f; mv $f ~/Pictures/Screenshots'~ |
-
-Here’s the equivalent in Common Lisp.
-#+begin_src lisp
- (defvar *my-screenshot-keymap*
- (let ((m (make-sparse-keymap)))
- <>
- m))
-#+end_src
-
-We can now define our applications keymap which will reference both
-the above keymaps.
-#+name: application-keymap
-#+caption: ~*my-applications-keymap*~
+#+name: window-management
+#+caption: ~*my-buffers-management-keymap*~
| Keychord | Function |
|----------+-------------------------|
-| ~b~ | ~firefox~ |
-| ~d~ | ~exec lightcord~ |
-| ~e~ | ~emacs~ |
-| ~g~ | ~exec gimp~ |
-| ~n~ | ~exec nemo~ |
-| ~r~ | ~'*my-rofi-keymap*~ |
-| ~s~ | ~'*my-screenshot-keymap*~ |
+| ~b~ | ~windowlist~ |
+| ~d~ | ~delete-window~ |
+| ~D~ | ~window-window-and-frame~ |
+| ~k~ | ~kill-window~ |
+| ~n~ | ~next~ |
+| ~o~ | ~other-window~ |
+| ~p~ | ~prev~ |
-This translates to:
#+begin_src lisp
- (defvar *my-applications-keymap*
+ (defvar *my-buffers-management-keymap*
(let ((m (make-sparse-keymap)))
- <>
+ <>
m))
+
+ (define-key *root-map* (kbd "b") '*my-buffers-management-keymap*)
#+end_src
-The application keymap can now be bound to the top map like so:
-#+begin_src lisp
- (define-key *top-map* (kbd "s-a") '*my-applications-keymap*)
-#+end_src
-
-I will also bind to the top map ~s-RET~ in order to open a new terminal
-window. The screenshot keymap is also bound to the ScreenPrint key.
-#+begin_src lisp
- (define-key *top-map* (kbd "s-RET") "exec kitty")
- (define-key *top-map* (kbd "Print") '*my-screenshot-keymap*)
-#+end_src
-
-** End of Session, Powering Off, and the Likes
+** Media and Media Control
:PROPERTIES:
-:CUSTOM_ID: Keybinds-End-of-Session-Powering-Off-and-the-Likes-mgz02z40w5j0
+:CUSTOM_ID: Keybinds-Media-and-Media-Control-hbv5uk91z5j0
:END:
-The module ~end-session~ provides functions for gracefully ending the
-user session, powering off, restarting, and suspending the computer.
-It also provides a function that interactively asks what the user
-whishes to do.
-#+name: end-session-keymap
+My music is managed through MPD, and I often use ~mpc~ commands in order
+to interact with it without any GUI application. So, we’ll see a lot
+of its usage here.
+
+First, let’s declare an interactive keymap in order to easily change
+several times in a row either the current song playing or the volume
+of MPD.
+#+name: inter-mpc
+#+caption: Interactive keybinds for ~mpc~
+| Keychord | Function |
+|----------+--------------------|
+| ~c~ | ~exec mpc prev~ |
+| ~t~ | ~exec mpc volume -2~ |
+| ~s~ | ~exec mpc volume +2~ |
+| ~r~ | ~exec mpc next~ |
+
+Cela donne le code suivant:
+#+begin_src lisp
+ <>
+#+end_src
+
+Another one will be defined for the general audio of my computer. And
+I know it isn’t technically media keybinds, but I’ll add in keybinds
+for my screen’s backlight.
+#+name: inter-media
+#+caption: Interactive keybinds for general media interaction
+| Keys | Function |
+|------+--------------------------------------|
+| ~c~ | ~exec xbacklight -dec 2~ |
+| ~t~ | ~exec amixer -q set Master 2%- unmute~ |
+| ~s~ | ~exec amixer -q set Master 2%+ unmute~ |
+| ~r~ | ~exec xbacklight -inc 2~ |
+| ~m~ | ~exec amixer -q set Master 1+ toggle~ |
+
+#+begin_src lisp
+ <>
+#+end_src
+
+Then, let’s declare a keymap for our media controls.
+#+name: media-management
+#+caption: ~*my-media-keymap*~
| Keychord | Function |
|----------+-------------------|
-| ~q~ | ~end-session~ |
-| ~l~ | ~logout~ |
-| ~s~ | ~suspend-computer~ |
-| ~S~ | ~shutdown-computer~ |
-| ~r~ | ~restart-computer~ |
+| ~.~ | ~media-interactive~ |
+| ~m~ | ~mpc-interactive~ |
+| ~p~ | ~exec mpc prev~ |
+| ~n~ | ~exec mpc next~ |
+| ~t~ | ~exec mpc toggle~ |
+| ~s~ | ~exec mpc stop~ |
-This translates to:
+Let’s translate this table in CommonLisp:
#+begin_src lisp
- (defvar *my-end-session-keymap*
+ (defvar *my-buffers-management-keymap*
(let ((m (make-sparse-keymap)))
- <>
+ <>
m))
+
+ (define-key *root-map* (kbd "m") '*my-media-keymap*)
#+end_src
-Which is bound in the root map to ~q~:
+I will also define on ~*top-map*~ some basic volume management keybinds
+so that they are immediately accessible. Again, this isn’t technically
+media-related, but I’ll add keybinds for my screen’s backlight.
+#+name: media-top-level
+#+caption: Top-level media keys
+| Keychord | Function |
+|-----------------------+--------------------------------------|
+| ~XF86AudioRaiseVolume~ | ~exec amixer -q set Master 2%+ unmute~ |
+| ~XF86AudioLowerVolume~ | ~exec amixer -q set Master 2%- unmute~ |
+| ~XF86AudioMute~ | ~exec amixer -q set Master 1+ toggle~ |
+| ~XF86MonBrightnessDown~ | ~exec xbacklight -dec 2~ |
+| ~XF86MonBrightnessUp~ | ~exec xbacklight -inc 2~ |
+
#+begin_src lisp
- (define-key *root-map* (kbd "q") '*my-end-session-keymap*)
+ <>
#+end_src
** Misc
@@ -964,3 +1115,57 @@ anywhere else:
#+begin_src lisp
<>
#+end_src
+
+* org functions :noexport:
+:PROPERTIES:
+:CUSTOM_ID: org-functions-syqgzgg0m6j0
+:END:
+
+#+name: keybinds-gen
+#+headers: :tangle no :exports none :cache yes :noweb yes
+#+begin_src emacs-lisp :var map="m" keybinds=frames-float
+ (mapconcat (lambda (keybind)
+ (format "%s" (let ((key (let ((s (car keybind)))
+ (substring-no-properties s 1 (1- (length s)))))
+ (function (let ((s (cadr keybind)))
+ (substring-no-properties s 1 (1- (length s))))))
+ `(define-key ,map
+ (kbd ,(format "\"%s\"" key))
+ ,(if (string-prefix-p "'" function t)
+ function
+ (format "\"%s\"" function))))))
+ keybinds
+ "\n")
+#+end_src
+
+#+name: interactive-gen
+#+headers: :tangle no :exports none :noweb yes
+#+begin_src emacs-lisp :var name="inter" keys=inter-mpc
+ (format "%s"
+ `(define-interactive-keymap ,name ()
+ "\n "
+ ,(mapconcat (lambda (keybind)
+ (format "%s"
+ (let ((key (let ((s (car keybind)))
+ (substring-no-properties s
+ 1
+ (1- (length s)))))
+ (command (let ((s (cadr keybind)))
+ (substring-no-properties s
+ 1
+ (1- (length s))))))
+ `((kbd ,(format "\"%s\"" key)) ,(format "\"%s\"" command)))))
+ keys
+ "\n ")))
+#+end_src
+
+#+name: num-to-char
+#+headers: :tangle no :exports none :noweb yes
+#+begin_src emacs-lisp :var table=number-to-char-table num=0
+ (replace-regexp-in-string (regexp-quote "~")
+ ""
+ (cadr (assoc num table)))
+#+end_src
+
+#+RESULTS: num-to-char
+: *