Tumgik
Text
Just noticed the new "Landlock" feature in Linux.
I haven't looked deeply enough to opine on design specifics, but from a birds-eye view: finally!
If you think about software security much, you know how frustrating it is that unprivileged processes have so few options for reducing their privileges even further.
And of course, only from inside the program can you get the most precise idea of how much you can limit your capabilities - just how little your logic needs.
So I really love seeing yet another step to the beautiful future where we can write programs that lock themselves down as much as possible.
8 notes · View notes
Text
Monkey-patching Emacs' built-in calendar UI to be actually nice on mobile:
Tumblr media
Just think of all the possibilities! (Like all the more valuable things I could do with my time instead.)
(The parts that I've done could be distilled down to like a 10-line upstream patch, but if you're trying to use my code, note that my monkey-patching is far from complete. For example, calendar.el's built-in navigation functions like `calendar-forward-day` are broken when they'd cause the calendar to "scroll".)
10 notes · View notes
Text
One thing I'd really like to see as standard in calendar software: let me create an event that has no specific time, just a duration and maybe also earliest/latest times.
That way the event can be automatically placed in the first available slot as you schedule other things, and only if you schedule too many things does it bother you about a conflict. And for example if coworkers can see your work calendar, it would still be clear your time is blocked off.
Then you could just dump all sorts of to-do items into your calendar as these free-floating unscheduled events, and have a unified place for seeing how you're budgeting your time and what time you have available.
This leads to a desire for putting priorities on events and other to-do software feature, but that's kinda my point: these is natural convergence of "calendar" and "to-do" tools, since both manage the same resources: your time, your energy, your availability and presence with people and at places, and so on.
22 notes · View notes
Text
Yeessss. Firefox has brought GreaseMonkey (and TamperMonkey and ViolentMonkey, for those who care about the difference) and Stylus to mobile.
At least to Android. I don't know about iOS, and last I heard Apple required every browser on iOS to use the same web engine that Safari uses, so that might get in the way.
I'm feeling optimistic about this lurch towards a decent level of extension support on mobile.
For me personally, injecting my own code into webpages is huge. I want the ability to shape things for me, instead of being locked into an interface and behavior that I have to tolerate and work around.
So now, finally, we have a semblance of civilized (personally malleable) UX coming to mobile web browsing.
70 notes · View notes
Text
Happy to discover that there's a name for one very useful alternative to mere "syntax" highlighting, which I naturally started doing for increased communication efficiency in my posts: semantic highlighting.
For example, each variable or function (within some scope) gets a distinct color.
Obviously in a limited color palette (like if I wanted to turn the results of a semantic highlighting library into Tumblr formatting which can still be manually edited without changing/losing color in the official post editors) you would perhaps have to reuse colors.
But if you have full RGB color space, a good move is to do what was described in this blog post: sort all identifiers, distribute them along a color spectrum.
For example, look at the way I use color in the code blocks of the `lambda-let` post. A syntax highlighter could never even come close to this. Automated semantic highlighting could get you most of the way there.
You do still need a mind's touch for things like choosing
yellow for both `let` and `apply-partially` (because both bind values to locally scoped variables, which is the relevant similarity in this case),
red for `lambda`,
orange for `lambda-let` (because it's the combination of those two).
Those are specific, intentionally suggestive choices that take into account semantics which you can only infer from the prose around the code.
So for blogging, I'd want the option of more manual control to put on those little finishing touches. Also, for blogging, you might even reasonably decide that in some situations syntax highlighting is better than semantic highlighting. (You might even decide that in the middle of editing/viewing code actually - I am a big believer in having a fast keybind to toggle code coloring - my ideal future setup instead cycles coloring between off, syntax, and semantic (possibly more than one for each kind).)
But for the most part, I think semantic highlighting is the superior approach, or at least is an umbrella that contains approaches which are superior for many cases. I would much rather that every IDE and code display used some basic semantic highlighting.
4 notes · View notes
Text
A few months ago I wrote this little macro for Emacs lisp called `lambda-let`, and I rather enjoy having it around.
It expands to a mere `lambda` wrapped in an `apply-partially`, but you get all the syntax niceties of a `let` form. You can get most of the idea by just comparing the "signatures":
(let VARLIST BODY...) (lambda ARGS BODY...) (lambda-let VARLIST ARGS BODY...)
(I actively oppose abbreviation in names by default, but these are the canonical names Emacs uses.)
So basically you get both a `let`-style variable list and a function argument list. For example, if you want to write a lambda that takes two parameters `foo` and `bar` but also lexically closes over `qux` in outer scope, you'd do:
(lambda-let (qux) (foo bar) ...)
which expands to
(apply-partially (lambda (qux foo bar) ...) qux)
But that's boring. Useful, ergonomic, but boring. Here's a more fun use:
(lambda-let ((qux (some-function-or-whatever)) (alp (do-stuff thing1 thing2))) (foo bar) ...)
which expands to
(apply-partially (lambda (qux alp foo bar) ...) (some-function-or-whatever) (do-stuff thing1 thing2))
Like I said:
you get all the syntax niceties of a `let`
The only difference from `let` is that `qux` and `(qux)` forms in the varlist are shorthands for `(qux qux)`, not `(qux nil)`, since the latter would be mostly useless while the former is one of the main use-cases - maybe even the most common one.
There's probably other ways to do this already in the libraries that ship with Emacs (especially in the Common Lisp stuff), but I remember taking a quick glance and for some reason not liking what I saw - not necessarily for any good reason though, I don't remember. In the meantime, I am happy with this! I find it very intuitive and pleasant to use!
This also lets us get lexical scope on a per-lambda basis, which helps if you've got code written for Emacs' default of dynamic scope and want to just have something that works without turning on lexical scope for the whole file and dealing with any breakages from that.
2 notes · View notes
Text
Titled Post!
My code now automatically takes the title out of my frontmatter YAML and sticks it in as the first H1 (`#`-prefixed) Markdown paragraph before running it through my Markdown-to-NPF stuff.
Naturally I can also do
`#` as "Biggest" text
and
`##` as "Bigger" text
more generally.
Actually the way I wrote the code it should handle any style of level one and level two headings that `mistune` supports, but I only ever use the `#`-prefixed style when I write Markdown.
1 note · View note
Text
Hey but on the other hand maybe I wouldn't be so quick to blame the Tumblr API if it gave me more precise error information, you know?
Like would it kill you to at least include "bad tags: {{unambiguous representation of the tags as the API received them}}" in the error response?
mentalisttraceur don't get mad at someone else's software before it turns out the problem is in your own software challenge (impossible difficulty)
9 notes · View notes
Text
It really is very frustrating to try to use Tumblr through the API, because:
First you have to Register An App, even though I am a user, I am trying to just automate some workflows, I am not an App Developer making a third-party integration for others.
Then you must use OAuth. Having an API where the only authentication mechanism is OAuth should be a crime. OAuth is an okay solution for letting third-party code get credentials on behalf of users with user consent. But I am not third-party code!!! I am me, the user; my code is an extension of me, it is me, alkfsdafklsdalfsalf!
Randomly things will just fail to post. You will be told the profoundly helpful status 400, code 8001, which if we go by observation alone are the only possible numbers, and mean any possible error. "Posting failed. Please try again." Incidentally, if you are ever responsible for a "Please try again" error message for something that is not a transient error but will persistently reliably fail, we need to break out the medieval corporal punishments. Flogging. Stocks. Those little cages on street posts. And responsibility goes up the chain of command - the higher the position, the longer the punishment.
This. This will be the thing that finally drives me off Tumblr. No amount of adoring Tumblr fans will keep me if I can't reliably publish posts from the comfort of my text editor.
29 notes · View notes
Text
Maybe it's just me, but I find it rather weird/strange that the convention is
have a special "title" field in the frontmatter YAML, and then inject that into the published content as a header
rather than
read the first line of the content, and (optionally: only if it is header markup), use it as a title.
Just seems backwards to me.
I do understand that from a parsing perspective, it can seem cleaner if you're imagining the kind of use-cases where you only need to parse the frontmatter. But that strikes me as missing the forest for the trees. Sure it's cleanly decoupled in isolation, but typical usage isn't going to be decoupled:
If I already run code to parse and convert article content to, say, HTML, it doesn't trouble me to extract the title from the content.
Conversely, if I'm already hand-typing, say, Markdown, I find it cleaner, easier, and more (conventionally/idiomatically) visually representative of what the final result will be (whether visually or just in intent) if the title is the first line of the content using the same representation as I would use for other headings/titles in that content format/markup/language.
It's also not strictly better in composability and decoupling:
on the one hand, your title-extraction composes with any content format without coupling to parsing that content, but
on the other hand, your content authoring is coupled to frontmatter, and content which was written to work without frontmatter (title in the content markup itself) won't compose as nicely with a system which expects a title in the frontmatter.
1 note · View note
Text
My workflow for turning a thought into a Post now looks like this:
In Emacs (in vi command state, Evil with my customizations/code).
Hit " m" (space, m) to start a new Denote note (configured to use Markdown, not f.e. Org Mode format).
Hit Enter to accept blank Denote title, or first type title, if I already know I might want to keep/find this file. I can change the title later.
Optionally specify tags now. Narrowing search over existing tags in my notes. I can change the tags later.
Type thoughts/post, quality of life is profoundly better, almost strictly better (even on Android, in Termux).
"gh" to add tags. "gr" to remove. (This is the same keybind that I use to invoke or remove commands from history in shells/REPLs. These two bindings never collide in the same buffer, and are conceptually almost the same thing in the abstract.) I have wrapped Denote so that the frontmatter tag changes are saved without redundantly confirming (if there are no other unsaved changes and if the file on the filesystem hasn't changed out from under Emacs).
" zw" (space, z, w) to publish. It prompts me for the blog since it's a new post. Narrowing search on the list of blogs I set in my Emacs config. " zw" will also update the existing post once it's published. " zd" deletes the post from Tumblr.
Glance at the post on Tumblr. As I gain evidence that my code doesn't mess things up, I will naturally do this less.
When I decide I am basically done, if it's not one of my long-term canonical posts, delete the local file.
Not to overstate things, but I feel a great deal of looming joy and optimism about how this will make things better for me. It's not as certain as many other things I've built for myself, but it seems pretty promising.
6 notes · View notes
Text
My Markdown-with-frontmatter-YAML-to-Tumblr-NPF (and then `pytumblr2` to the Tumblr API) code is now wrapped in a very minimal CLI, and I have written Emacs glue for calling that CLI.
I am using `docopt`, which I reach for first when I need a Python CLI MVP, because it reduces boilerplate almost entirely down to just writing the `--help` text string.
(Naturally this post was created and updated through it. Basically ":w" to save changes in my text editor, two keys to switch from this file in my editor to my shell, then rerun the publish command from history to push updates. For the initial posting, I just had to tab-complete the file path and type out my blog name.)
Edit: I have now also added
CLI to get/set my two Tumblr-specific frontmatter fields,
Emacs code to prompt me interactively to pick from one of my blog names (I use Vertico+Orderless for `fzf`-like narrowing/search in all such prompts).
Emacs function to get the target Tumblr blog from the frontmatter (or prompt if it's not in there) and then call the publish CLI.
Emacs function to call the post deleting CLI.
Code within the above two functions to automatically reload the file from the file system if it had no unsaved changes before the publish/delete (to pick up the frontmatter change made by my Tumblr CLI, since that bypasses Emacs and edits the file itself).
(Naturally these latest edits were made by calling that function from within Emacs.)
Final edit: and now, finally, I can publish/update/delete posts with just three key presses (from vi command mode, when on the post's local Markdown file in my Emacs). Naturally, this final triumphant edit was published that way.
4 notes · View notes
Text
So with any luck, my Markdown-to-Tumblr-NPF code can now do links (and nest formatting)!
Sometimes the API seems inconsistent though? (Sometimes it seems like just changing the text or the target sideblog makes the difference between a success and it rejecting the post with extremely opaque "Posting failed. Please try again.")
3 notes · View notes
Text
This post was created and written in Emacs as Markdown (with Frontmatter YAML), and then I used my mostly-finished Python code to post it as NPF using the Tumblr API.
The Python packages I'm using are
`pytumblr2` for interacting with the API using Tumblr's "Neue Post Format",
`python-frontmatter` for reading the frontmatter (but not writing; I hate how it disruptively rearranges and reformats existing YAML),
`mistune` for the Markdown parsing, for now with just the strikethrough extension (`marko` seems like it would be a fine alternative if you prefer strict CommonMark compatibility or have other extension wants).
The workflow I now have looks something like this:
Create a new note in Emacs. I use the Denote package, for many reasons which I'll save for another post.
Denote automatically manages some fields in the frontmatter for the information it owns/manages.
Denote has pretty good code for managing tags (Denote calls them "keywords"). The tags go both in the file name and in the frontmatter. There's some smarts to auto-suggest tags based on tags you already use, etc.
The usual composable benefits apply. Denote uses completing-read to get tags from you when used interactively, so you can get nicer narrowing search UX with Vertico, Orderless, and so on.
So when I create a new "note" (post draft in this case) I get prompted for file name, then tags.
I have my own custom code to make tag adding/removing much nicer than the stock Denote experience (saves manual steps, etc).
Edit the post as any other text file in Emacs. I get all the quality-of-life improvements to text editing particular to my tastes.
If I stop and come back later, I can use any search on the file names or contents, or even search the contents of the note folder dired buffer, to find the post draft in a few seconds.
Every time I save this file, Syncthing spreads it to all my devices. If I want, I can trivially use Emac's feature of auto-saving and keeping a configurable number of old copies for these files.
I have a proper undo tree, if basic undo/redo isn't enough, and in the undo tree UI I can even toggle displaying the diff for each change.
My tools such as viewing unsaved changes with `git diff`, or my partial write and partial revert like `git add -p`, are now options I have within easy reach (and this composes with all enhancements to my Git config, such as using Git Delta or Difftastic).
After a successful new post creation, my Python code adds a "tumblr" field with post ID and blog name to the frontmatter YAML. If I tell it to publish a post that already has that information, it edits the existing post. I can also tell it to delete the post mentioned in that field, and if that succeeds it removes the field from the file too.
The giant leap of me being able to draft/edit/manage my posts outside of Tumblr is... more than halfway complete. The last step to an MVP is exposing the Python functions in a CLI and wrapping it with some Emacs keybinds/UX. Longer-term TODOs:
Links! MVP is to just add links to my Markdown-to-NPF code. Ideal is to use Denote links and have my code translate that to Tumblr links.
Would be nice to use the local "title" of the file as the Tumblr URL slug.
Pictures/videos! I basically never make posts with media, but sometimes I want to, and it would be nice to have this available.
6 notes · View notes
Text
One small nicety of posting through the API with raw NPF block data is that `backticks` should get preserved, whereas Tumblr's own in-browser post editor keeps trying to steal them for some mysterious secret formatting that doesn't actually affect rendering.
2 notes · View notes
Text
I wrote this post as Markdown in a Python REPL string literal, ran it through a parser, and posted it as NPF using the Tumblr API through pytumblr2!
A second decently-sized step in the giant leap of me being able to draft/edit/manage my posts outside of Tumblr.
List item! (With bold and italic!)
Another!
Ordered?
Yes.
6 notes · View notes
Text
Oooooohhh myyyyy goddddd synchronized history between all my REPLs on all my devices is so life-improvingly gooooooood!
Just had to switch laptops because one was a lot lower on battery than I expected. At a cafe, don't have charger - thought I had two fully charged laptops turns out I only have one. Okay, tolerable, that's what the second laptop is for. Resuming some Python development.
Normally, that would be annoying. I'd have to go out of my way to retrieve some information. Re-think some commands.
This time? Not only are the pip install commands in my local history, okay yeah you could get that with another shell history sync like Atuin, but so are the Python REPL lines which I ran yesterday on the other laptop. No information to retrieve - it's already inline in the Python history.
Blissful. Utopic.
4 notes · View notes