Originally posted at https://beathagenlocher.com/stream#00129
Originally posted at https://beathagenlocher.com/stream#00129
Some time ago, I visited a friend who's fairly well versed in tech (e.g. NeoVim, can code) and watches him struggle with editing a file in Word fast on someone else's Laptop. I asked him whether he knew about <KB>Ctrl-arrow</KB> for wordwise movement (which he didn't), and was fairly surprised. But in hindsight, I didn't know that for the longest time either. I took this as an example to start writing on Better Computer Use (then only a collection of basically "Keyboard Shortcuts You Might Want To Know"). Today I revisited this, and something that started out as "You might want to know these shortcuts" ended in a discussion on how Software Developers and Product Designers should structure their UIs. Feel free to check it out, tell me what you think, and tell me where I'm wrong :) (Or just wait until it's more polished.) :)
Hey :) I've greatly expanded upon an older note of mine. Check it out!
#Simplicity #Writing
Read the full post at https://beathagenlocher.com/stream#00128
Today I finally tackled something that has annoyed me for a while since switching most of my editing/digital gardening/second brain-writing over to Emacs. Whenever I took 30 minutes and tried to get title fetching of links to work, I couldn't get it to work in this self-allotted time. So I asked Opus to do the dumbest thing possible: Just fetch it via curl, and then apply stuff asynchronously. (Obviously the other, non-dumb way should work too, but I've spent way to much time on this now either way.) (And apparently there's also `url-insert-file-contents`, maybe I'gonna try that some other time.) ```elisp (defun flt--url-at-point () "Get URL at point, or nil." (thing-at-point 'url)) (defun flt--url-from-kill-ring () "Get URL from kill ring if it looks like one, or nil." (let ((text (current-kill 0 t))) (when (and text (string-match-p "\\`https?://" text)) (string-trim text)))) (defun flt--get-url () "Get URL from point first, then kill ring. Nil if neither has one." (or (flt--url-at-point) (flt--url-from-kill-ring))) (defun flt--extract-title (html) "Extract <title> content from HTML string." (when (string-match "<title[^>]*>\\([^<]*\\)</title>" html) (string-trim (match-string 1 html)))) (defun flt--insert-markdown-link (url title marker) "Replace URL at MARKER with a markdown link, or insert at MARKER." (with-current-buffer (marker-buffer marker) (save-excursion (goto-char marker) ;; If there's a raw URL at point, replace it (let ((url-bounds (thing-at-point-bounds-of-url-at-point))) (if url-bounds (progn (delete-region (car url-bounds) (cdr url-bounds)) (insert (format "%s" title url))) (insert (format "%s" title url))))))) (defun flt-fetch-link-title () "Fetch the title of a URL (at point or kill ring) and insert a markdown link. If point is on a URL, replaces it. Otherwise inserts at point." (interactive) (let ((url (flt--get-url))) (if (not url) (message "No URL found at point or in kill ring.") (let ((marker (point-marker)) (buf (generate-new-buffer " *flt-curl*"))) (message "Fetching title for %s..." url) (make-process :name "flt-curl" :buffer buf :command (list "curl" "-sL" "-m" "10" "-H" "User-Agent: Emacs" "--" url) :sentinel (lambda (proc _event) (when (eq (process-status proc) 'exit) (let ((title (with-current-buffer (process-buffer proc) (flt--extract-title (buffer-string))))) (if title (progn (flt--insert-markdown-link url title marker) (message "Inserted: %s" title url)) (message "Could not extract title from %s" url))) (kill-buffer (process-buffer proc)) (set-marker marker nil)))))))) (map! :leader :desc "->title" :nv "d f" #'flt-fetch-link-title) ``` And in the meantime, I also learned that _markers_ exist! So now, I can fetch link titles again, like I'm used to :)
Async Link Fetching in Emacs
#TIL #Emacs #DoomEmacs
Originally posted at https://beathagenlocher.com/stream#00127
I've been dragging quite a few notes around with me for the last one, two weeks. Here they are! :)
Just uploaded a bunch of my already-written/accumulated notes :)
#Writing
Read the full post at https://beathagenlocher.com/stream#00126
For presentations, I'm using slidev, a pretty cool and versatile tool (Markdown slides with inline HTML/Vue, so you can do basically anything on your slides), which has lots of cool features. One minor annoyance: If you're using either of the QRCode addons and want to add more than one QR Code per slide deck, it breaks. Luckily, with the power of the web, this is pretty easy to fix: We can just define a component: ```vue <template> <QrcodeCanvas :value="value" :size="width" :foreground="foreground" :background="background" :margin="margin" level="H" /> </template> <script lang="ts" setup> import { QrcodeCanvas } from 'qrcode.vue' const props = withDefaults( defineProps<{ value: string width?: number height?: number color?: string margin?: number }>(), { width: 200, color: '#000000', margin: 2, }, ) const foreground = props.color.startsWith('#') ? props.color : `#${props.color}` const background = '#FFFFFF' </script> ``` And use it: ```vue <QRCode class="rounded" value="https://beathagenlocher.com/me" :width="140" :height="140" /> ``` Sweet!
Finally fixed a minor slide annoyance of mine: Non-working QR codes
#Slidev #QRCode #slides #Vue
Totally fair ^^
In case it helps, I've got some notes on Nix stuff: beathagenlocher.com?q=nix
(but there's plenty of good stuff online too nowadays)
And feel free to ask questions!
Then, when you're managing all of your projects written in, say, python inside nix/flakes, you can remove the global python from your homebrew state.
And concurrently: As soon as you've got a bit of a grasp on flakes, you can start a managed /home/user via home-manager, and so on.
The cool thing is though that you don't even need to switch all-in-one, you can make the transition pretty gradual.
You can start out with just one project, and manage those project's dependencies in a flakes' devShell.
[Simple](www.youtube.com/watch?v=SxdO...) yes, not easy, very much worth it.
Over here, itβs called the _evil_ side.
π
github.com/emacs-evil/e...
Yep, very much so. Thanks for writing this up!
Fish abbreviation from 'co' to 'claude --model opus' :)
Originally posted at https://beathagenlocher.com/stream#00125
Today I learned that there's magic `pre<*>` and `post<*>` hooks inside `npm` (and everything npm-compatible): -> https://docs.npmjs.com/cli/v8/using-npm/scripts I think I would've preferred less magic-side-effect-ness, but fair, I guess. So, to run something post `install` ```json { "scripts": { // ..., "postinstall": "echo 'hello postinstall'", } } ``` Caveat: For `npm`, this only works when literally running `npm install` (or `npm i`), but now when running `npm i <some-package>`. Well, that's what you get, I guess? I'm even less convinced by its usefulness now. For `bun` at least, both seem to work :)
Learned something about package.json postinstall scripts :)
#npm #JavaScript #TypeScript #bun #pnpm #TIL
Read the full post at https://beathagenlocher.com/nix-flake
An entry point for Nix stuff. # Writing your first flake Your flake is the entry point to your application built and run with nix. Your flake is a function from `inputs` (which consist of urls for getting package sets) to `outputs`, with outputs being one big _attribute set_. This `outputs` _attribute set_ looks something like this (very much like a JSON object): ```nix # outputs { apps = { ... }; checks = { ... }; devShells = { ... }; formatter = { ... }; legacyPackages = { ... }; nixosConfigurations = { ... }; nixosModules = { ... }; overlays = { ... }; packages = { ... }; } ``` Every key in here is a special, magic key that Nix interprets in a certain way. For the minimal (non-functional) flake: ```nix { inputs = {}; outputs = {...}: {}; } ``` all of them are empty. Through populating them, we give our Nix Flake additional capabilities. The first capability to give our Nix Flakes is normally a _development shell_. In Nix Language, we create this like this: ```nix title="flake.nix" { inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; }; outputs = { nixpkgs, ... }: { devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {}; }; } ``` And run it via `nix develop` (getting it? The `devShells` output gets run by `nix develop`): ```shell > nix develop (nix-shell-env)> ``` But that doesn't do anything yet. For it to do something we need to add something into the devshell: ```nix title="flake.nix" del={7} ins={8-10} { inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; }; outputs = { nixpkgs, ... }: { devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {}; devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell { packages = [ nixpkgs.legacyPackages.x86_64-linux.hello ]; }; }; } ``` (Run `nix develop`, and then we have the `hello` executable available.): ```shell > nix develop (nix-shell-env)> hello Hello, world! ``` Let's clean this up a bit, and then we're done for now. There's lots of repetition in the current file, and the solution to this is not as easy as inserting a `let` block. The accepted and easily extensible solution for this is flake-parts, but their homepage is pretty hard to understand at first. We want to translate our example to this: ```nix title="flake.nix" { inputs = { nixpkgs.url = "https://github.com/nixos/nixpkgs?ref=nixos-unstable"; }; outputs = inputs@{ flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; perSystem = { pkgs, ... }: { devShells.default = pkgs.mkShell { packages = [ pkgs.hello ]; }; }; }; } ``` This even has the benefit that it will work on all the systems specified. <Draft> # Evaluated Flake top level You can inspect your flake like this: ```shell nix repl . > :load-flake . # shorthand ':lf .' ``` ```nix { _type = "flake"; inputs = { ... }; outputs = { ... }; sourceInfo = { ... }; } ``` </Draft> <References> <ReferenceLink href="https://www.youtube.com/watch?v=JCeYq72Sko0">vimjoyer flakes guide</ReferenceLink> </References>
Especially this here for Nix Flakes :)
#Nix #Simplicity #FunctionalProgramming
Originally posted at https://beathagenlocher.com/nix
# Install Nix The installer on the website sucks (doesn't work with SELinux, for example), but there is a community-maintained one: ```shell curl -fsSL https://artifacts.nixos.org/nix-installer | sh -s -- install ``` With that completed, go write your first Nix Flake
I've added a bit more barebones Nix stuff that can be confusing at first :)
#Nix #OS #ProgrammingLanguage #nixpkgs #NixOS #FunctionalProgramming #DeclarativeProgramming
Well, this is how it starts.. ^^
Never heard of webrings before. Thanks for writing this up!
Sure! :)
Specifically constructions like
"Not x. Not y. Just z"
"That's not x. It's y"
and similar :)
Just leaving that here for feedback (with which you can do what you want :)) :
Your posts sound pretty AI-sloppy to me.
(Though I can't say I'm getting more engagement with mine π¬)
Like the idea of posting every day very much, though :)
Originally posted at https://beathagenlocher.com/stream#00123
I did not know it's a thing that people are building desktop environments in the browser for fun: - https://webos.js.org/ - https://dustinbrett.com/ Wild.
Apparently this is a thing: Desktop Environments in the browser
#OS #TheWeb
Originally posted at https://beathagenlocher.com/stream#00122