HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
alexpovel
srgn
Rust2023–2026
alexpovel / srgn

srgn

A grep-like tool which understands source code syntax and allows for manipulation in addition to search

2Distinct people
8Mentions
0Explicit recommenders
915GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A grep-like tool which understands source code syntax and allows for manipulation in addition to search

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 5:04:57 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by month8 dated mentions

Observed mentions: 2023-12-10 13:36:47 UTC to 2026-02-12 19:14:53 UTC.

01232023-12-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 commentsDec 20232024-01-01 00:00:00 UTC to 2024-02-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2024-02-01 00:00:00 UTC to 2024-03-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-03-01 00:00:00 UTC to 2024-04-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-04-01 00:00:00 UTC to 2024-05-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-05-01 00:00:00 UTC to 2024-06-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-06-01 00:00:00 UTC to 2024-07-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-07-01 00:00:00 UTC to 2024-08-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-08-01 00:00:00 UTC to 2024-09-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-09-01 00:00:00 UTC to 2024-10-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2024-10-01 00:00:00 UTC to 2024-11-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-11-01 00:00:00 UTC to 2024-12-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-12-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2025-02-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 commentsJan 20252025-02-01 00:00:00 UTC to 2025-03-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-03-01 00:00:00 UTC to 2025-04-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-04-01 00:00:00 UTC to 2025-05-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-05-01 00:00:00 UTC to 2025-06-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-06-01 00:00:00 UTC to 2025-07-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-07-01 00:00:00 UTC to 2025-08-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-08-01 00:00:00 UTC to 2025-09-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-09-01 00:00:00 UTC to 2025-10-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-10-01 00:00:00 UTC to 2025-11-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-11-01 00:00:00 UTC to 2025-12-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-12-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-01-01 00:00:00 UTC to 2026-02-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-02-01 00:00:00 UTC to 2026-03-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 commentsFeb 2026

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
Dec 20232023-12-01 00:00:00 UTC2024-01-01 00:00:00 UTC303
Jan 20242024-01-01 00:00:00 UTC2024-02-01 00:00:00 UTC110
Feb 20242024-02-01 00:00:00 UTC2024-03-01 00:00:00 UTC000
Mar 20242024-03-01 00:00:00 UTC2024-04-01 00:00:00 UTC000
Apr 20242024-04-01 00:00:00 UTC2024-05-01 00:00:00 UTC000
May 20242024-05-01 00:00:00 UTC2024-06-01 00:00:00 UTC101
Jun 20242024-06-01 00:00:00 UTC2024-07-01 00:00:00 UTC000
Jul 20242024-07-01 00:00:00 UTC2024-08-01 00:00:00 UTC000
Aug 20242024-08-01 00:00:00 UTC2024-09-01 00:00:00 UTC000
Sep 20242024-09-01 00:00:00 UTC2024-10-01 00:00:00 UTC202
Oct 20242024-10-01 00:00:00 UTC2024-11-01 00:00:00 UTC000
Nov 20242024-11-01 00:00:00 UTC2024-12-01 00:00:00 UTC000
Dec 20242024-12-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
Jan 20252025-01-01 00:00:00 UTC2025-02-01 00:00:00 UTC000
Feb 20252025-02-01 00:00:00 UTC2025-03-01 00:00:00 UTC000
Mar 20252025-03-01 00:00:00 UTC2025-04-01 00:00:00 UTC000
Apr 20252025-04-01 00:00:00 UTC2025-05-01 00:00:00 UTC000
May 20252025-05-01 00:00:00 UTC2025-06-01 00:00:00 UTC000
Jun 20252025-06-01 00:00:00 UTC2025-07-01 00:00:00 UTC000
Jul 20252025-07-01 00:00:00 UTC2025-08-01 00:00:00 UTC000
Aug 20252025-08-01 00:00:00 UTC2025-09-01 00:00:00 UTC000
Sep 20252025-09-01 00:00:00 UTC2025-10-01 00:00:00 UTC000
Oct 20252025-10-01 00:00:00 UTC2025-11-01 00:00:00 UTC000
Nov 20252025-11-01 00:00:00 UTC2025-12-01 00:00:00 UTC000
Dec 20252025-12-01 00:00:00 UTC2026-01-01 00:00:00 UTC000
Jan 20262026-01-01 00:00:00 UTC2026-02-01 00:00:00 UTC000
Feb 20262026-02-01 00:00:00 UTC2026-03-01 00:00:00 UTC110

What Hacker News says

8 sources
These sorts of cases are why I wrote srgn [0]. It's based on tree-sitter too. Calling it as cat file.py | srgn --py def --py identifiers 'database' 'db' will replace all mentions of `database` inside identifiers inside (only!) function definitions (`def`) with `db`. An input like import database import pytest @pytest.fixture() def test_a(database): return database def test_b(database): return database database = "database" class database: pass is turned into import database import pytest @pytest.fixture() def test_a(db): return db def test_b(db): return db database = "database" class database: pass which seems roughly like what the author is after. Mentions of "database" outside function definitions are not mod
Read the rest
ified. That sort of logic I always found hard to replicate in basic GNU-like tools. If run without stdin, the above command runs recursively, in-place (careful with that one!). Note: I just wrote this, and version 0.13.2 is required for the above to work. [0]: https://github.com/alexpovel/srgn
In Refactoring Python with Tree-sitter and Jedi
alexpovel·Jan 27, 2024Submission

Show HN: Srgn, AST-aware text manipulation

srgn is a niche source code (or just text) manipulation tool. It's written in Rust, with performance in mind. I used it to learn the language a while back, in order to work towards something resembling "useful in the real world". Think of srgn as a blend of rip-grep, tree-sitter and GNU `tr`/`sed`. At its core, it most closely resembles `tr`, but expands on it in two important ways. First, srgn provides scoping, used to specify what part of an input to work on. This can be literal text, regular expressions, or tree-sitter queries. The latter is the most interesting one. As tree-sitter queries can be tough to construct (although the tool is excellent, with an online playground for testing and more), srgn has pre-defined queries and makes an effort to unify these across languages. For example, across TypeScript, C#, Go, Rust and Python, you
Read the rest
can specify to scope all "comments", and it (hopefully) just works as expected, despite these languages having different ideas of how comments work and look like (C# has multi-line and inline, for example, while Python only has a single type, all of which is also reflected in what tree-sitter calls those corresponding nodes). Secondly, there's actions, which simply perform text manipulation on whatever is in scope from the previous step. One could delete certain parts of all comments, for example, or rewrite all import statements across an entire code base (https://github.com/alexpovel/srgn#mass-import-module-renamin...). I had looked around a bunch for similar tools (https://github.com/alexpovel/srgn#similar-tools), but couldn't find any that quite did what srgn does. The CLI is a rather thin wrapper around the Rust library, which is usable in the usual way. By the way, the name srgn stands for surgeon, in the sense of a code surgeon: precise manipulation of text. Regular expressions and tree-sitter queries can be combined, which turns out to be much more powerful than either of these by itself, and also fills a different niche than LSP-powered Rename all-like features. It can also be used in CI, as a simple custom linter ("fail if you find any 'TODO' strings in comments"). A lot of the use cases can be covered by just regex, and then fixing mistakes manually; srgn mainly inches the precision of these operations closer to 100%, for when it's needed (like large refactors, where srgn offers full parallelization as well).
2 points · Open discussion
https://github.com/alexpovel/srgn It grew out of a niche, almost historical need: using a QWERTY keyboard, but needing access to German Umlauts (ä, ö, ü, as well as ß). Switching keyboard layouts is possible but exhausting (it's much more pleasant sticking to one); using modifier keys is similarly tedious, and custom setups break and aren't portable. So this tool can do: $ echo 'Gruess Gott, Poeten und Abenteuergruetze!' | srgn --german Grüß Gott, Poeten und Abenteuergrütze! meaning it not only replaces Umlauts and Eszett, it also knows when not to (Poeten), and handles arbitrary compound words. Write your text, slap it all into the tool, it spits out results instantly. The original text can use alternative spellings (ou, ae, ue, ss), which is ergonomic. Combined with tools like AutohotKey, GUI integration through a single keyboa
Read the rest
rd shortcut is possible. See [0] for a similar example. A niche need I haven't yet come across someone else having as well! (just the amount of text explaining what it's all about is saying a lot in terms of specificity...) The tool now grew into a tree-sitter based (== language grammar-aware) text manipulation thing, mostly for fun. The bizarre German core is still there however. [0]: https://github.com/alexpovel/betterletter/blob/c19245bf90589...
In Ask HN: What apps have you created for your own use?
Wow! What a coincidence. Just the other day I finished "v1" of a similar tool: https://github.com/alexpovel/srgn , calling it a combination of tr/sed, ripgrep and tree-sitter. It's more about editing code in-place, not finding matches. I've spent a lot of time trying to find similar tools, and even list them in the README, but `AST-grep` did not come up! I was a bit confused, as I was sure such a thing must exist already. AST-grep looks much more capable and dynamic, great work, especially around the variable syntax.
In AST-grep(sg) is a CLI tool for code structural search, lint, and rewriting

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.