Searching yarn

Twts matching #US
Sort by: Newest, Oldest, Most Relevant
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@david@daiwei.me Ha, I just noticed that I changed Newsboat’s defaults. Right from the factory, new items are just bold, while read ones aren’t. No different colors, white on black. Focused items are bold yellow on blue. No matter the read status. I think that’s why I started to play with the config to differentiate them. It’s been so long ago that I didn’t know anymore I even messed with that.

And yes, you’re right, the red on black is borderline readable. Also, my white on green focus is rather silly. But I’m sooo used to it, I don’t realize how bad the contrast is. To be fair, I don’t spend a lot of time in the lists. Aha, there are new articles, Enter to hit the artice view, read it, press n to immediately jump to the next unread article, rince and repeat, finally I’m back in the article list view.

Default theme, read focused:

Default theme, unread focused:

Lyse’s schlimmbesserung, read focused:

Lyse’s schlimmbesserung, unread focused:

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@david@daiwei.me I had to look these up, horror isn’t my genre at all. :-D No idea what the cool kids use today, but I still have zsh as my interactive shell. For shell scripts, though, I try to stick to POSIX and only resort to bash if really needed or it would be too cumbersome.

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@david@daiwei.me Not sure if you only mean the code segments or in general. In theory, a general darker text color for read messages would probably work. The thing is that regular white on black is quite standard. In Newsboat, new articles are red (I opted for yellow here) and read ones white. I found that useful and kinda copied it for tt.

⤋ Read More
In-reply-to » @dce So let me get this straight... You want to store your feed on a Codeberg repo right? But you want to clone that repo down somewhere else to serve it on a different location. Right? And you'd like to use the Twtxt App (https://twtxt.app) to front all of this? Right?

@prologic@twtxt.net That’s more-or-less it. If I could do it without Codeberg (just using SCP, SSHFS, or something similar), that would be even better, but probably out-of-scope for the project.
My thinking behind how twtxt.app worked was that I could give it access to a repo, in order to add to my twtxt.txt, but that the alternative feed URL would then be presented to other users instead of the Codeberg URL; unless, of course, this is already part of the twtxt metadata.
In short, the feed URL would just be a dummy.

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@dce@hashnix.club So let me get this straight… You want to store your feed on a Codeberg repo right? But you want to clone that repo down somewhere else to serve it on a different location. Right? And you’d like to use the Twtxt App (https://twtxt.app) to front all of this? Right?

⤋ Read More
In-reply-to » @dce You may also be interested in the Twtxt App and the little tiny twtd publishing backend? šŸ¤”

@prologic@twtxt.net I was actually trying to use twtxt.app, with Codeberg as a backend, but I kept getting a 403 error. As for twtd, well, my twtxt is hosted on a pubnix. The people behind Hashnix are really nice, but I’d rather not bother them with software requests if there’s a simpler solution, and I imagine it would be rude of me to run a deamon from my homedir without permission. Could be worth asking, though, unless I decide to write a client myself.

⤋ Read More
In-reply-to » I trip over this in our code at work all the time.

@movq@www.uninformativ.de The nice thing about properties is that you can compute and cache things on the fly at first attempt and also ensure validation for writing. But like you said, since it’s not obvious that reading or writing might do some more things, it’s strongly advised to avoid doing expensive stuff disguised as properties.

I reckon the vast majority of property use cases is to provide read-only access. At least that was my impression when I was doing a lot more in Python.

Personally, I think that this just reads a lot nicer:

oink.my_property
oink.my_property = 42

Than:

oink.get_my_property()
oink.set_my_property(42)

Btw, any field access is implemented using method calls. I might be wrong, but I believe there’s always __getattr__ and __setattr__ involved. 8-)

⤋ Read More

I trip over this in our code at work all the time.

Python has this concept of ā€œpropertiesā€:

class Oink:
    def __init__(self):
        self._foo = 3

    @property
    def my_property(self):
        return self._foo


a = Oink()
print(a.my_property)

my_property() is a method but it can be used as if it were a field.

This can also be used to define a setter:

class Oink:
    def __init__(self):
        self._foo = 3

    @property
    def my_property(self):
        return self._foo

    @my_property.setter
    def my_property(self, value):
        self._foo = 123 * value

Because, for some reason, Python people don’t like getters and setters. Instead, they hide it behind a property.

The result is, when you read this:

a.my_property = 5
print(a.my_property)

You have no idea that this actually calls a method.

⤋ Read More
In-reply-to » (Just a brain dump, nobody needs to read this.)

@movq@www.uninformativ.de My grief with Java is that it’s sooo verbose. Sure, all the enterprise garbage makes it a hell lot more terrible, but even regular Java feels always so lengthy. And back in the days when I was using it daily, I missed so many convenient things in the stdlib after having experienced Python’s ā€œbatteries includedā€. Not sure if or how recent Java versions caught up.

⤋ Read More
In-reply-to » @lyse Ahh yes, but tt has a "draft" mode right? You didn't publish, then edit over and over did you? šŸ˜…

@prologic@twtxt.net Not sure if this really counts as a draft mode or this is what you had in mind. I just was in the editor for ages and didn’t close it. tt provides an integrated preview for the rendered message in there. It automatically updates every second.

Here’s a screenshot of the compose view with the conversation context on the top to which to reply to, the editor in the middle and the almost-live preview at the bottom, I hope it’s big enough:

But it’s not like I hit the ā€œAdd messageā€ button in the compose view (the one currently selected on the screenshot), see the message in the conversation tree and then come back into the compose view to continue editing. There’s no edit functionality in tt. Once the message is appended to my twtxt.txt file on disk, all I can do is edit it with vim. The U+2028 line breaks are really annoying to deal with (I’m sure I could do something about that if I spent the time), so I try to avoid that at all costs.

Once new messages have been added to my local file, I then manually upload the file to my server in a separate terminal. There’s no upload command integrated into tt. Right from my very first message in the beginning, I’ve always done it exactly like that. I’m used to this and it really doesn’t bother me. But I can see that others might not be fans of that at all. I might add an upload mechanism to tt at some point in the future.

⤋ Read More

I really think I should go back to Java.

Writing programs in Python is so exhausting. I want a compiler and I want static typing. No, linters and type checkers and IDEs are not good enough. Compilers catch way more errors in advance.

Rust is also exhausting. They’re constantly adding language features and, at the same time, the runtime library remains tiny and you need 3rd party libraries for everything. Many of those are still at version 0.x (SemVer!) and you can’t rely on anything. Often times, you need the latest Rust nightly compiler.

Go is … I don’t like it. And huge binaries.

I like C as a language, but it’s too fragile. I want to have a proper HashMap every now and then.

None of the above have good GUI libraries, at least not on Linux.

And then there’s Java. This is my fractal renderer that I wrote over 17 years ago:

https://movq.de/v/fcd3c4e557/vid-1784121825.mp4

It’s fast. It has a GUI with custom widgets and those weren’t even hard to make. It still works without changing a single line of code. The source code files have timestamps from 2009 and I just noticed that the JAR file I’m using in the video was compiled in 2010.

Java as a language is relatively easy to learn and to master. There are few surprises. The source code organization with packages is good. Java API docs are clear and well written.

The JVM ramp-up times have improved considerably:

https://movq.de/v/e7314e521e/vid-1784121998.mp4

This isn’t like the Dark Ages anymore. Might even be usable for some CLI tools.

The only thing where Java really sucks is anything close-ish to the kernel. Try issuing an ioctl() … I couldn’t have made my TUI framework in Java, but then again, I wouldn’t have needed to because Swing already exists and it just works.

⤋ Read More
In-reply-to » Easy way to do digital detox: Use a Mastodon instance that someone else maintains. And when it’s down, there’s nothing you can do but wait. šŸ˜…

@david@daiwei.me That’s a good thing. I still use it heavily, but I also realize that it is addictive. This whole idea of getting likes and boosts is horrible. Seeing ā€œnumber goes upā€ is inherently addictive design, if you ask me. This should never have been added to a Free Platform like Mastodon, and I’m glad that twtxt doesn’t have anything like it.

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

also, just to clarify, we built the hosted Service as the last lowest rung ladder for non-technical people. I fully expect most technical people will spin up their own publishing backend or use Github or similar so that long-term the ecosystem still remains very much decentralized.

⤋ Read More
In-reply-to » New in the Twtxt App 🄳 a Hosted feed backend — claim a nick, one tap, no account, no server, nothing to run. Your feed lives at https://twtpub.com/u/yournick and you're posting from the app straight away šŸŽ‰

@david@collantes.us heads up šŸ‘‹ that verification code never reached you — outbound email was broken on my end (my mail relay was rejecting twtxt.net senders šŸ¤¦ā€ā™‚ļø). Fixed + deployed now 🄳 give the hosted feed another go, it’ll land this time šŸ¤ž

⤋ Read More

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!

⤋ Read More
In-reply-to » +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.ā€

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@balloonfu-sen@yarn.girlonthemoon.xyz I could in toehry publish a specification for what twtd implements, which forms the basis of the API between twtxt.app <-> twtd, if you wanted to write your own twtd / twtxt.app compatible publishing backend (assuming you didn’t want to use Github/Gitea, etc).

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@balloonfu-sen@yarn.girlonthemoon.xyz Unfortunately I tried to support SFTP but ripped this out as Browsers (which the Swag framework uses under the hood as a framework to build PWA(s)) doesn’t support raw TCP connections. So FTP / SFTP is not possible without hacks like a proxy. Which I don’t really want to support. So only things that have some kind of HTTP API are possible viable publihsing backends right now. That is Github/Gitea, twtd, Yarn, etc.

⤋ Read More
In-reply-to » So... Quick count. Hands up those who are using the Twtxt App? šŸ¤” -- And who's also pairing this with the twtd publishing backend?

šŸ‘ definitely using the Twtxt App as my daily-driver now for Twtxt/Yarn. Not using twtd however, as I just pair the app with my already existing yarnd powered profile on twtxt.net

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

Well, after all these tests, I can’t reproduce. I have used exclusively the desktop to conduct these tests.

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@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.

⤋ Read More
In-reply-to » 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.

@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.

⤋ Read More

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.

https://lyse.isobeef.org/walduebernachtung-2026-07-09-10/

⤋ Read More

Fixed the broken hashes in the Twtxt App (https://twtxt.app) 🄳 It was hashing your twts with a client-side timestamp the server never used šŸ¤¦ā€ā™‚ļø Now it keeps the canonical created/hash the pod (or twtd) returns, and the GitHub/Gitea backends write a # url = preamble so every client hashes your feed the same way. Thanks @fastidious@tilde.town for the report šŸ™

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@marcorocco@roccodrom.de that’s interesting. Not the act itself, nor that you did it for your wife (it is the least you could do, right?). I find it interesting because in the US you can’t find bicycles with inner tubes. The tyre is it, nothing else. Yep, just the tyre.

⤋ Read More
In-reply-to » Anyone using XMPP? I've been hearing a lot about how it is the OG messaging protocol. That G00gle Talk used to use it as a back-end, that FB messanger and w_hatsapp use some modified version of it or something; And that setting up a server (or even using a public one) would be a better alternative to the aforementioned apps, so I did. Now the question is: "Where the Fu__ are my video calls at!!? 🤣" ... The protocol supports videoconferencing and I'm yet to find a decent Desktop/Mobile client that implements it. I wish I knew enough Code-Fu to contribute/help implement some, somewhere.

XMPP greatest peak was when Google Talk was around. Being able to chat with thousands, if not millions, of Google users at that time, using your own domain, and your own XMPP server was amazing. Then Google, in all its wisdom, and as it does very often, decided to kill it.

I might be on the minority, but can care less about video calls. Heck, even calls! Text is King. 🤪

⤋ Read More
In-reply-to » Anyone using XMPP? I've been hearing a lot about how it is the OG messaging protocol. That G00gle Talk used to use it as a back-end, that FB messanger and w_hatsapp use some modified version of it or something; And that setting up a server (or even using a public one) would be a better alternative to the aforementioned apps, so I did. Now the question is: "Where the Fu__ are my video calls at!!? 🤣" ... The protocol supports videoconferencing and I'm yet to find a decent Desktop/Mobile client that implements it. I wish I knew enough Code-Fu to contribute/help implement some, somewhere.

@movq@www.uninformativ.de I don’t. but i do use IRC so hmmm 🧐

⤋ Read More
In-reply-to » Anyone using XMPP? I've been hearing a lot about how it is the OG messaging protocol. That G00gle Talk used to use it as a back-end, that FB messanger and w_hatsapp use some modified version of it or something; And that setting up a server (or even using a public one) would be a better alternative to the aforementioned apps, so I did. Now the question is: "Where the Fu__ are my video calls at!!? 🤣" ... The protocol supports videoconferencing and I'm yet to find a decent Desktop/Mobile client that implements it. I wish I knew enough Code-Fu to contribute/help implement some, somewhere.

@lyse@lyse.isobeef.org How many people are still using XMPP? šŸ¤” I’d expect the number to just as low as IRC users? šŸ¤”

⤋ Read More
In-reply-to » The original twt is unavailable. It may have been edited or deleted, or is from an unknown or muted feed.

@lyse@lyse.isobeef.org simplified it a little bit. Using only *bot* will bring collateral damage I want to avoid (there are, still some ā€œgoodā€ bots):

@aibots {
      header_regexp User-Agent (?i)(GPTBot|ChatGPT|OAI-Search|anthropic|Claude|Google-Extended|FacebookBot|CCBot|Perplexity|Applebot-Extended|cohere|Omgili|Bytespider)
}
abort @aibots

⤋ Read More