Compare commits
No commits in common. "5cda6c844e70b75a2e2b498133586fa1c7a588ca" and "6baf0e1f9386e66702c2dac138d235f0ee6a1d84" have entirely different histories.
5cda6c844e
...
6baf0e1f93
22 changed files with 233 additions and 256 deletions
58
.build.yml
Normal file
58
.build.yml
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
image: alpine/edge
|
||||||
|
oauth: pages.sr.ht/PAGES:RW
|
||||||
|
packages:
|
||||||
|
- hut
|
||||||
|
- uv
|
||||||
|
environment:
|
||||||
|
site: ficd.sh
|
||||||
|
draft_site: draft.ficd.sh
|
||||||
|
proxy: ficd.srht.site
|
||||||
|
repo: ficd.sh
|
||||||
|
zona_repo: git+https://git.sr.ht/~ficd/zona
|
||||||
|
zona_ref: 71e541aa5e02a3e28a8b62bc7a1e609a9f6f7b78
|
||||||
|
tasks:
|
||||||
|
- build: |
|
||||||
|
if [ "$GIT_REF" = "refs/heads/main" ]; then
|
||||||
|
cd $repo
|
||||||
|
uv run --with "${zona_repo}@${zona_ref}" zona build --output public
|
||||||
|
else
|
||||||
|
echo "Skipping build: not on main"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- build_draft: |
|
||||||
|
if [ "$GIT_REF" = "refs/heads/main" ]; then
|
||||||
|
cd $repo
|
||||||
|
uv run --with "${zona_repo}@${zona_ref}" zona build --output public-draft --draft
|
||||||
|
else
|
||||||
|
echo "Skipping build: not on main"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- package: |
|
||||||
|
if [ "$GIT_REF" = "refs/heads/main" ]; then
|
||||||
|
cd $repo/public
|
||||||
|
tar -cvz . > ../public.tar.gz
|
||||||
|
else
|
||||||
|
echo "Skipping package: not on main"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- package_draft: |
|
||||||
|
if [ "$GIT_REF" = "refs/heads/main" ]; then
|
||||||
|
cd $repo/public-draft
|
||||||
|
tar -cvz . > ../public-draft.tar.gz
|
||||||
|
else
|
||||||
|
echo "Skipping package: not on main"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- upload: |
|
||||||
|
if [ "$GIT_REF" = "refs/heads/main" ]; then
|
||||||
|
hut pages publish -d "$site" $repo/public.tar.gz
|
||||||
|
hut pages publish -d "$proxy" $repo/public.tar.gz
|
||||||
|
else
|
||||||
|
echo "Skipping upload: not on main"
|
||||||
|
fi
|
||||||
|
- upload_draft: |
|
||||||
|
if [ "$GIT_REF" = "refs/heads/main" ]; then
|
||||||
|
hut pages publish -d "$draft_site" $repo/public-draft.tar.gz
|
||||||
|
else
|
||||||
|
echo "Skipping upload: not on main"
|
||||||
|
fi
|
|
@ -6,7 +6,6 @@ sitemap:
|
||||||
Now: /now
|
Now: /now
|
||||||
Git: /git
|
Git: /git
|
||||||
Contact: /contact
|
Contact: /contact
|
||||||
Rss: /rss.xml
|
|
||||||
ignore:
|
ignore:
|
||||||
- .git
|
- .git
|
||||||
- .env
|
- .env
|
||||||
|
|
|
@ -2,19 +2,16 @@
|
||||||
title: About
|
title: About
|
||||||
---
|
---
|
||||||
|
|
||||||
My name is Daniel, and I am a programmer, Linux enthusiast, and graduate student
|
My name is Daniel, and I am a programmer, Linux enthusiast, and graduate
|
||||||
of cybersecurity. My research interest is authentication, and I like programming
|
student of cybersecurity. My research interest is authentication, and I
|
||||||
in Python and POSIX shell. I spend my free time writing code, tinkering, and
|
like programming in Python and POSIX shell. I spend my free time writing
|
||||||
contributing to open-source projects. Feel free to [contact me](/contact) if you
|
code, tinkering, and contributing to open-source projects. Feel free to
|
||||||
want to see my resume or learn more about my work.
|
[contact me](/contact) if you want to see my resume or learn more about my
|
||||||
|
work.
|
||||||
|
|
||||||
[TOC]
|
I'm the author [zona] (a static site generator), [Ashen] (a color scheme),
|
||||||
|
and a number of [Kakoune] plugins. Check my various [Git] forge profiles
|
||||||
## My work
|
to see my latest work.
|
||||||
|
|
||||||
I'm the author [zona] (a static site generator), [Ashen] (a color scheme), and a
|
|
||||||
number of [Kakoune plugins](/kakoune). Check my various [Git] forge profiles to
|
|
||||||
see my latest work.
|
|
||||||
|
|
||||||
[zona]: https://git.ficd.sh/ficd/zona
|
[zona]: https://git.ficd.sh/ficd/zona
|
||||||
[Git]: /git
|
[Git]: /git
|
||||||
|
@ -23,25 +20,25 @@ see my latest work.
|
||||||
|
|
||||||
## Education
|
## Education
|
||||||
|
|
||||||
I completed a Bachelor's of Computing (Honours) at Queen's University in 2024,
|
I completed a Bachelor's of Computing (Honours) at Queen's University in
|
||||||
and I'm currently in the Master's of Science program at the School of Computing.
|
2024, and I'm currently in the Master's of Science program at the School
|
||||||
As part of the NSERC CREATE Cybersecurity program, my work combines programming,
|
of Computing. As part of the NSERC CREATE Cybersecurity program, my work
|
||||||
cryptography, system design, and threat modeling to tackle real-world security
|
combines programming, cryptography, system design, and threat modeling to
|
||||||
challenges. I'm currently working on my thesis, which introduces a novel method
|
tackle real-world security challenges. I'm currently working on my thesis,
|
||||||
of detecting signal relay attacks in the context of multi-factor authentication.
|
which introduces a novel method of detecting signal relay attacks in the
|
||||||
|
context of multi-factor authentication.
|
||||||
|
|
||||||
## Things I use
|
## Stack
|
||||||
|
|
||||||
I use [Kakoune] as my text editor, and I type in
|
I use [Kakoune] as my text editor, and I type in
|
||||||
[Colemak-DH](https://colemakmods.github.io/mod-dh/) on a
|
[Colemak-DH](https://colemakmods.github.io/mod-dh/) on a
|
||||||
[custom layout](https://git.ficd.sh/ficd/zmk). I run Arch Linux on a desktop PC
|
[custom layout](https://git.ficd.sh/ficd/zmk). I run Arch Linux on a
|
||||||
and ThinkPad, my preferred terminal is Foot, and I enjoy Niri as a window
|
desktop PC and ThinkPad, my preferred terminal is Foot, and I enjoy Niri
|
||||||
manager.
|
as a window manager.
|
||||||
|
|
||||||
## This Website
|
## This Website
|
||||||
|
|
||||||
This website is my personal blog and homepage. It's
|
This website is my personal blog and homepage. It's
|
||||||
[JavaScript free](https://jsfree.org/), and registered on
|
[JavaScript free](https://jsfree.org/), and registered on
|
||||||
[1mb.club](https://1mb.club/). The color scheme is [Ashen], and it was built
|
[1mb.club](https://1mb.club/). The color scheme is [Ashen], and it was
|
||||||
using [zona]. I'm working on a post describing my process for building it ---
|
built using [zona].
|
||||||
stay tuned if you're interested.
|
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
title: How I'm Surviving The AI Programming Epidemic
|
title: How I'm Surviving The AI Programming Epidemic
|
||||||
date: Wed 09 Jul 2025
|
date: Wed 09 Jul 2025
|
||||||
draft: true
|
draft: true
|
||||||
description: |
|
|
||||||
My thoughts on AI programming, and my self-imposed rules and workflow when it comes
|
|
||||||
to AI integration.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This post should cover my thoughts about AI assisted programming, vibe-coding,
|
This post should cover my thoughts about AI assisted programming,
|
||||||
and my personal rules and workflow when it comes to AI integration to keep
|
vibe-coding, and my personal rules and workflow when it comes to AI
|
||||||
myself from becoming reliant on it and to help myself keep learning.
|
integration to keep myself from becoming reliant on it and to help myself
|
||||||
|
keep learning.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: angels and wires
|
title: angels and wires
|
||||||
date: 2025-07-16
|
date: 2025-07-16
|
||||||
description: A poem about technology. And mushrooms.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="image-container">
|
<div class="image-container">
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
title: Building My Own Static Site Generator
|
title: Building My Own Static Site Generator
|
||||||
date: 2025-07-10
|
date: 2025-07-10
|
||||||
draft: true
|
draft: true
|
||||||
description: |
|
|
||||||
An overview of static site generators and my experience of developing Zona.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*[SSG]: Static Site Generator
|
*[SSG]: Static Site Generator
|
||||||
|
@ -19,73 +17,75 @@ description: |
|
||||||
|
|
||||||
[^jd]: [jdugan6240.dev](https://jdugan6240.dev/posts/custom_site_generator.html#why)
|
[^jd]: [jdugan6240.dev](https://jdugan6240.dev/posts/custom_site_generator.html#why)
|
||||||
|
|
||||||
[^long-sentence]: I disabled the "long sentences" linter in my grammar checker.
|
[^long-sentence]: I disabled the "long sentences" linter in my grammar
|
||||||
Take that for being unapologetic!
|
checker. Take that for being unapologetic!
|
||||||
|
|
||||||
[^small-web]: The "small web" is a way to collectively refer to independent,
|
[^small-web]: The "small web" is a way to collectively refer to
|
||||||
home-made, personal websites --- often with a focus on creativity,
|
independent, home-made, personal websites --- often with a focus on
|
||||||
anti-capitalism, and technology.
|
creativity, anti-capitalism, and technology.
|
||||||
|
|
||||||
Those of us in the open-source world tend to be very _passionate_ about what we
|
Those of us in the open-source world tend to be very _passionate_ about
|
||||||
do — and passion often manifests itself in _blogging_. Rolling your own blogging
|
what we do — and passion often manifests itself in _blogging_. Rolling
|
||||||
setup seems to be a rite of passage. It's a project of moderate complexity, fun,
|
your own blogging setup seems to be a rite of passage. It's a project of
|
||||||
and not particularly time-consuming.
|
moderate complexity, fun, and not particularly time-consuming.
|
||||||
|
|
||||||
Personal websites and blogs are very... personal. Why not maximize the control
|
Personal websites and blogs are very... personal. Why not maximize the
|
||||||
we have over them? Many of the programmers I respect publish blogs using a
|
control we have over them? Many of the programmers I respect publish blogs
|
||||||
[homebrewed] SSG. I figured it was time to join them!
|
using a [homebrewed] SSG. I figured it was time to join them!
|
||||||
|
|
||||||
This article is about how (and why) I built [zona], the SSG that built and
|
This article is about how (and why) I built [zona], the SSG that built and
|
||||||
rendered the blog post you're reading. Without any further ado, let's get into
|
rendered the blog post you're reading. Without any further ado, let's get
|
||||||
it!
|
into it!
|
||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
|
||||||
## Zonelets & Zoner
|
## Zonelets & Zoner
|
||||||
|
|
||||||
I don't remember how I found out about the small web,[^small-web], but I _do_
|
I don't remember how I found out about the small web,[^small-web], but I
|
||||||
recall how it immediately sparked something in me. As an autist with very
|
_do_ recall how it immediately sparked something in me. As an autist with
|
||||||
particular interests that's always struggled to fit in, the premise of having my
|
very particular interests that's always struggled to fit in, the premise
|
||||||
very own corner of the internet where I could unapologetically be myself without
|
of having my very own corner of the internet where I could
|
||||||
fear of retribution from rude social-media commenters or being subject to the
|
unapologetically be myself without fear of retribution from rude
|
||||||
whims of some grumpy content moderator was _very_ appealing to me.[^long-sentence]
|
social-media commenters or being subject to the whims of some grumpy
|
||||||
|
content moderator was _very_ appealing to me.[^long-sentence]
|
||||||
|
|
||||||
## Reinventing The Wheel
|
## Reinventing The Wheel
|
||||||
|
|
||||||
There's no shortage of excellent SSG tools out there. [Hugo] is fast,
|
There's no shortage of excellent SSG tools out there. [Hugo] is fast,
|
||||||
configurable, and very popular. [Jekyll] is the default on GitHub pages, which
|
configurable, and very popular. [Jekyll] is the default on GitHub pages,
|
||||||
makes it _(I'm guessing)_ the most commonly-used SSG by a long shot. [Zola] is
|
which makes it _(I'm guessing)_ the most commonly-used SSG by a long shot.
|
||||||
tiny, dependency free, and _very_ flexible.
|
[Zola] is tiny, dependency free, and _very_ flexible.
|
||||||
|
|
||||||
You can certainly build some awesome blogs with these tools, and customize them
|
You can certainly build some awesome blogs with these tools, and customize
|
||||||
as much as you want. For example, my friend Alisa uses [Zola] to publish
|
them as much as you want. For example, my friend Alisa uses [Zola] to
|
||||||
[her blog](https://axlefublr.github.io/), which is a great example of how a
|
publish [her blog](https://axlefublr.github.io/), which is a great example
|
||||||
minimal website can truly shine with the right styling and customization.
|
of how a minimal website can truly shine with the right styling and
|
||||||
|
customization.
|
||||||
|
|
||||||
So: if there's such an abundance of great static site generators, why did I
|
So: if there's such an abundance of great static site generators, why did
|
||||||
write my own? JD[^jd], a fellow Kakoune enjoyer, puts it well:
|
I write my own? JD[^jd], a fellow Kakoune enjoyer, puts it well:
|
||||||
|
|
||||||
> 1. It's a good learning experience \[...\]
|
> 1. It's a good learning experience \[...\]
|
||||||
> 2. Many static site generators are complex and take time to learn to configure
|
> 2. Many static site generators are complex and take time to learn to
|
||||||
> \[...\]
|
> configure \[...\]
|
||||||
> 3. A custom solution grants complete control over how exactly the site is
|
> 3. A custom solution grants complete control over how exactly the site
|
||||||
> generated \[...\]
|
> is generated \[...\]
|
||||||
|
|
||||||
My main motivation for starting work on [zona] was the third point: **complete
|
My main motivation for starting work on [zona] was the third point:
|
||||||
control**. I don't think being a control freak makes me an outlier among Linux
|
**complete control**. I don't think being a control freak makes me an
|
||||||
users — why else would we be breaking our operating system near-daily, if not
|
outlier among Linux users — why else would we be breaking our operating
|
||||||
for some obsessive customization?
|
system near-daily, if not for some obsessive customization?
|
||||||
|
|
||||||
It's happened very often that I find some tool I like, and during the process of
|
It's happened very often that I find some tool I like, and during the
|
||||||
tweaking it, I find _something_ that can't be changed --- which ends up
|
process of tweaking it, I find _something_ that can't be changed --- which
|
||||||
bothering me immensely. I figured that I'd rather avoid this experience while
|
ends up bothering me immensely. I figured that I'd rather avoid this
|
||||||
writing my own blog. This way, if something is missing, it's my fault, and no
|
experience while writing my own blog. This way, if something is missing,
|
||||||
one else's.
|
it's my fault, and no one else's.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
The features I implemented in [zona] are informed by what I want from my own
|
The features I implemented in [zona] are informed by what I want from my
|
||||||
blog. The primary user is myself, after all! I knew I wanted:
|
own blog. The primary user is myself, after all! I knew I wanted:
|
||||||
|
|
||||||
- Writing in Markdown with as little embedded HTML as possible.
|
- Writing in Markdown with as little embedded HTML as possible.
|
||||||
- A convenient live preview.
|
- A convenient live preview.
|
||||||
|
@ -96,6 +96,6 @@ blog. The primary user is myself, after all! I knew I wanted:
|
||||||
|
|
||||||
## Snakes Eating Gophers: A Valiant First Attempt
|
## Snakes Eating Gophers: A Valiant First Attempt
|
||||||
|
|
||||||
I started work on [zona] in October, 2024. At this point, I had written a few
|
I started work on [zona] in October, 2024. At this point, I had written a
|
||||||
(smaller) projects in Go, and I wanted to work on something more complicated to
|
few (smaller) projects in Go, and I wanted to work on something more
|
||||||
learn the language better.
|
complicated to learn the language better.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Building This Site
|
title: Building This Site
|
||||||
date: 2025-04-10
|
date: 2025-04-10
|
||||||
description: Short post about why I'm publishing this website.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
I care about thoughtful design, and forcing your visitors to download dozens of
|
I care about thoughtful design, and forcing your visitors to download dozens of
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Email Formatting Is Harder Than It Looks
|
title: Email Formatting Is Harder Than It Looks
|
||||||
date: 2025-07-14
|
date: 2025-07-14
|
||||||
description: |
|
|
||||||
A detailed overview of plain-text email formatting, what makes it deceptively
|
|
||||||
hard, and how I wrote mailfmt.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*[UTF-8]: Unicode Transformation Format – 8 bit. Text encoding standard.
|
*[UTF-8]: Unicode Transformation Format – 8 bit. Text encoding standard.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Writing Emails In Helix
|
title: Writing Emails In Helix
|
||||||
date: 2025-05-29
|
date: 2025-05-29
|
||||||
description: Tutorial on configuring Helix for email composition.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This article is all about writing emails in Helix. Obviously, Helix isn't an
|
This article is all about writing emails in Helix. Obviously, Helix isn't an
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
---
|
---
|
||||||
title: Writing Emails In Kakoune
|
title: Writing Emails In Kakoune
|
||||||
date: 2025-06-01
|
date: 2025-06-01
|
||||||
description: Tutorial on configuring Kakoune for email reading & composition.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This post will guide you through my setup for using Kakoune as an email composer
|
This post will guide you through my setup for using Kakoune as an email
|
||||||
inside `aerc`. I'll also explain how to configure Kakoune to act as the _pager_
|
composer inside `aerc`. I'll also explain how to configure Kakoune to act
|
||||||
for reading `text/plain` emails. If you only care about the final config, feel
|
as the _pager_ for reading `text/plain` emails. If you only care about the
|
||||||
free to skip to it [here](#final-configuration).
|
final config, feel free to skip to it [here](#final-configuration).
|
||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
|
||||||
## Naive Approach
|
## Naive Approach
|
||||||
|
|
||||||
Since `aerc` uses your `$EDITOR` for composition, you don't technically have to
|
Since `aerc` uses your `$EDITOR` for composition, you don't technically
|
||||||
do anything. I prefer setting it explicitly in `aerc.conf`, for good measure:
|
have to do anything. I prefer setting it explicitly in `aerc.conf`, for
|
||||||
|
good measure:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[compose]
|
[compose]
|
||||||
|
@ -25,8 +25,9 @@ The rest of the magic happens in your `kakrc`.
|
||||||
|
|
||||||
## Composer Setup
|
## Composer Setup
|
||||||
|
|
||||||
Essentially, we want to hook `filetype=mail` and set our buffer configuration
|
Essentially, we want to hook `filetype=mail` and set our buffer
|
||||||
there. I'll share a recommended configuration with some explanation.
|
configuration there. I'll share a recommended configuration with some
|
||||||
|
explanation.
|
||||||
|
|
||||||
```kak
|
```kak
|
||||||
hook global WinSetOption filetype=mail %~
|
hook global WinSetOption filetype=mail %~
|
||||||
|
@ -41,51 +42,53 @@ hook global WinSetOption filetype=mail %~
|
||||||
~
|
~
|
||||||
```
|
```
|
||||||
|
|
||||||
I use a custom formatter to format emails. It automatically hard-wraps lines
|
I use a custom formatter to format emails. It automatically hard-wraps
|
||||||
while preserving certain markup elements, code blocks, sign-offs, and signature
|
lines while preserving certain markup elements, code blocks, sign-offs,
|
||||||
blocks. For more details, check the formatting section of my post on
|
and signature blocks. For more details, check the formatting section of my
|
||||||
[Helix](/blog/email/helix#formatting).
|
post on [Helix](/blog/email/helix#formatting).
|
||||||
|
|
||||||
I find that setting `>` as the `comment_line` token is convenient for working
|
I find that setting `>` as the `comment_line` token is convenient for
|
||||||
with quotes in replies.
|
working with quotes in replies.
|
||||||
|
|
||||||
The `try autospell-enable` enables my
|
The `try autospell-enable` enables my
|
||||||
[kak-autospell](https://codeberg.org/ficd/kak-autospell) plugin for the buffer.
|
[kak-autospell](https://codeberg.org/ficd/kak-autospell) plugin for the
|
||||||
Essentially, it provides spellchecking that's continuously refreshed and hidden
|
buffer. Essentially, it provides spellchecking that's continuously
|
||||||
in insert mode.
|
refreshed and hidden in insert mode.
|
||||||
|
|
||||||
The remaining commands configure auto-formatting on save. I always prefer having
|
The remaining commands configure auto-formatting on save. I always prefer
|
||||||
this on so I never forget to format my message before sending it.
|
having this on so I never forget to format my message before sending it.
|
||||||
|
|
||||||
## Reader Setup
|
## Reader Setup
|
||||||
|
|
||||||
I find that using Kakoune to **read** emails is helpful because of how easy it
|
I find that using Kakoune to **read** emails is helpful because of how
|
||||||
is to copy quotes, open links, etc. Configuring this is a tad hackier, however.
|
easy it is to copy quotes, open links, etc. Configuring this is a tad
|
||||||
The basic idea is to set Kakoune as the viewer `pager` in `aerc.conf`.
|
hackier, however. The basic idea is to set Kakoune as the viewer `pager`
|
||||||
|
in `aerc.conf`.
|
||||||
|
|
||||||
However, all this does is pipe the email to `kak` through standard input, so we
|
However, all this does is pipe the email to `kak` through standard input,
|
||||||
need to tell the editor to treat it like an email:
|
so we need to tell the editor to treat it like an email:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[viewer]
|
[viewer]
|
||||||
pager=kak -e 'set buffer filetype mail'
|
pager=kak -e 'set buffer filetype mail'
|
||||||
```
|
```
|
||||||
|
|
||||||
When you're using Kakoune as a pager, you'll probably want to configure some
|
When you're using Kakoune as a pager, you'll probably want to configure
|
||||||
things differently. In my case, I like to set the buffer as `readonly`, remove
|
some things differently. In my case, I like to set the buffer as
|
||||||
the `number-lines` and `show-whitespaces` highlighters, disable soft-wrap & my
|
`readonly`, remove the `number-lines` and `show-whitespaces` highlighters,
|
||||||
scrolloff settings, and _not_ set any formatters.
|
disable soft-wrap & my scrolloff settings, and _not_ set any formatters.
|
||||||
|
|
||||||
The `pager` command above sets the filetype, but we need to distinguish between
|
The `pager` command above sets the filetype, but we need to distinguish
|
||||||
_composing_ and _reading_ in our Kakoune hook. When Kakoune is opened with input
|
between _composing_ and _reading_ in our Kakoune hook. When Kakoune is
|
||||||
through standard input, it loads a buffer that's conveniently named `*stdin*`.
|
opened with input through standard input, it loads a buffer that's
|
||||||
Thus, we can check the buffer name before continuing.
|
conveniently named `*stdin*`. Thus, we can check the buffer name before
|
||||||
|
continuing.
|
||||||
|
|
||||||
If we're in "reading mode", we define a hidden command called `ismailreader`
|
If we're in "reading mode", we define a hidden command called
|
||||||
which doesn't do anything. Why? If the command is defined, and we try to invoke
|
`ismailreader` which doesn't do anything. Why? If the command is defined,
|
||||||
it... well, nothing happens! But if it's **not** defined, we get an error
|
and we try to invoke it... well, nothing happens! But if it's **not**
|
||||||
instead. We can combine this with the `try` command to for some simple boolean
|
defined, we get an error instead. We can combine this with the `try`
|
||||||
logic.
|
command to for some simple boolean logic.
|
||||||
|
|
||||||
```kak
|
```kak
|
||||||
evaluate-commands %sh{
|
evaluate-commands %sh{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Implementing Kakoune Syntax Highlighting In Pygments
|
title: Implementing Kakoune Syntax Highlighting In Pygments
|
||||||
date: July 04, 2025
|
date: July 04, 2025
|
||||||
description: An account of my implementation of a Kakoune lexer in Pygments.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
As a programmer, one thing I care about a _lot_ is syntax highlighting. In fact,
|
As a programmer, one thing I care about a _lot_ is syntax highlighting. In fact,
|
||||||
|
@ -109,5 +108,4 @@ own projects.
|
||||||
[Kakoune]: https://kakoune.org
|
[Kakoune]: https://kakoune.org
|
||||||
[Helix]: https://github.com/helix-editor/helix
|
[Helix]: https://github.com/helix-editor/helix
|
||||||
[Pygments]: https://pygments.org/
|
[Pygments]: https://pygments.org/
|
||||||
|
|
||||||
*[SSG]: Static Site Generator
|
*[SSG]: Static Site Generator
|
||||||
|
|
|
@ -4,4 +4,7 @@ template: post_list
|
||||||
post: false
|
post: false
|
||||||
---
|
---
|
||||||
|
|
||||||
Likely topics: text editors, command line, Linux, and programming.
|
Welcome to my blog. Expect to find posts about Linux, text editors, and
|
||||||
|
programming. If you have questions about something I've written, please
|
||||||
|
[contact](/contact) me.
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
title: "Kakoune: Markdown Formatter Ignore"
|
title: "Kakoune: Markdown Formatter Ignore"
|
||||||
date: 2025-07-09
|
date: 2025-07-09
|
||||||
draft: true
|
draft: true
|
||||||
description: |
|
|
||||||
An account of Markdown formatter pre-processing. In Kakoune, just because.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This post about the markdown formatting mini-plugin I wrote which can ignore
|
This post about the markdown formatting mini-plugin I wrote which can
|
||||||
block images by regex.
|
ignore block images by regex.
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
---
|
---
|
||||||
title: Opening URLs In Kakoune
|
title: Opening URLs In Kakoune
|
||||||
date: 07 Jul 2025
|
date: 07 Jul 2025
|
||||||
description: |
|
|
||||||
A brief post about how I implemented URL opening in Kakoune.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[Kakoune]: https://kakoune.org
|
[Kakoune]: https://kakoune.org
|
||||||
|
|
||||||
One feature built into [Helix](https://docs.helix-editor.com/) is the ability to
|
One feature built into [Helix](https://docs.helix-editor.com/) is the
|
||||||
super-easily open URLs in your browser. All you need to do is move your cursor
|
ability to super-easily open URLs in your browser. All you need to do is
|
||||||
over a URL, and press `gf`. This is _very_ helpful when reading documentation,
|
move your cursor over a URL, and press `gf`. This is _very_ helpful when
|
||||||
emails, et cetera...
|
reading documentation, emails, et cetera...
|
||||||
|
|
||||||
So, how can we do this in [Kakoune]?
|
So, how can we do this in [Kakoune]?
|
||||||
|
|
||||||
|
@ -26,15 +24,16 @@ Here's our target user experience:
|
||||||
4. The user is notified of any errors or success.
|
4. The user is notified of any errors or success.
|
||||||
|
|
||||||
Like any bit of custom functionality, the best way to go is to define a
|
Like any bit of custom functionality, the best way to go is to define a
|
||||||
**command**. This gives us re-usability, and greater flexibility (since `map`
|
**command**. This gives us re-usability, and greater flexibility (since
|
||||||
only allows mapping to _key sequences_, not any arbitrary string of commands).
|
`map` only allows mapping to _key sequences_, not any arbitrary string of
|
||||||
|
commands).
|
||||||
|
|
||||||
## Selecting
|
## Selecting
|
||||||
|
|
||||||
First, we need to find the URL under the cursor. Of course, if there _isn't_
|
First, we need to find the URL under the cursor. Of course, if there
|
||||||
one, we should fail at this step. The standard way to do this in Kakoune is by
|
_isn't_ one, we should fail at this step. The standard way to do this in
|
||||||
using a regular expression to filter the selection. If there's no matches at
|
Kakoune is by using a regular expression to filter the selection. If
|
||||||
all, that's something we can `try/catch`.
|
there's no matches at all, that's something we can `try/catch`.
|
||||||
|
|
||||||
We won't get far without a URL regex. When I'm including long regexes in
|
We won't get far without a URL regex. When I'm including long regexes in
|
||||||
`#!kak execute-keys` commands, I like saving them to a register, like so:
|
`#!kak execute-keys` commands, I like saving them to a register, like so:
|
||||||
|
@ -43,23 +42,24 @@ We won't get far without a URL regex. When I'm including long regexes in
|
||||||
set-register b 'https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)'
|
set-register b 'https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)'
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, we just need to check if this regex exists around the user's cursor. Since
|
Then, we just need to check if this regex exists around the user's cursor.
|
||||||
URLs don't have spaces, we can select the surrounding `WORD`, and filter from
|
Since URLs don't have spaces, we can select the surrounding `WORD`, and
|
||||||
there:
|
filter from there:
|
||||||
|
|
||||||
```kak
|
```kak
|
||||||
execute-keys -draft '<a-a><a-w>s<c-r>b<ret>"ay'
|
execute-keys -draft '<a-a><a-w>s<c-r>b<ret>"ay'
|
||||||
```
|
```
|
||||||
|
|
||||||
The above command selects the outer `WORD`, then runs the select command with
|
The above command selects the outer `WORD`, then runs the select command
|
||||||
our regex (stored in register `b`). Once the URL has been selected, it's copied
|
with our regex (stored in register `b`). Once the URL has been selected,
|
||||||
to the `a` register. If there is no URL, the command fails.
|
it's copied to the `a` register. If there is no URL, the command fails.
|
||||||
|
|
||||||
## Cleaning
|
## Cleaning
|
||||||
|
|
||||||
It's usually better to allow regex to be a bit greedier, and then filter
|
It's usually better to allow regex to be a bit greedier, and then
|
||||||
unwanted characters out of the result. In our case, some trailing punctuation is
|
filter unwanted characters out of the result. In our case, some
|
||||||
included in the capture -- we can use `sed` in a shell block to strip them.
|
trailing punctuation is included in the capture -- we can use `sed`
|
||||||
|
in a shell block to strip them.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
clean_url="$(echo "$kak_reg_a" | sed 's/[][(){}.,;!?]*$//')"
|
clean_url="$(echo "$kak_reg_a" | sed 's/[][(){}.,;!?]*$//')"
|
||||||
|
@ -67,37 +67,37 @@ clean_url="$(echo "$kak_reg_a" | sed 's/[][(){}.,;!?]*$//')"
|
||||||
|
|
||||||
## Opening
|
## Opening
|
||||||
|
|
||||||
Our next step is to figure out how we'd open a URL from the shell -- after all,
|
Our next step is to figure out how we'd open a URL from the shell --
|
||||||
anything we implement in Kakoune ends up running shell commands! If you have
|
after all, anything we implement in Kakoune ends up running shell
|
||||||
`xdg-open` available (part of the `xdg-utils` package on Arch Linux), this is
|
commands! If you have `xdg-open` available (part of the `xdg-utils`
|
||||||
simple:
|
package on Arch Linux), this is simple:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
xdg-open https://ficd.sh
|
xdg-open https://ficd.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
XDG handles figuring out the correct application to forward the URL to. If your
|
XDG handles figuring out the correct application to forward the URL to. If
|
||||||
environment is set up properly, this is probably your default browser. If you
|
your environment is set up properly, this is probably your default
|
||||||
don't have (or don't want to use) `xdg-open`, most browsers let you open URLs
|
browser. If you don't have (or don't want to use) `xdg-open`, most
|
||||||
from the command line directly:
|
browsers let you open URLs from the command line directly:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
firefox https://ficd.sh
|
firefox https://ficd.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Depending on the browser -- if you already have an open session, the link will
|
Depending on the browser -- if you already have an open session, the link
|
||||||
be opened as a new tab in an existing window. Nice!
|
will be opened as a new tab in an existing window. Nice!
|
||||||
|
|
||||||
Let's define an **option** which contains the shell command we'll use to open
|
Let's define an **option** which contains the shell command we'll
|
||||||
the link:
|
use to open the link:
|
||||||
|
|
||||||
```kak
|
```kak
|
||||||
# %s gets replaced with the URL
|
# %s gets replaced with the URL
|
||||||
declare-option str url_open_cmd 'xdg-open %s'
|
declare-option str url_open_cmd 'xdg-open %s'
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, in our shell block, we can substitute the cleaned URL into the `%s` format
|
Then, in our shell block, we can substitute the cleaned URL into the `%s`
|
||||||
specifier, and evaluate the resulting string as a command:
|
format specifier, and evaluate the resulting string as a command:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
if eval "$(printf "$kak_opt_url_open_cmd" "$clean_url")" >/dev/null 2>&1; then
|
if eval "$(printf "$kak_opt_url_open_cmd" "$clean_url")" >/dev/null 2>&1; then
|
||||||
|
@ -109,8 +109,8 @@ fi
|
||||||
|
|
||||||
## Completed Plugin
|
## Completed Plugin
|
||||||
|
|
||||||
That's it, that's all! We now have a command called `url-open`, which we can
|
That's it, that's all! We now have a command called `url-open`,
|
||||||
easily bind to something like `gu`:
|
which we can easily bind to something like `gu`:
|
||||||
|
|
||||||
```kak
|
```kak
|
||||||
map global goto u '<esc>: url-open<ret>'
|
map global goto u '<esc>: url-open<ret>'
|
||||||
|
@ -148,3 +148,4 @@ define-command -docstring %{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Automatically Mirror Sr.ht To GitHub
|
title: Automatically Mirror Sr.ht To GitHub
|
||||||
date: 2025-05-15
|
date: 2025-05-15
|
||||||
description: Brief tutorial on setting up automatic mirroring from sr.ht to github.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
For a variety of reasons, I've recently migrated to [sr.ht](https://sr.ht/~ficd)
|
For a variety of reasons, I've recently migrated to [sr.ht](https://sr.ht/~ficd)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: On Websites (Or The Case For The Personal Web)
|
title: On Websites (Or The Case For The Personal Web)
|
||||||
date: 2025-05-05
|
date: 2025-05-05
|
||||||
description: My thoughts on websites, DIY, and the small web.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Preamble
|
## Preamble
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Rediscovering Email
|
title: Rediscovering Email
|
||||||
date: 2025-03-24
|
date: 2025-03-24
|
||||||
description: My experience of delving into email. Nerdily.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Preamble
|
## Preamble
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
title: Why Text Editing Matters
|
title: Why Text Editing Matters
|
||||||
date: Wed 09 Jul 2025
|
date: Wed 09 Jul 2025
|
||||||
draft: true
|
draft: true
|
||||||
description: A manifesto on why we should care about our text editing experience.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This post will gather my thoughts in general about why text editing, and caring
|
This post will gather my thoughts in general about why text editing, and
|
||||||
about your text editor experience, really matters, especially for programmers
|
caring about your text editor experience, really matters, especially for
|
||||||
and writers.
|
programmers and writers.
|
||||||
|
|
||||||
- Keep this less focused on any particular editor, and more about the general
|
- Keep this less focused on any particular editor, and more about the
|
||||||
principles of why modal editing is cool and the ideological/personal reasons I
|
general principles of why modal editing is cool and the
|
||||||
have for caring so much about my editor. Can reference vim & kakoune but the
|
ideological/personal reasons I have for caring so much about my editor.
|
||||||
kakoune deep-dive will get its own post.
|
Can reference vim & kakoune but the kakoune deep-dive will get its own
|
||||||
|
post.
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: The Lovecraftian Internet
|
title: The Lovecraftian Internet
|
||||||
date: 2025-04-05
|
date: 2025-04-05
|
||||||
description: Brief post about how the internet is very, very big.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
The web we know is spun by gluttonous spiders no longer satiated by flies and
|
The web we know is spun by gluttonous spiders no longer satiated by flies and
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title: Why Kakoune?
|
title: Why Kakoune?
|
||||||
date: July 6, 2025
|
date: July 6, 2025
|
||||||
draft: true
|
draft: true
|
||||||
description: Detailing my experience with Kakoune and why I think it's so great.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Blog post explaining why I switched to and really enjoy using Kakoune.
|
Blog post explaining why I switched to and really enjoy using Kakoune.
|
||||||
|
|
||||||
|
|
|
@ -7,26 +7,14 @@ title: Git
|
||||||
[codeberg]: https://codeberg.org/ficd
|
[codeberg]: https://codeberg.org/ficd
|
||||||
[github]: https://github.com/ficcdaf
|
[github]: https://github.com/ficcdaf
|
||||||
|
|
||||||
## forge profiles
|
My main forge for projects on which I expect to _collaborate_ is
|
||||||
|
[codeberg]. I [self-host a Forgejo instance](https://git.ficd.sh/ficd) for
|
||||||
My main forge for projects on which I expect to _collaborate_ is [codeberg]. I
|
my personal projects. I have repositories on [git.sr.ht], but I'm
|
||||||
[self-host a Forgejo instance](https://git.ficd.sh/ficd) for my personal
|
currently in the process of migrating to [codeberg] -- don't expect the
|
||||||
projects. I have repositories on [git.sr.ht], but I'm currently in the process
|
old repositories to stay mirrored. Finally, I use [github] _only_ if I'm
|
||||||
of migrating to [codeberg] -- don't expect the old repositories to stay
|
contributing to a project hosted there.
|
||||||
mirrored. Finally, I use [github] _only_ if I'm contributing to a project hosted
|
|
||||||
there.
|
|
||||||
|
|
||||||
- [git.ficd.sh] (self-hosted)
|
- [git.ficd.sh] (self-hosted)
|
||||||
- [codeberg]
|
- [codeberg]
|
||||||
- [git.sr.ht]
|
- [git.sr.ht]
|
||||||
- [github]
|
- [github]
|
||||||
|
|
||||||
## selected projects
|
|
||||||
|
|
||||||
Here are some of my projects you may be interested in. To see the rest, please
|
|
||||||
check my [profiles](#forge-profiles).
|
|
||||||
|
|
||||||
- [kakoune plugins](/kakoune)
|
|
||||||
- [zona](https://git.ficd.sh/ficd/zona)
|
|
||||||
- [ashen](https://codeberg.org/ficd/ashen)
|
|
||||||
- [`mailfmt`](https://git.ficd.sh/ficd/mailfmt)
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
---
|
|
||||||
title: Kakoune
|
|
||||||
---
|
|
||||||
|
|
||||||
[Kakoune]: https://kakoune.org
|
|
||||||
|
|
||||||
Here is a list of [Kakoune]-related software I've written:
|
|
||||||
|
|
||||||
[TOC]
|
|
||||||
|
|
||||||
## `pygments-kakoune`
|
|
||||||
|
|
||||||
An implementation of Kakoune command lexing for the Pygments syntax highlighting
|
|
||||||
library. [Repo](https://codeberg.org/ficd/pygments-kakoune)
|
|
||||||
|
|
||||||
## `kak-ashen`
|
|
||||||
|
|
||||||
Implementation of [Ashen](https://codeberg.org/ficd/ashen) for Kakoune.
|
|
||||||
[Repo](https://codeberg.org/ficd/kak-ashen)
|
|
||||||
|
|
||||||
## `kak-search-highlight`
|
|
||||||
|
|
||||||
Plugin for interactively highlighting search terms in Kakoune.
|
|
||||||
[Repo](https://codeberg.org/ficd/kak-search-highlight)
|
|
||||||
|
|
||||||
## `kak-ltex-dictionary`
|
|
||||||
|
|
||||||
Hack implementing "add to dictionary" functionality for
|
|
||||||
[`ltex-ls`](https://github.com/ltex-plus/ltex-ls-plus) through `kakoune-lsp`.
|
|
||||||
[Repo](https://codeberg.org/ficd/kak-ltex-dictionary)
|
|
||||||
|
|
||||||
## `kak-autospell`
|
|
||||||
|
|
||||||
Small plugin to make working with Kakoune `stdlib`'s `spell`' plugin more
|
|
||||||
convenient. [Repo](https://codeberg.org/ficd/kak-autospell)
|
|
||||||
|
|
||||||
## `kak-fish`
|
|
||||||
|
|
||||||
Implementation of `fish %{...}` command evaluation for Kakoune.
|
|
||||||
[Repo](https://codeberg.org/ficd/kak-fishr)
|
|
||||||
|
|
||||||
## `kak-title-bar`
|
|
||||||
|
|
||||||
Plugin implementing a live buffer list as the terminal window title.
|
|
||||||
[Repo](https://codeberg.org/ficd/kak-title-bar)
|
|
||||||
|
|
||||||
## `kak-lsp-diags`
|
|
||||||
|
|
||||||
Companion plugin to `kakoune-lsp` adding inlay diagnostics on hover support.
|
|
||||||
[Repo](https://codeberg.org/ficd/kak-lsp-diags)
|
|
||||||
|
|
||||||
## `byline.kak`
|
|
||||||
|
|
||||||
Fork of [`byline.kak`](https://github.com/evanrelf/byline.kak) (which adds
|
|
||||||
Helix-like behavior to `x` and `X`) --- improving performance by 17 times.
|
|
||||||
[Repo](https://codeberg.org/ficd/byline.kak)
|
|
Loading…
Add table
Add a link
Reference in a new issue