@david@daiwei.me You mean, you mean⦠like mowing down a whole rain forest in a thunderstormās brutal heat? :-?
Show us todayās rain. :-)
Now, thatās cool shit, I have to say! Discovering so many hidden sounds⦠With Fotric Acoustic Imager: https://youtu.be/CKJT_ECOsK4
@david@daiwei.me Hahaahaaahaaaaa, that was funny as heck, mate! I had to laugh really hard! :ā-D
@david@daiwei.me Hahaha, for sure. (But my observation wasnāt meant as a complaint.)
@david@daiwei.me :-D
Wow, 79 new messages over night, similar numbers in the past days. Looks like weāre surfing a high-traffic wave again. :-)
gg instead of g to go to the top in tt. Much better! :-) Other multi-key combinations are also easily possible now.
@prologic@twtxt.net @david@daiwei.me Thanks! Hahaha, rest assured, it was not right from the beginning at all. I had to fix it over and over again.
Uuhh, nice, @eldersnake@we.loveprivacy.club is back!
@prologic@twtxt.net Perhaps somebody tried to register āyarn_secret_serviceā. 8-)
@prologic@twtxt.net Whereās the before picture!? :-D
@movq@www.uninformativ.de Yes, this is absolutely a no-go!
A long time ago when the first telemetry shitstorm happened, I added export GOTELEMETRY=off in my ~/.zshrc. But it doesnāt seem to be picked up at all (I actually call this sabotage!):
$ go env GOTELEMETRY
local
$ go env -w GOTELEMETRY=off
go: GOTELEMETRY cannot be modified
$ go telemetry off
$ go env GOTELEMETRY
off
@prologic@twtxt.net @david@daiwei.me I just want to bring up the following: From a data protection point of view, edits and deletions are important. But thatās about it, I will not join discussions on that topic. :-)
@prologic@twtxt.net You also have to tell us the username!
Hell yeah, @kat@yarn.girlonthemoon.xyz is back! \o/
Hurray, I can now press gg instead of g to go to the top in tt. Much better! :-) Other multi-key combinations are also easily possible now.
I should probably write a real article about this at some point, but here we go. The only downside with my new key binding system is that it breaks tviewās established pattern. Youāve got an InputHandler(), that is implemented using WrapInputHandler(ā¦). It typically then directly implements the switching logic depending on the key press. Something like this:
func (w *Widget) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
// WrapInputHandler allows for intercepting key events with SetInputCapture(ā¦)
// from the outside for customization. This handles the default key bindings.
return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
switch event.Key() {
case tcell.KeyRune:
if event.Modifiers() == tcell.ModNone {
switch event.Rune() {
case 'k':
w.scrollUp()
return // we already handled the event, stop processing
case 'j':
w.scrollDown()
return
}
}
}
// We didn't handle the key event. Maybe the parent
// widget knows what to do with it.
if handler := w.parent.InputHandler(); handler != nil {
handler(event, setFocus)
}
})
}
From the outside, you can intercept and either stop or continue the widgetās original key handling with a potentially rewritten key event using SetInputCapture(ā¦):
w := NewWidget()
// customized or additional key bindings
w.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyUp:
// Rewrite the event, so the "cursor up" key is an alias
// for the vim key binding "k", that is handled by the
// wrapped input handler above. (I know, I know, this is a
// completely unrealistic example, why would anyone use
// cursor keys when there are vim key bindings available?!)
return tcell.NewEventKey(tcell.KeyRune, 'k', tcell.ModNone)
case tcell.KeyRune:
if event.Modifiers() == tcell.ModNone {
switch event.Rune() {
case 'q':
app.Stop()
// we already handled the event, do not pass it
// to the wrapped input handler above
return nil
case 'r':
toggleMessageReadStatus()
return nil
}
}
}
// we didn't handle the event, pass it to the wrapped
// input handler above
return event
}
Since they all expect a single key, Iāve noticed that using multiple dedicated KeyBindings of mine on these different levels kinda breaks multi-key handling with common prefixes. The outer-most KeyBinding captures the prefix, but it canāt transfer it to the inner one if not handled by the outer one. At least not without some more (potentially ugly) changes. So, I now have to work with just a single KeyBindings object for the entire widget chain (if it consists of multiple other widgets or the regular input handler and input capture are in the game). The outside needs to register all its key bind customizations or extensions at the same level that the original widget handles its default ones. Doable by exposing the widgetās KeyBindings instance, but not pretty. You always have to keep this in mind.
With the KeyBindings, it will look like that:
type Widget struct {
parent tview.Primitive
// make it available to children or the outside either by
// direct field access or by providing a getter method
KeyBindings *bind.KeyBindings
}
func NewWidget() *Widget {
w := &Widget{KeyBindings: &bind.KeyBindings{}}
w.KeyBindings. // default key bindings
Bind0(bind.KeySequence('k', w.scrollUp).
Bind0(bind.KeySequence('j', w.scrollDown)
return w
}
func (w *Widget) InputHandler() InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
// also note the missing support for focus transfer at the moment
event = w.KeyBindings.Capture(event)
if event == nil {
return
}
if handler := w.parent.InputHandler(); handler != nil {
handler(event, setFocus)
}
}
}
And then from the outside, or in a child widget:
w := NewWidget()
w.KeyBindings. // additional or customized key bindings
Bind1(bind.KeySequence(tcell.KeyUp), func(*tcell.EventKey) *tcell.EventKey {
return tcell.NewEventKey(tcell.KeyRune, 'k', tcell.ModNone)
}).
Bind0(bind.KeySequence('q'), app.Stop).
Bind0(bind.KeySequence('r'), toggleMessageReadStatus)
When directly working with tview primitives that are not part of custom widget implementations, the following works well so far:
textView := tview.NewTextView().
SetWordWrap(true).
SetText("ā¦")
SetScrollable(true)
textView.SetInputCapture((&bind.KeyBindings{}).
Bind0(bind.KeySequence('q'), app.Stop).
Bind1(bind.KeySequence('g', 'g'), func(*tcell.EventKey) *tcell.EventKey {
return tcell.NewEventKey(tcell.KeyHome, 0, tcell.ModNone)
}).
Capture)
I need to sleep on this some more.
Also, writing very long messages like this one is really not all that fun in ttās editor. I should absolutely provide a way to shell out to vim.
(Took me about one and a half hours to compose, holy crap. But not only because of not using vim. Although, that might have saved me a quarter hour or so for sure. Proof-reading this message also uncovered quite a few bugs in my real documentation. So, thatās a big win!) Good night!
@david@daiwei.me Not so keen on the mowing part. :-)
@prologic@twtxt.net Thatās a good way to keep spammers out:
Your browser did not pass the anti-spam check! Please make sure JavaScript is enabled and try again.
It was turned on.
@david@daiwei.me Haha, great response!
@movq@www.uninformativ.de Hottest room is still at 24°C. But that will change in this week, no doubt. :-(
@david@daiwei.me I donāt want to start the discussion again, but edits wouldnāt be an issue if we had agreed on a better addressing scheme. Maybe edit more as a quiet riot. :-P
@david@daiwei.me Oh boy, that looks super yummy! :-) I want to have rain here, too!
@david@daiwei.me Exactly. Spaces are fixed, tabs always break the layout when the tab sizes are different.
@david@daiwei.me Hahaahaaahaaaahaaaaa, so good! :ā-D
Nice product, I should probably buy it: 
+00:00 vs Z should be treated as equivalent UTC š¤¦āāļø I'll take a look at the timestamp parsing in Yarnd š§
@prologic@twtxt.net For what itās worth, the twt hash extension is specifically modeled after yarndās implementation with all the quirks coming from Goās stdlib: https://twtxt.dev/exts/twt-hash.html#timestamp-format
āAll timezones representing UTC must be formatted using the designated Zulu indicator Z rather than the numeric offsets +00:00 or -00:00. If the timestamp does not explicitly include any timezone information, it must be assumed to be in UTC.ā
<tab> (white space) between the timestamps and posts look a bit shorter than the ones from jenny? just noticed that and thought maybe it's someting you'd want to know.
@aelaraji@aelaraji.com @david@daiwei.me @prologic@twtxt.net It depends on the tab size, but often, a tab aligns the following character to next column that is a multiple of eight.
1 8 |16 |24 |32
2026-07-12T08:11:34+02:00 Here goes the text
2026-07-12T06:11:34Z Here goes the text
@david@daiwei.me Oh no, what a giant waste of time. :-(
@arne@uplegger.eu Diese Karten sind ja echt winzig. :-)
Aber da fällt mir ein, ich sollte mir auch mal wieder ein Taschenmesser zulegen. Hab ich es doch über all die Jahre geschafft, alle schlussendlich zu verlieren.
@david@daiwei.me Ta, I continued my fun with studying the tcell and cbind code bases for key bindings. My plan is to eventually not only support custom key bindings in the tt configuration file, but also to enable multi-key sequences, such as gg to jump to the top of a list/tree. Or use other vim-like navigation movements like 7j or 25gg etc.
And it turns out there are only a hand full oft tcell/cbind version combinations that work together. Only if all stars align, thereās chance of success. I will probably end up pulling cbind in to simplify my life. There are situations where tcell.EventKeyās triple of key, modifiers and rune are not all that intuitive to me. Letās see.
@prologic@twtxt.net Well, 15 shows the site. On the left, I had a roll mat on a tarp. I borrowed some āNVA tarpsā from the scouts for this trip. The scouts got them from the National Peopleās Army, the German Democratic Republicās armed forces after Germany was reunited. Theyāre 1.75m x 1.75m in size and weigh 1.3kg, quite heavy, but super awesome. One tarp on the bottom, another one to cover up the clothes, shoes and sleeping bag in order to protect against the thaw. Finally, a mosquito net over all that, hung from a rope between two trees.
My mate just used a hammock with a mozzie net on the right hand side. The third tarp served as the luxurious bedside carpet. :-)
We sat on my second tarp to chill and enjoy the sunset and surroundings. It was nice to notice birds etc. die down. It took a really long time for the last light to fade away. Since we have a very high risk of forest fires, we of course couldnāt have a camp fire. But after all the exhaustion, I didnāt even miss it for one second.
Since we had dinner at home before leaving, all we brought were two lye rolls, two grain rolls, two brezels, some sausage and chocolate biscuits for breakfast. From the 2.5l of water, I ended up using 2l. Itās always good to have a little extra, despite the unnecessary weight. We had brekkie a few kilometers further on a bench in the shade. The first bench was already in direct sun.
Our camp site was maybe 30m to the side and a few meters down of a summit path hidden behind some trees and bushes. We were quite lucky, the other side of the hill got quite a bit of a breeze at night. We could hear the leaved treetops making much more noise behind us.
@movq@www.uninformativ.de Yes, these kind of dogs should really be strictly forbidden!
Itās not illegal if you own the forest or ask the owner. :-)
@david@daiwei.me Yeah, no clue. But my mate said the dog is disqualified from such adventures in the future. :-)
The temps were supposed to hit 14°C just before sunrise. Since we didnāt bring a thermometer, I canāt tell for sure. I was rather hot in my sleeping bag, so I had to pull out my arms every now and then. My mateās sleeping bag was a little lighter and, unfortunately, the zipper jammed up. Since it didnāt close all the way, it felt quite a bit cold I was told in the morning. When we got up at 6ish (we said, we donāt care about time at all), it was probably already 16°C if not more. I brought a jumper, but a t-shirt was already nice enough to wear. The jumper just served as my pillow. The mercury raised by the minute then.
Yeah, I circled the spot with a biro to keep an eye on it. Until now, thereās absolutely nothing to see. Looks like I got lucky.
We slept in the forest. It was really great except of my mateās fucking terror dog who was barking and snarling the entire night to each and every sound. I had maybe half an hour of sleep in total. Despite that, it was pleasantly warm. Well, the night, that is. The heat was brutal during the days. Literally streams of sweat were running down on us on the way there in the evening and back in the morning.
Surprisingly, there werenāt any mozzies around at night, I would have lost all safe bets. On the way there, my mate convinced me to take a shortcut through the taller and taller growing grass. Itās been some time that somebody traveled on this track, so we had to search around a bit for the overgrown path where we could cross the mostly dried up creek. In the beginning I said that this will be a bad idea. Lo and behold, I discovered a tick on my inner upper leg the next morning. Luckily, I got it out with my tick hook on the first attempt.
@bender@twtxt.net Immediately reminded me of the German childrenās song āLaurentia, liebe Laurentia meinā: https://www.youtube.com/watch?v=3Q0aky9FvLc
Have a nice weekend!
@prologic@twtxt.net Iām glad you like it. :-)
@bender@twtxt.net I bet thatās true!
@bender@twtxt.net Nice job! Without the comparison of the after photo, the grass doesnāt look all that tall before. :-D But there sure was one or the other centimeter chopped off.
@movq@www.uninformativ.de What a desaster.
@bender@twtxt.net Thanks! I wanted that to never end as well. :-)
@movq@www.uninformativ.de Even way lower than that.
@prologic@twtxt.net @bender@twtxt.net @movq@www.uninformativ.de @aelaraji@aelaraji.com Success!
@david@daiwei.me Some entries can be probably simplified with just *bot*. :-) (But I donāt use Caddy, so no idea about case (in)sensitivity.
That reminds me, I should do something similar with my Nginx.
@aelaraji@aelaraji.com I do use XMPP. But only the text chat part. ;-)
@movq@www.uninformativ.de Hier hab ich zum Glück überhaupt gar nichts davon mitbekommen.
Very hot above 30°C, but luckily also incredibly cloudy and a lot of wind. Thatās what we got today. My mate and I went on a quick stroll this evening and got a surprise killer sunset: https://lyse.isobeef.org/abendhimmel-2026-07-07/
@bender@twtxt.net Iām glad to announce that Lyseās Free Nose Cleaning Service is now internationally available.
@movq@www.uninformativ.de Congrats! :-)
@movq@www.uninformativ.de There is nothing like that on Linux, because you donāt need it. Everything just works!
@prologic@twtxt.net Very nice! Which boat is yours? :-)
@arne@uplegger.eu Whoah! āSchaffung eines Aufenthaltsraumes für Nichtraucher!ā Irre, dass es einen solchen vor dem 1. Mai 1975 nicht gab. Kann man sich heute überhaupt nicht vorstellen.
Cool, schƶnes Heftchen hast Du da gesetzt. :-) Die Lochkartenanzahlen sind auch der absolute Wahnsinn.
@itsericwoodward@itsericwoodward.com @bender@twtxt.net Oh, I missed that. Whoopsy daisy!