HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
alefore
edge
C++2020–2025
alefore / edge

edge

Edge - a text editor

3Distinct people
19Mentions
0Explicit recommenders
88GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Edge - a text editor

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

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 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 year19 dated mentions

Observed mentions: 2020-03-24 18:12:12 UTC to 2025-10-18 16:40:55 UTC.

02468102020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 10 mentions; 1 submissions, 9 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20222023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2024-01-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 2026-01-01 00:00:00 UTC (exclusive): 3 mentions; 2 submissions, 1 comments2025

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
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC1019
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC505
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC321

What Hacker News says

19 sources
afc·Jul 20, 2025Submission

Show HN: Duende: Web UX for guiding Gemini as it improves your source code

I wrote a simple web UX in Python/JavaScript that spawns a conversation with Google Gemini with MCP commands that let it work on a specific coding task that you specify: http://github.com/alefore/duende The UX lets you observe the conversation and provide guidance (e.g. "don't implement Foo through Bar, that's suboptimal; instead …"). It supports a `--review` mode, where once the main conversation says "I'm done with the task", various "evaluation" conversations are spawned, each focusing on reviewing the change from a very specific angle (e.g. "does it introduce useless comments?"). In the future, I'm considering adding other workflows. I've used it mostly to develop itself (I started with a super rudimentary manual implementation and then mostly used Duende to extend its own implementation) as well as (with moderate success) to add a fe
Read the rest
w new features to [my C++ text editor](http://github.com/alefore/edge). It's been a lot of fun. I'm still developing my intuitions for what works and what doesn't, but I've already had plenty of experiences where I've been WOW'ed by what LLMs can already accomplish (as well as, to be honest, plenty of very disappointing cases where it struggles significantly on tasks that I expected would have been trivial). It's a learning experience, seeing things like how to avoid hallucinations; developing an intuition for how much to break down large tasks into smaller ones; or knowing when to abort a conversation and restart it with an improved prompt (vs continue to steer it in the right direction). I think investing up-front in setting up a good context (e.g., good validation logic, useful constant contexts, a good set of "review evaluators" that can push-back against sloppy code) can go a long way to increase the odds of success. It has changed my perception on the applicability of AI for developing software. While I've reviewed all the outputs (and often rewrite parts of them manually), I'm already incorporating it into (some parts) of my development life-cycle. I have many ideas for improvements, but figured I'd share this early and ask for feedback. Hopefully others find it interesting; would love to hear your thoughts.
8 points · Open discussion
In my text editor (https://github.com/alefore/edge) I use a balanced binary tree containing small chunks (std::vector) of contiguous lines. That works well enough for me: https://asciinema.org/a/314752 This requires loading the entire file into memory, but computers are so fast today that optimizing that away is pointless IMO (as the video shows, a 12MB file with 400k lines can be loaded/edited/saved reasonably). The tree structure is implemented as a generic container here: https://github.com/alefore/edge/blob/master/src/language/con.... The tree is actually deeply immutable; each modification operation returns a new tree (where most contents are shared with the original tree). The leafs contain std::vectors that hold between 128 and 256 lines (save for a few cases). The actual specialization that holds a sequence of lines is LineSequenc
Read the rest
In Text Editor: Data Structures
> Something I have wanted to create for a long time (definitely more than 5 years) is a new modal editor. I don't want yet another vi clone: I want something that is defined from the ground up by user configuration. This is more or less the philosophy of the editor I've been working on (and using ~exclusively) since 2014: https://github.com/alefore/edge/tree/master Some parts of the UI are still defined in the compiled language (so don't fully fit your philosophy yet), but a big part of the UI comes from the configuration loaded at runtime: every time the editor starts, it interpretes and runs this configuration defining the UI: https://github.com/alefore/edge/blob/master/rc/hooks/start.c... (This file is not compiled into the editor, but loaded and executed directly at runtime; the format of that file is my editor's extension language/c
Read the rest
onfiguration (the equivalent to emacs lisp or vimscript), which just happens to be a garbage collected C-like language.)
In Text Editor Data Structures: Rethinking Undo
In my text editor (https://github.com/alefore/edge) I keep the undo/redo history always linear, which I find works pretty well. So suppose the user does the following operations: • Insert "Hello" • Insert " world!" • Undo once. • Insert ", Cameron!" At this point, undo operations would gradually transform the buffer thus: "Hello, Cameron!" => "Hello" => "Hello world!" => "Hello" => "". Obviously, one can redo at any point. The undo/redo days structure don't preserve the state, just the transformations (which are reversible). The gist of it is that when you apply a modification to the buffer and the redo stack isn't empty, the redo stack gets flipped and inserted into the undo stack. If you undo a long list of transformations and then make a change, that long list is duplicated, but this hasn't been a problem in practice. In case someone f
Read the rest
inds this interesting, this is mostly implemented here: https://github.com/alefore/edge/blob/28c031230a8babe888ffe1a...
In Text Editor Data Structures: Rethinking Undo
How about many readers and zero writers? :) For my text editor, I went with an immutable balanced tree. I was surprised by how easily I was about to implement all operations I needed with reasonable runtime complexity (log N mostly, operations like "give me a copy with element at position i removed"): https://github.com/alefore/edge/blob/master/src/language/con... I use this throughout my editor. For example, I load a file into a sequence of lines represented here: https://github.com/alefore/edge/blob/8fdf7f76ffa167497a7e9e9... I found that the good performance, relatively straightforward implementation and very strong thread safety (making the data immutable means a whole class of problems just disappears) works very well.
In Why does unsafe multithreaded std:unordered_map crash more than std:map?
I also use this pattern: https://github.com/alefore/edge/blob/master/src/concurrent/p... I added an optional template Validator parameter that can be used to double-check invariants on the protected fields. I also declared a Protected with condition subclass. Here is one example of how I use it to implement a "barrier" of sorts (the operation instance blocks in the destructor until execution of all callables passed to "Add" has completed): https://github.com/alefore/edge/blob/master/src/concurrent/o... I found it slightly preferable over Abseil annotations; I think it's slightly more robust (i.e., make errors, like forgetting an annotation, less likely) and I like making this explicit in the type system.
In MutexProtected: A C++ Pattern for Easier Concurrency
Well said. This feels terrible: just silently ignore logical errors (where some code expects but doesn't receive a fully constructed object) and ... keep going. I'd rather take a crash (that way I'll know soon that I have a bug and it'll be easy to fix) or, even better, a compiler/type error ("code is expecting a fully constructed object but doesn't always receive one"). In C++ I recently started using a NonNull<> templated type (with specializations for std::unique_ptr<> and std::shared_ptr<>): https://github.com/alefore/edge/blob/af1192a70646f662539bfe6... It's slightly verbose, but has allowed me to delete a ton of CHECK(x != nullptr) statements (since the type will already carry the information that x can't be null) and this use of types has helped me detect a few mismatches (where e.g. the consumer had unnecessary complexity to deal
Read the rest
with null but the caller always emitted fully constructed types, or the, much worse, symmetric case).
In The Brilliance of “nil” in Objective-C
Interesting read. I'm not sure I agree with the conclusion: I find using futures with very carefully controlled threading a preferable paradigm (for how I structure my programs in C++, at least for my text editor: https://github.com/alefore/edge). In my experience, using sync code looks more readable on the surface but just kicks the can down the road: you'll still need to deal with the complexity of threading, and, in my experience, it's going to be waaay uglier. What you gain with your "superficial" simplicity, you pay a hundred times over with the algorithmic complexity of having to use threads with shared state. Every time you're troubleshooting some weird race condition that you can't easily reproduce you'll be wishing you had just used futures. What I do is that the bulk of my processing runs in the main thread and I occasionally di
Read the rest
spatch work to other threads, making sure that no mutable state is shared. When the "async" work is finished, I just have the background threads communicate the results to the main thread by setting a future (i.e., scheduling in the main thread the execution of the future's consumer on the results). Async IO operations are modeled just the same. In the beginning I had used callbacks spaghetti (mostly writing things in continuation passing style), but I started trying futures and found them much nicer. I'll admit that on the surface this makes my code look slightly uglier than if it was directly sync code; however, it allows me to very safely use multiple threads. I think not having to make my classes thread safe (I typically stop at making them thread-compatible) and not having to troubleshoot difficult race conditions (and not having to block on IO or being able to easily run background operations) has been a huge win. If I had to rewrite this from scratch, I'd likely choose this model again. My editor only needs to use mutexes and such in very very few places; it suffices to make my classes thread-compatible and to ensure that all work in threads other than the main thread happens on const objects (and that such objects don't get deallocated before the background threads are done using them). I rolled out my own implementation of futures here: https://github.com/alefore/edge/blob/master/src/futures/futu... (One notable characteristic is that it only allows a single listener, which I found worked well with "move" semantics for supporting non-copyable types that the listener gets ownership of.) Here is one example of where it is used: https://github.com/alefore/edge/blob/5cb6f67e1e0726f8fbe12db... In this example, it implements the operation of reloading a buffer, which is somewhat complex in that it requires several potentially long running or async operations (such as the evaluation of several "buffer-reload.cc" programs, opening the file, opening a log for the file, notifying listeners for reload operations...). It may seem uglier than if it was all in sync code, but then I would have to either block the main thread (unacceptable in this context) or make all my classes thread safe (which I think would be significantly more complexity). I think this is cleaner than callbacks spaghetti because the code still reflects somewhat closely its logical structure. For loops I do have to use futures::ForEach functions, as the example shows, which is unfortunate but acceptable. In my experience, with callbacks spaghetti, it is very difficult to make code reflect its logical structure.
In What Color Is Your Function? (2015)
I've been writing a lot on my Zettelkasten. I've been very productive! I published an article about Zettelkästen: https://github.com/alefore/weblog/blob/master/zettelkasten.m... I'm also working on an article about software correctness, summarizing my experience working on infrastructure software at Google for about 13 years. It's very incomplete and I'll probably end up restructuring it significantly (not very happy with the current logical structure). I only started working on this two or three weeks ago (as a side project), so I'm satisfied with the progress I've been able to make: https://github.com/alefore/weblog/blob/master/software-corre... I'm also working on other similar articles on other topics (Bitcoin, Stoicism, Bauhaus), but those are even less complete. Lastly, I've continued to make significant improvements to my text edit
Read the rest
or (https://github.com/alefore/edge). I think it's interesting that I'm finding it hard to focus on some topics, but I'm currently very productive in others.
In Ask HN: What's your quarantine side project?
Aww, thank you for your reply, I'm very flattered. I usually get very skeptical/cynical comments when I mention to my coworkers and friends that I use my own text editor, so receiving comments like yours is very encouraging. Yeah, what you see there corresponds to the syntax tree of the file being edited. You can see it fairly clearly in this screenshot (which has the advantage of showing how this really looks in an actual terminal, without some noise from asciinema): https://raw.githubusercontent.com/alefore/edge/master/screen... In this screenshot, the very last column is just a scrollbar. Right next to it you see a representation of a subset of the syntax tree. It is a subset because I deliberately drop from it any subtrees that don't span more than a single line. In the recording you also see something on the right of the scrollbar. T
Read the rest
he things shown on the left of the scrollbar correspond to the lines currently shown on the screen; the parts on the right are a representation of the tree for the entire file. The syntax parsing is a bit dumb: just just based on things like parenthesis, comments, quotes, and brackets and such, not really aware of high semantic concepts (like classes or methods). For C++ (and other C like languages such as Java) this is implemented here: https://github.com/alefore/edge/blob/master/src/cpp_parse_tr... (if it seems too complex, part of it is because I cache previous states, as an optimization, since this runs every time you type a character into the file, refreshing the tree; I want this to work with very large source files, where most of the time you type a character the vast majority of the previous outputs can be reused). I have two other parsers, for Markdown and diff (patches). It should be easy to add more parsers, but I want to clean up the API used by them. Anyhow, you just have to generate a representation of the syntax tree (in this structure https://github.com/alefore/edge/blob/master/src/parse_tree.h). I've been considering integrating this with clang or vscode but haven't gotten around to it. Once you have the ParseTree, the editor will display this information about the scopes (the logic that does that is a bit complex but lives here: https://github.com/alefore/edge/blob/master/src/buffer_metad..., function DrawTree, which returns a string with the characters for a given line). I probably gave you more information than you wanted. :-P Thanks again for your comment.
In Ask HN: What are your favorite developer-efficiency tips?
Aww, thank you! Yeah, that entire article is generated from the set of notes. There's one note for each subsection (down to the finest level of granularity) and it just extracts the article directly based on the links. I described this in a set of notes that end up here: https://github.com/alefore/weblog/blob/master/zettelkasten.m... The images (e.g., distribution of back links per file, semilattice view, etc.) are also just generated programmatically from the repository of notes. The code that extract it is here: https://github.com/alefore/edge/blob/master/rc/editor_comman... (function zke, which receives the output path, the path to the initial note, and a string listing space separated paths of notes to ignore). Here's another example of an article generated from my notes (this is way longer and is very incomplete, and probably contain
Read the rest
s a bunch of mistakes, but you may find it interesting as an example): https://github.com/alefore/weblog/blob/master/software-corre...
In Ask HN: What are your favorite developer-efficiency tips?
Probably an unpopular opinion but... Write your own text editor. I've been working on my own (https://github.com/alefore/edge) as a side project and using it exclusively for about six years. I don't expect it to be very usable by other people (it's very customized for my workflows, I suppose; e.g., it's mostly useful for writing C++ and Markdown files) but, because I know it inside out (and I've invested in making it easy to customize through its extension language), it's very easy for me to adjust it to behave exactly the way I want it, which allows me to lower the friction for any operations I care about (and it abides very exactly to my principles/expectations for how an editor should behave; e.g. never block the main thread/UI while executing some operation such as opening a file). Because I don't have to use but a small set of comput
Read the rest
ers directly (mostly my laptop and my workstation), this works well enough. I don't know if overall it'll save me more time than it has taken me to implement it, but I do believe it allows me to move significantly faster than if I still used Vim or Emacs (or than most of my team mates), especially because it allows me to operate at a higher semantic level than otherwise, eliminating distractions from lower level details. ... and, I guess, it has been a lot of fun to implement it (and I've probably learned a bunch). I think it has played a role for me similar to that videogames have played for some of my friends (e.g., this weekend's challenge may be to generate visualizations for the logs I keep for every interaction I have with each file I've edited; implementing stuff like that feels similar to how in the past I felt about making progress in some videogames).
In Ask HN: What are your favorite developer-efficiency tips?

Showing the 15 most recent of 19 sources. Enable JavaScript to search and browse every indexed mention.

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.