tmux-battery.md (5899B)
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 :)