News for hackers. Stuff that matters.

Wilfred

Re:Type Server Protocol on Monday October 26, 2026 @04:22PM (#50250368)
It seems to be a more structured representation of the type. Normally in LSP you'd have a plain string or markdown that you render in the IDE, but nothing that you can analyse structurally.

It's a shame it's not just an LSP extension though, or a feature in a newer LSP version. LSP is maintained by Microsoft engineers.

This is actually possible with glasses-mode in Emacs: https://codelearn.me/2025/02/24/emacs-glasses-mode.html

I think it sees very little usage though.

Re:TmuxAI: AI-Powered, Non-Intrusive Terminal Assistant on Monday April 28, 2025 @12:21AM (#43817517)
If I've understood this interesting workflow correctly, there's two major components.

streamdown: a markdown renderer for the terminal, intended for consuming LLM output. It has affordances to make it easier to run the code snippets: no indentation, easy insertion in the clipboard, fzf access to previous items.

llmehelp: tools to slurp the current tmux text content (i.e. recent command output) as well as slurp the current zsh prompt (i.e. the command you're currently writing).

I think the idea is then you bounce between the LLM helping you and just having a normal shell/editor tmux session. The LLM has relevant context to your work without having to explicitly give it anything.

Re:Two Years of Rust on Monday April 21, 2025 @06:09PM (#43757049)
In `use foo::bar; use bar::foo;`, am I importing an external crate called foo that has a submodule bar::foo, or vice versa?

This bit me when trying to write a static analysis tool for Rust that finds missing imports: you essentially need to loop over imports repeatedly until you reach a fixpoint. Maybe it bites users rarely in practice.

Re:Two Years of Rust on Wednesday April 16, 2025 @01:19AM (#43701756)
> Rust's users find the module system even more difficult than the borrow checker. I've tried to figure out why, and figure out how to explain it better, for years now.

The module system in Rust is conceptually huge, and I feel it needs a 'Rust modules: the good parts' resource to guide people.

(1) There are five different ways to use `pub`. That's pretty overwhelming, and in practice I almost never see `pub(in foo)` used.

(2) It's possible to have nested modules in a single file, or across multiple files. I almost never see modules with braces, except `mod tests`.

(3) It's possible to have either foo.rs or foo/mod.rs. It's also possible to have both foo.rs and foo/bar.rs, which feels inconsistent.

(4) `use` order doesn't matter, which can make imports hard to reason about. Here's a silly example:

use foo::bar; use bar::foo;

(Huge fan of your writing, by the way!)

Re:Pijul: Version-Control Post-Git • Goto 2023 on Saturday August 12, 2023 @02:06PM (#37102694)
> How well do existing VCSs integrate with it?

Git supports external diffing tools really well with GIT_EXTERNAL_DIFF, which you can use with difftastic[1]. Other VCSs are less flexible. For example, I haven't found a nice way of getting a pager when using difftastic with mercurial.

> Did you feel restricted at any point by writing a diffing tool, instead of basing a new VCS around this concept?

Oh, that's an interesting question! Difftastic has been a really big project[2] despite its limited scope and I'm less interested in VCS implementation.

I think text works well as the backing store for a VCS. There are a few systems that have structured backends (e.g. monticello for smalltalk), but they're more constrained. You can only store structured content (e.g. monticello requires smalltalk code) and it must be well-formed (your VCS must understand any future syntax you use).

Unison[3] is a really interesting project in this space, it stores code by hash in a sqlite backend. This makes some code changes trivial, such as renames.

From the perspective of a text diff, an AST diff is lossy. If you add an extra blank line between two unchanged functions, difftastic ignores it. That's great for understanding changes, but not for storage.

[1]: https://difftastic.wilfred.me.uk/git.html

[2]: https://www.wilfred.me.uk/blog/2022/09/06/difftastic-the-fan...

[3] https://www.unison-lang.org/

Re:Pijul: Version-Control Post-Git • Goto 2023 on Saturday August 12, 2023 @12:56AM (#37097171)
Shameless plug: I've written difftastic[1], a tool that builds ASTs and then does a structural diff of them. You can use it with git too.

It's an incredibly hard problem though, both from a computational complexity point of view, and trying to build a comprehensible UI once you've done the structural AST diff.

[1]: https://github.com/wilfred/difftastic

Re:The Quest for a Simple Smartwatch on Thursday June 29, 2023 @01:31AM (#36516688)
Another enthusiastic Bangle.js user here: I had the original and used it, programmed it until the strap (integrated into the body) broke.

Apparently you can actually connect it to phone notifications using gadgetbridge[0] but I didn't have much success when I tried it. The BLE was a little flaky at the best of times (pairing to a PC for programming failed more often than I'd like).

[0] https://www.espruino.com/Gadgetbridge

Re:Difftastic, the fantastic diff on Thursday September 08, 2022 @12:36PM (#32768030)
tree-sitter has first class support for parsing errors as ERROR nodes in the output tree. I treat these as just another atom in the s-expression.

In practise I haven't noticed any issues yet. I suspect that difftastic doesn't see many syntax errors because users have fixed most of them by the time they run the diff. When you look at diffs of committed code you hopefully have no parse errors at all.

The tree-sitter parsers could still reject valid code I suppose. I worry slightly more about the parsers getting precedence/associativity wrong, but it would be hard to construct an example that produce identical parse trees due to incorrect precedence.

Re:Difftastic, the fantastic diff on Thursday September 08, 2022 @02:53AM (#32762117)
Thanks for the feedback. This is really hard to explain.

Autochrome has a brilliant worked example https://fazzone.github.io/autochrome.html and it still took me several readings before it clicked.

Every graph vertex represents a pair of pointers (or positions) to AST nodes. So in the example, the start program is `A` and the end program is `X A`. The positions point to AST nodes in these programs.

I try to use 'vertex' consistently for graph vertices, to avoid confusion with AST/s-expression nodes. If you have any suggestions for better terminology I'd be very interested too :)

Re:Difftastic, the fantastic diff on Thursday September 08, 2022 @02:46AM (#32762070)
I've looked at several tree diffing papers, including Chawathe et al, but it's not always easy to assess whether their approach would suit difftastic.

I know that sdiff by Arun Isaac is based on applying that paper to Scheme: https://archive.fosdem.org/2021/schedule/event/sexpressiondi... , although he also reports performance challenges.

Most tree diffing papers that I've seen focus on either (1) providing a minimal diff and accepting the performance cost or (2) providing a relatively minimal diff and focusing on the performance.

I've generally found that you need a minimal diff to get a good result, so papers in (2) are less applicable. I've also found several cases where there are several possible minimal diffs, but there's a clear 'correct' answer from the user's perspective.

Difftastic doesn't handle moves: the edit set is add, remove, or replace similar comment. If you reorder functions, it will take the largest unchanged subset. Moves are hard to model in a diffing algorithm, but they're also very hard to display coherently in the UI.

I know a few code forge websites (e.g. Phabricator) show moves in a fairly comprehensible way, although they're all based on line-based diffs.

Re:Difftastic, the fantastic diff on Wednesday September 07, 2022 @12:52PM (#32753082)
Side-by-side diff displays work really great in a browser. You usually have more screen real estate, and you can offer a responsive UI.
Re:Difftastic, the fantastic diff on Wednesday September 07, 2022 @12:50PM (#32753060)
Thanks for the feedback! I'll look to clarify the wording here. The failed example was a real output that difftastic gave in early versions.

I agree that the classic red/green colour scheme of diffs isn't great for colourblind users. I've asked a few colourblind developers and they were happy with terminal ANSI colours (which is what difftastic uses), because they can configure each colour individually.

Re:Difftastic, the fantastic diff on Wednesday September 07, 2022 @12:45PM (#32752976)
You can use difftastic as your default git diff tool, but you can also use it as an opt-in diffing tool. I recommend using it as an opt-in, but defining a git alias so you can do 'git difft'.

https://difftastic.wilfred.me.uk/git.html has docs.

Re:Difftastic, the fantastic diff on Wednesday September 07, 2022 @12:43PM (#32752951)
Yep, that's correct. Difftastic is only a syntactic analysis, although it often makes the semantic intent clearer.
Re:Difftastic: A diff that understands syntax on Wednesday March 30, 2022 @05:28PM (#30861010)
tree-sitter inserts error nodes and gives you an AST for all inputs. It seems to work well in practice.
Re:Difftastic: A diff that understands syntax on Wednesday March 30, 2022 @05:26PM (#30860984)
I imagine it's a misunderstanding with the rustc-hash dependency used in difftastic for faster hashing.
Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @04:15PM (#30847800)
I'd like to add it, but I haven't found any good tree-sitter parsers for Scheme.
Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @04:14PM (#30847794)
This looks like you're using a version of Rust older than the minimum required (1.56).
Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @04:12PM (#30847775)
https://github.com/andreyvit/json-diff works really well for JSON diffing in my experience.

It's more simplistic than difftastic though: it considers `1` and `[1]` to have nothing in common.

Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @04:09PM (#30847725)
It's really hard! :)

(1) Parsing an arbitrary language is hard. Without tree-sitter, difftastic would probably be a lisp-only tool. You also want a parser that preserves comments.

(2) Inputs may not be syntactically well formed.

(3) Efficiently comparing trees is extremely difficult (difftastic is O(N^2) in time and memory).

(4) Displaying tree diffs is equally difficult. Alignment is particularly challenging when your 'unchanged before' and 'unchanged after' are syntactically the same, but textually different.

Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @04:04PM (#30847672)
The underlying parser is just tree-sitter, which is a reusable (and excellent) parsing library.

Difftastic then converts the tree-sitter parse tree to a simpler s-expression style format (see https://difftastic.wilfred.me.uk/parsing.html#simplified-syn...), and computes differences on that.

I'm just trying to clarify that I'm not generating conventional 'unified diff' patches, so I can provide a nicer interface (e.g. line numbers).

Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @04:00PM (#30847617)
FWIW I've had reports of people using difftastic on Windows successfully.
Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @12:42PM (#30844954)
There are a few packages available, e.g. https://aur.archlinux.org/packages/difftastic and https://pkgsrc.se/wip/difftastic.

I've also had requests from Alpine Linux packagers to allow dynamic linking to parsers. This is something I want to support in future, once I'm happy with the basic diffing logic.

Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @12:38PM (#30844862)
FWIW VCS for Smalltalk basically does this.

The challenge for a tool like difftastic is that I can't guarantee that syntax is well-formed. You might be using new syntax that my parser doesn't support, you might have merge conflicts, or you might have a plain syntax error in your code.

Tree-sitter handles parse errors gracefully, so difftastic handles syntax errors pretty well in my experience.

Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @12:32PM (#30844774)
Difftastic has support for ~20 languages, and I'm happy to add more if there's a decent tree-sitter parser available :)
Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @12:31PM (#30844747)
JSON and CSS are supported today, and I'm interested in adding more structured text formats.

If a format has a tree-sitter parser, it can be added to difftastic. The TOML tree-sitter parser looks good, but there isn't a mature markdown parser for tree-sitter. There are other markdown parsers available, so in principle difftastic could support markdown that way.

The display logic might need a little tuning for prose-heavy formats like markdown though. I'm not happy with how difftastic handles block comments yet either.

I'm not sure about formats that contain more prose, such as markdown or HTML.

Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @12:21PM (#30844604)
Difftastic is only ignoring whitespace that isn't significant. If you remove `if (true)`, it will get highlighted.

With a textual diff today, your only choices are 'highlight all whitespace changes' (e.g the git default) or 'ignore all whitespace' (e.g. diff --word-diff).

If difftastic says there are no changes, then both files have the same parse tree and the same comments.

Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @12:17PM (#30844531)
Yep! It does a conventional textual diff: run Myers' diff algorithm on lines, then word highlighting on changed lines.
Re:Difftastic: A diff that understands syntax on Tuesday March 29, 2022 @12:16PM (#30844523)
There's a basic single-column 'inline' display available if you do `INLINE=y`, but it's not as mature as the side-by-side display yet.

Older »