diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-07-11 11:55:36 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-07-11 11:55:36 +0200 |
| commit | 6c8d5dbed46e66b3a1e1adc261cbf94b7da78022 (patch) | |
| tree | e8a36e7692c7450b2f362422ba5d940c90c0b045 | |
| parent | 227efac0e9d896663540c29a114dc66183d2ea1c (diff) | |
| download | sebastiano.tronto.net-6c8d5dbed46e66b3a1e1adc261cbf94b7da78022.tar.gz sebastiano.tronto.net-6c8d5dbed46e66b3a1e1adc261cbf94b7da78022.zip | |
new blog post
| -rw-r--r-- | src/blog/2024-07-11-tmux-battery/tmux-battery.md | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/blog/2024-07-11-tmux-battery/tmux-battery.md b/src/blog/2024-07-11-tmux-battery/tmux-battery.md new file mode 100644 index 0000000..1ea5b99 --- /dev/null +++ b/src/blog/2024-07-11-tmux-battery/tmux-battery.md | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | # tmux tricks #1: battery status indicator | ||
| 2 | |||
| 3 | [tmux](https://github.com/tmux/tmux/wiki) is a program that allows | ||
| 4 | you to create multiple virtual terminals in the same shell and keep | ||
| 5 | your terminal sessions open even after the shell exits. A common | ||
| 6 | use case for both of these features is connecting to a remote server: | ||
| 7 | with *multiplexing* you can use multiple terminals with a single | ||
| 8 | SSH connection, and the session persistence feature leaves the | ||
| 9 | remote programs running even when you disconnect from the server. | ||
| 10 | Having multiple virtual terminals open on the same screen and easily | ||
| 11 | switching between windows is also useful when working locally. In | ||
| 12 | fact, tmux is the first command I use pretty much every time I use | ||
| 13 | my [netbook](../2022-09-10-netbooks) - even though | ||
| 14 | [one shell is all I need](../2023-02-25-job-control). | ||
| 15 | |||
| 16 | Since tmux is quite a complex program, I never learned the details | ||
| 17 | of how it works. I learned how to do the couple of things I need, | ||
| 18 | and use the default settings for everything. But sometimes I do | ||
| 19 | feel the need to improve my workfow a bit, and what better excuse | ||
| 20 | for tinkering with a software tool than writing about it? | ||
| 21 | |||
| 22 | In this post I have one simple goal: display the battery level in | ||
| 23 | tmux's status bar. I am going to focus on OpenBSD, because this is | ||
| 24 | the system where I need this: on my Linux laptop I use my window | ||
| 25 | manager status bar to display this information, but on my underpowered | ||
| 26 | OpenBSD laptop I rarely use a graphical environment, and I rely on | ||
| 27 | tmux as a desktop environment. | ||
| 28 | |||
| 29 | ## tmux commands | ||
| 30 | |||
| 31 | tmux can be controlled using a variety of key bindings, all prefixed by | ||
| 32 | a "prefix" key combination, which by default is `Ctrl+B`. For example, | ||
| 33 | `Ctrl+B C` creates a new window and `Ctrl+B %` splits the screen | ||
| 34 | vertically. | ||
| 35 | |||
| 36 | Each key binding calls a *tmux command*. Not all commands are bound to | ||
| 37 | a key combination, and there are other ways to call them, including: | ||
| 38 | |||
| 39 | * Typing them in the tmux command line, invoked by pressing `Ctrl+B :`. | ||
| 40 | * Calling them from any shell as `tmux command ...`. | ||
| 41 | * Adding them to the tmux configuration file (by default `~/.tmux.conf`) | ||
| 42 | to be called on startup. | ||
| 43 | |||
| 44 | ## The tmux status bar | ||
| 45 | |||
| 46 | tmux has a status bar, which can be any size between 0 (disabled) | ||
| 47 | and 5 lines long. The default is 1 line with date, time and hostname | ||
| 48 | displayed on the right, and some information on the current session | ||
| 49 | on the left. | ||
| 50 | |||
| 51 | My goal is to customize the status indicators on the right. After | ||
| 52 | consulting the [man page](https://man.openbsd.org/tmux) for a while, | ||
| 53 | I figured out that the command I need is: | ||
| 54 | |||
| 55 | ``` | ||
| 56 | set status-right "Hello, World!" | ||
| 57 | ``` | ||
| 58 | |||
| 59 | To show the output of a command one can use the `#()` notation: | ||
| 60 | |||
| 61 | ``` | ||
| 62 | set status-right "#(date +'%H:%M')" | ||
| 63 | ``` | ||
| 64 | |||
| 65 | This example is actually a bit redundant, because the string is | ||
| 66 | passed through [strftime](https://man.openbsd.org/strftime) before | ||
| 67 | displaying. So one could simply use `set status-right "%H:%M"` to | ||
| 68 | specify a date in the HH:MM format. | ||
| 69 | |||
| 70 | The status bar by default refreshes (and so re-runs the commands | ||
| 71 | in `#()`) every 15 seconds, but this can be changed with the | ||
| 72 | `status-interval` command. | ||
| 73 | |||
| 74 | ## Battery information | ||
| 75 | |||
| 76 | The next step is getting the battery status from a command. On Linux | ||
| 77 | I wrote a little [script](https://git.tronto.net/scripts) to automate | ||
| 78 | this, but I don't have one (yet!) for OpenBSD. On this OS, this | ||
| 79 | information can be retrieved with `apm`: | ||
| 80 | |||
| 81 | ``` | ||
| 82 | $ apm | ||
| 83 | Battery state: high, 91% remaining, 367 minutes life estimate | ||
| 84 | AC adapter state: not connected | ||
| 85 | Performance adjustment mode: manual (1000 MHz) | ||
| 86 | ``` | ||
| 87 | |||
| 88 | I am only interested in the `91%` part, so I should pass this through `grep` | ||
| 89 | |||
| 90 | ``` | ||
| 91 | $ apm | grep -o '[^ ]*%' | ||
| 92 | 91% | ||
| 93 | ``` | ||
| 94 | |||
| 95 | This command means "print the strings that consist of a % symbol | ||
| 96 | preceded by any number of non-space characters". To learn more about | ||
| 97 | `grep`, check out [my blog post](../2023-08-20-grep). | ||
| 98 | |||
| 99 | ## Putting it all together | ||
| 100 | |||
| 101 | We can get our status line to show the battery status with this | ||
| 102 | tmux command: | ||
| 103 | |||
| 104 | ``` | ||
| 105 | set status-right "#(apm | grep -o '[^ ]*%%')" | ||
| 106 | ``` | ||
| 107 | |||
| 108 | Cool! But did you notice the double `%%`? That's because the string | ||
| 109 | is formatted with `strftime`, as I mentioned before, so we must | ||
| 110 | escape the `%`. Tricky! | ||
| 111 | |||
| 112 | ## More status info | ||
| 113 | |||
| 114 | We reached our goal, but in doing so we also got rid of all the information | ||
| 115 | that was already part of the status. I would like to have at least some of | ||
| 116 | it back. | ||
| 117 | |||
| 118 | One way to solve this is to use the `-a` flags for the `set` command, | ||
| 119 | like this: | ||
| 120 | |||
| 121 | ``` | ||
| 122 | set -a status-right " #(apm | grep -o '[^ ]*%%')" | ||
| 123 | ``` | ||
| 124 | |||
| 125 | This will append the new string to the current status, instead of | ||
| 126 | replacing it. Alternatively, we could declare exactly all the stuff | ||
| 127 | that we want there: | ||
| 128 | |||
| 129 | ``` | ||
| 130 | set status-right "#(apm | grep -o '[^ ]*%%') | %Y-%m-%d | %H:%M" | ||
| 131 | ``` | ||
| 132 | |||
| 133 | But what if one wants even more information there? I don't want to have | ||
| 134 | a cluttered status line, but for example being able to see at a glance if | ||
| 135 | I am connected to wifi or not would be convenient. | ||
| 136 | |||
| 137 | A simple solution is writing a shell script that prints out all this | ||
| 138 | information, save it somewhere in the `$PATH`, and then use | ||
| 139 | `set status-right "#(status_script)"`. I already have such a script | ||
| 140 | for Linux, and now I added one for OpenBSD in my | ||
| 141 | [scripts repository](https://git.tronto.net/scripts). | ||
| 142 | |||
| 143 | ## Configuration file | ||
| 144 | |||
| 145 | Finally, we can have our status bar set on startup by adding the | ||
| 146 | following line to our configuration file: | ||
| 147 | |||
| 148 | ``` | ||
| 149 | set -g status-right "#(status_script)" | ||
| 150 | ``` | ||
| 151 | |||
| 152 | ...wait a minute, that is the `-g` flag about? Witout it, I get the | ||
| 153 | following error on startup: | ||
| 154 | |||
| 155 | ``` | ||
| 156 | /home/sebastiano/.tmux.conf:1 no current session | ||
| 157 | ``` | ||
| 158 | |||
| 159 | Apparently, commands run *without* `-g` only apply to the current | ||
| 160 | "session", but the configuration file is sourced *before* a session | ||
| 161 | is created. The `-g` is used to apply this command globally. My | ||
| 162 | understanding of this is still superficial, but for now I am happy | ||
| 163 | that the battery status is there. Maybe I'll learn about sessions | ||
| 164 | at some point, and I'll write a new blog post about them :) | ||
