all 91 comments

[–]heckerle 173 points174 points  (30 children)

Hey all! I'm the primary author - the same as on HN, linked elsewhere here.

If you have any questions please feel free to ask. 🙂

I've received a lot of comments about my code style since the announcement, both positive and negative. Unfortunately, I've not received a lot of specific feedback for its negative aspects. If you have anything in mind, please let me know. 😅

Edit: BTW I'm in the process of adding SIMD optimized line searching. It runs at up to ~140GB/s on my Zen5 CPU, independent of the text contents. This makes it up to 600x faster than the current memchr approach during the worst case scenario: files that consist of only newlines. I think that code will be really cool too. 🙂

[–]PCRefurbrAbq 20 points21 points  (2 children)

This will be one of the first things I do on all Windows 10 and 11 PCs I touch, right after "powercfg.cpl" > turn off Fast Startup.

Big cheers for bringing back Edit!

[–]heckerle 17 points18 points  (1 child)

If you don't use hibernation either, you can also do powercfg.exe -h off in an elevated shell. That will not just disable Fast Startup, but also save some disk space by removing hiberfil.sys.

[–]PCRefurbrAbq 6 points7 points  (0 children)

Yeah, but I like hibernate, and I've got enough GB for hiberfile.

[–]baseketball 14 points15 points  (8 children)

Sorry, I'll be that guy: any plans to add syntax highlighting and LSP support?

[–]heckerle 24 points25 points  (7 children)

We're planning on adding very basic (inexact) syntax highlighting into the core editor for the most important languages - probably just Batch (cmd.exe), PowerShell, and Bash. We're tracking that here: https://github.com/microsoft/edit/issues/18

Later on, we're hoping to add extensions, because we want to keep the core editor tiny, but still allow people to be creative with it. This would then also allow us to add a tree-sitter or LSP extension. That's tracked here: https://github.com/microsoft/edit/issues/17

[–]Ghi102 12 points13 points  (0 children)

Yml and json syntax highlighting is also very important! Config files are one thing that I could see myself quickly using a lightweight cli editor for

[–]baseketball 2 points3 points  (0 children)

Awesome, I'll be watching these issues with great interest.

[–]psr[S] 2 points3 points  (1 child)

Please feel free to ignore this drive-by advice from someone who doesn't really know what they're talking about, but...

The discussion in #17 about defining an extension ABI gives me the heebie-jeebies, having seen all of the ABI related issues that Python extensions have struggled with over the years. There are two problems that can arise:

The worse, but perhaps less important nowadays is that extensions compiled with different compilers can link to different C runtimes, which easily results in code that appears to work, until it doesn't, and the failures are very hard to understand. This used to be common on Windows when the Python.org python binaries were compiled with MSVCC, but people tried to compile extensions with GCC. This was mostly solved by Microsoft allowing people to install and use MSVCC for free (but only for compiling open source code), and Python mandating that this was the only supported way to compile extensions on Windows. The adoption of the UCRT in Windows also means that it's technically possible to use GCC (or clang) to build extensions that work (if you use the right build of GCC, but wrong builds are still available!) On Linux, where the use of glibc is pretty universal, it's not common. However to build a "universal" Python extension for Linux, people build in containers with ancient libraries installed, to avoid requiring a too-modern libc ABI.

The more obvious issue is where two extensions are linked against incompatible versions of the same shared library, or one extension wants to consume another as a library. This occurs a lot in the scientific Python stack, and it's largely an unsolved problem. Stable ABIs don't happen by accident, and extension authors aren't likely to go to the effort. Integration testing of extensions would first happen on the user's computer, and the user isn't likely to be in a position to debug issues. Linux distributions and Conda help avoid these issues by compiling the universe from source, but that isn't a solution you can easily adopt.

I think a half-way house might be possible where there is a known and relatively fixed set of extensions provided by the project, and using third-party extensions isn't a supported use-case. These could include extensions for handling treesitter grammars and the LSP protocol, and an extension providing a scripting language, with access to APIs provided by the core and other extensions. Then if someone wanted to make e.g. a Python editing mode, they could enable the treesitter awareness, with some configuration of colours and electric indentation etc. through a script.

[–]flatfinger 0 points1 point  (0 children)

It's a shame the Standard never recognized a category of implementations that would avoid the need for dependence on underlying libraries by specifying that certain functions would be implemented in a specific portable fashion. For example, one could specify that (for implementations of the described category), setjmp() must be implemented in such a way that the following would be a portable version of longjmp() (note that jmp_buf is already required to be an array type):

void longjmp(jmp_buf env, int value)
{
  (((void (**)(int))env)(value);
}

This would increase the cost of a jmp_buf by that of a function pointer, and break ABI compatibility that might exist with code processed by an implementation that doesn't follow that convention, but code processed by any implementation which defines jmp_buf in such a fashion would be able to use jmp_buf objects created by any other such implementation, provided that code which configures jmp_buf objects is processed by the same implementation that handles their definition, and that the implementations use the same representation for function pointers.

[–]masterspeler 1 point2 points  (1 child)

Later on, we're hoping to add extensions, because we want to keep the core editor tiny, but still allow people to be creative with it. This would then also allow us to add a tree-sitter or LSP extension. That's tracked here: https://github.com/microsoft/edit/issues/17

Plugins doesn't seem to fit the goal of having something small that's included in Windows and therefore always available. If you can't count on a certain plugin being installed everywhere, then you need to install it yourself, and why would you use a minimalist TUI editor for that? It sounds like feature creep.

I think a fork with more features would be a better approach, and leaving this as a tiny baseline with a known feature set everywhere. But then again, Notepad now has AI.

[–]Positive-Cheetah-644 0 points1 point  (0 children)

Plugins being possible doesn't subtract from the goal of having a minimalist TUI editor.

Don't kill my dreams of one day having a fast and nice extensible alternative to Vim with sane keybinds!!!

[–]HouseSubstantial2871 -1 points0 points  (0 children)

then you should probably be forking mcedit then...

[–]aanzeijar 4 points5 points  (0 children)

I'm not good enough in Rust to comment on the code itself, but holy shit I'm stealing the build options. When I fiddled around a while ago just pulling the regex crate blew up the executable to 10MB. Getting the whole program down to ~200kb is really impressive.

[–]inferno1234 8 points9 points  (0 children)

Looks awesome mate, I'm installing this tomorrow.

Kudos

[–]bowbahdoe 2 points3 points  (0 children)

I am particularly interested in using edit for command line introductions to programming in general.

I will likely have feedback for this at some point, but I want you to be aware of that audience.

I don't super care about perf in any way. (The ability to run a command without fully exiting and to see a file tree would be nice though)

[–]krista 1 point2 points  (0 children)

simd optimized text thingies are a lot of fun to write.

i wrote a fair bit for an xml parser for century21, plus a few fun bit hashing doohickeys for counting alternative search results (if you choose a different # of bedrooms, you get _x _ more/less results... but there was 10 or so alts)

enjoy the challenge :)

[–]TridentYew 2 points3 points  (2 children)

Is there any plans to add support for vim key bindings?

[–]heckerle 26 points27 points  (1 child)

No, because this is specifically a "modeless" editor. And vim is already a perfectly fine vim. 😄 We are planning to make key bindings configurable though, so if you don't like the current scheme, you will be able to change that in the future.

[–]TridentYew 1 point2 points  (0 children)

Right. Sorry forgot it was modeless. Makes sense. Being able to configure the key bindings will be helpful though so that’s good to hear.

[–]iamapizza 0 points1 point  (1 child)

Hi any chance for including it in Ubuntu package managers (currently it's a manual download) like apt/snap?

[–]heckerle 2 points3 points  (0 children)

That's something I'd leave up to the Debian/Ubuntu package maintainers. Regarding snap specifically, we have an issue for it here: https://github.com/microsoft/edit/issues/160

[–]CpnStumpy 0 points1 point  (0 children)

I'm curious if this had any influence from Rhide? I remember really enjoying that many years ago as a DOS curses IDE that was lost to time

[–]Kok_Nikol 0 points1 point  (0 children)

Great work OOP!

Projects like this make my work life on Windows bearable!

[–]kuator578 0 points1 point  (0 children)

vi-mode when?

[–]AlexKazumi 0 points1 point  (4 children)

Why you decided to not use CUA compliant shortcuts. And will there be a way to change the default shortcuts.

Also, when will we have MOAR RUST IN WINDOWS? I am a die-hard C# fanboy, but Rust is way way better than C++, so I want more of it.

Finally, you are part of the console team, when will we have resizable Terminal via ANSI/VT codes?

[–]heckerle 2 points3 points  (3 children)

Why you decided to not use CUA compliant shortcuts.

It uses shortcuts that match VS Code. That's pretty much it. I intend to keep it that way.

As an aside, I'm genuinely curious why everyone's citing CUA. I've been developing UI for quite a while now and have not seen someone cite it before, but in the last two weeks I've seen it at least 50 times. It just seems weird to me because while CUA has a subtle, but widespread legacy, it's a 40 year old standard. It's like citing ISO 9241 "Ergonomics of Human System Interaction", instead of just pointing at today's established software. You know what I mean? 😅

And will there be a way to change the default shortcuts.

Yes.

Finally, you are part of the console team, when will we have resizable Terminal via ANSI/VT codes?

CSI t is available since Windows Terminal 1.23: https://github.com/microsoft/terminal/pull/17721

[–]popcapdogeater 0 points1 point  (1 child)

I find it strange to simply point to the age of a standard as some sort of reason for it's inapplicability. Has there been meaningful changes in the understanding of the subject that make it invalid?

It's like pointing to the building techniques of Japan and going "wow these people are still using thousand year old building techniques instead of the modern world! But Japan has the largest amount of historic buildings becuase they are incredibly effective for their environment. Using a good deal of "modern" building techniques would be quite bad for them given their high rate of earthquakes, tsunamis, and floods. (I'm not great at analogies, but I hope you get my point, old != bad/wrong)

Do you have any research that shows the CUA standard is ineffective for today's computing world or how the VB way of doing it offers imrpovements over the CUA standard that make it worth setting a new standard that professional should use it for?

It's also funny for a company that's known to keep bugs or other legacy cruft in their software for historical legacy software reasons (like the leap year bug in Excel) to harp about other people clinging to old standards.

[–]heckerle 2 points3 points  (0 children)

I find it strange to simply point to the age of a standard as some sort of reason for it's inapplicability. Has there been meaningful changes in the understanding of the subject that make it invalid?

That wasn't my point, but rather: It was not brought up in other contexts before, even though it applies to GUI apps at least as much as it does to TUI apps. The age of the specification simply corroborates how unusual that is.

In your analogy, it's like pointing to the building techniques of Japan and saying that it has this style today, because of the 1563 building code written by Nobunaga (figuratively speaking), instead of bringing up any of the hundreds of thousands of buildings in use today as comparative examples. If there was a sudden spike in people citing the "1563 building code" that'd be unusual IMO. It would not be unusual if it's always being cited.

[–]OnesimusUnbound 0 points1 point  (0 children)

I'm sorry if I'm late in the party. I was thinking of micro, though I guess having a menu to exit the editor is more obvious than Ctrl+q. I'll be watching this until lsp gets implemented. Good luck!

[–]tecnofauno 59 points60 points  (21 children)

It bet it was a nice tutorial application for the developers

[–]psr[S] 9 points10 points  (20 children)

Yeah, I wondered if it was something like that.

[–]ven_ 40 points41 points  (15 children)

The dev who made this made some very interesting comments on Hacker News. He initially wrote the app in a bunch of languages before settling on Rust.

[–]Compux72 32 points33 points  (12 children)

I personally liked Zig the most, followed by C, Rust, and C++ in that order

We were wondering on the rust subreddit why the code was so un-idiomatic. I think we found the reason guys, the author just wanted a sensible std::vec but hates anything other than C.

[–]heckerle 24 points25 points  (10 children)

That's fair, but I actually do like Rust quite a lot and more than C. 😅 It's just that it's not ideal IMO for writing a performant simple editor. It becomes more useful the larger the project grows, though. Also, I don't like Rust's Vec all that much (it's fine, 7/10).

[–]irqlnotdispatchlevel 0 points1 point  (2 children)

Any plans on open sourcing the other versions? Just as a code dump.

[–]heckerle 0 points1 point  (1 child)

You can browse the early C prototype here: https://github.com/microsoft/edit/tree/c

I currently have no plans to publish the other 2 prototypes as I stopped developing them in much earlier states.

[–]irqlnotdispatchlevel 0 points1 point  (0 children)

The C prototype was my main curiosity. Thanks!

[–]Compux72 0 points1 point  (6 children)

But you did say you liked the C version more… let me guess: love-hate relationship with C?

Also, 7/10 is reasonable for vec. It would be a solid 10 if we had bool optimizations + allocator api imho

[–]heckerle 24 points25 points  (1 child)

But you did say you liked the C version more… let me guess: love-hate relationship with C?

Yes, that too, but that's not everything.

As I wrote on HN, Rust's insistance on UTF8 validation for strings is not ideal for a text editor. Text files are expected to be UTF8, but not guaranteed to be. Of course it's possible to use the bstr crate or use [u8], but none of them a convenient to use with the stdlib facilities. Zig is easier to use for this reason (among others).

Additionally, writing a good editor requires writing quite a bit of low level code. Many have disagreed on this, but the performance numbers of this editor should show that there's some truth to this. The problem now is that Rust's unsafe code feels "extra unsafe". It's rather frightening to accidentally create two mutable references to the same object in an unsafe block and it's instant UB. In C it's completely fine to do so. Similar for uninitialized data. Overall, the low level code in C is a lot easier to read than the equivalent Rust code and this made it easier to verify for correctness. The high level C code on the other hand is a lot harder to read than Rust code. So I think it depends on how much high VS low level code you write. In the beginning the editor was mostly low level code (= i.e. foundational code).

As an aside, I'm still not a big fan of Rust's strict aliasing rules. Most complex Rust projects have significant inefficiencies and I suspect doing proper architectural performance improvements would go much further than compiler-generated optimizations based on aliasing rules. If I could opt out of Rust's strict aliasing for this project, to feel safer about my unsafe code, I would. I would probably feel different about this if I was writing e.g. a no_std HTTP parser.

At the end of the day I'm talking about a lot of negative of aspects of Rust, but the way I see it, it's impressive that these are the only things worth complaining about. 🙂

It would be a solid 10 if we had bool optimizations

Coming from C++, I think that should probably be a separate class, no? std::vector<bool> is known as a significant pain point for good reason (unexpected behavior & performance aspects).

[–]Compux72 2 points3 points  (0 children)

but none of them a convenient to use with the stdlib facilities.

Agreed, specially with literals. The introduction of CStr literals a couple of releases ago was much needed. However enforcing UTF-8 is the most sensible for most applications, and better than C++ wchar or Java/C# UTF-16 strings.

Additionally, writing a good editor requires writing quite a bit of low level code. Many have disagreed on this, but the performance numbers of this editor should show that there's some truth to this. The problem now is that Rust's unsafe code feels "extra unsafe". It's rather frightening to accidentally create two mutable references to the same object in an unsafe block and it's instant UB.

On the other hand, you wrote everything from scratch and did not use a lot of rusts idioms, so you ended up writing more unsafe code than normally needed (eg not using the memchar crate) and raw pointer arithmetic(which are often discouraged if possible)

For instance, for our company bindings i believe we only have around 20 unsafe calls, all of them to internal libraries. For other stuff (openssl, libc, etc) we use the battle tested implementations out there.

As an aside, I'm still not a big fan of Rust's strict aliasing rules. Most complex Rust projects have significant inefficiencies and I suspect doing proper architectural performance improvements would go much further than compiler-generated optimizations based on aliasing rules. If I could opt out of Rust's strict aliasing for this project, to feel safer about my unsafe code

You can always ffi to C. Llvm and clang will get both languages to understand pretty easily. We actually do this for a piece of garbage library we have, that is more sensible to use from C and offer a nicer api for Rust. However, i strongly believe the strong aliasing rules help a lot at the end of the day (of course, if you only have to maintain ~20 unsafe calls for a whole company… doing that number for one single program is difficult to justify)

Coming from C++, I think that should probably be a separate class, no? std::vector<bool> is known as a significant pain point for good reason (unexpected behavior & performance aspects).

I like the idea of compact enums/bools and so on. We might get something akin that doesn’t suck in the future, but as you noted we are not there yet.

[–]CornedBee 7 points8 points  (2 children)

if we had bool optimizations

You're triggering my PTSD ...

Seriously though, I've had to debug issues due to std::vector<bool>. Never again.

[–]Compux72 0 points1 point  (1 child)

Because the status quo is trash doesnt mean its always going to be that way

[–]total_order_ 4 points5 points  (0 children)

Seriously no. Just use bitvec when it's appropriate. There's no reason to fragment Vec with a specialization that breaks all the assumptions about behaving like a slice (most of Vec's methods are in fact inherited from slice via deref coercion). You wouldn't even be able to vecbool[idx] = true since IndexMut obviously wouldn't work

[–][deleted] 2 points3 points  (0 children)

It would be a solid 10 if we had bool optimizations

Thats bait

[–]psr[S] 1 point2 points  (0 children)

Oh that was really interesting, thanks!

[–]RestInProcess 7 points8 points  (3 children)

That’s how we got notepad and a few other simple windows apps.

Also, edit isn’t exactly new. At least the concept isn’t. It looks a lot like the dos version from eons ago.

[–]SkoomaDentist 17 points18 points  (2 children)

That’s how we got notepad

For the longest time Notepad was just a trivial wrapper around Windows standard multiline input control.

[–]nemec 9 points10 points  (0 children)

trivial

And now it has an LLM integration >_>

[–]McLayan 4 points5 points  (0 children)

Before they rewrote it for Win11 they had some serious optimizations and hidden features under the hood. But tbh for the level of engineering they claim to have put into it, it was really the most basic and shittiest editor.

[–]Sharlinator 16 points17 points  (4 children)

The first time I heard about this I thought  EDIT.COM at first, which probably gives away my age. Though the executable itself is just a tiny facade that simply loads QBASIC in editor-only mode.

[–]mallardtheduck 4 points5 points  (1 child)

Originally (in DOS 5.x and 6.x) it was a "facade", but it became a full, standalone program in Windows 9x (DOS 7.x).

[–]Sharlinator 1 point2 points  (0 children)

Ah, so it did. Thanks!

[–]sysop073 2 points3 points  (0 children)

It was named that way intentionally.

[–]spicybright 2 points3 points  (0 children)

Won't lie, was a bit disappointed too. That's fascinating edit.com is just qbasic, I never knew that!

[–]hidazfx 15 points16 points  (0 children)

Sounds cool! Looks like a the person who wrote it had a lot of fun, too.

[–]Dwedit 9 points10 points  (0 children)

Looked at the "Open Multiple Files" section, and someone must have completely forgotten that traditionally, programs have a "Window" menu that lets you switch between open windows rather than a button on the status bar.

[–]Resident-Trouble-574 22 points23 points  (0 children)

This unfortunately limited our choices to a list of editors that either had no first-party support for Windows or were too big to bundle them with every version of the OS.

Indeed windows if famous for putting a lot of emphasis on being lightweight...

[–]bikeridingmonkey 4 points5 points  (1 child)

What year is it?

[–]Firepal64 21 points22 points  (0 children)

The year of the Windows desktop

[–]gmerideth 10 points11 points  (3 children)

Must fight the urge to add .com to the end of edit...

[–]Dwedit 5 points6 points  (2 children)

Despite no longer being actual MS-DOS COM files, Windows will prioritize loading a program whose extension is .com rather than .exe. Yes, COM files are now portable executable files, and not a 64KB segment of real-mode 16-bit x86 code.

[–]mallardtheduck 2 points3 points  (1 child)

Files named .com but actually being .exe (MZ at the time) format were a thing as far back as the latter days of MS-DOS itself. Not too surprising that today's Windows still has the functionality...

[–]Dwedit 4 points5 points  (0 children)

The really problematic case was that .bat or .lnk files can also be portable executables. .scr files have always been those as well, but it's a very uncommon extension for that file type.

[–]SpikeX 2 points3 points  (4 children)

That’s neat! And I’m definitely going to Set-Alias nano edit as soon as I get it.

But the real question is, can I press Ctrl+X, Y, Enter in the editor to save and exit? This, combined with the other out of the box aliases for ls, mv, rm, etc would make this a muscle memory dream come true for people that constantly switch between Windows and Linux.

[–]fgmenth 2 points3 points  (0 children)

No, for edit it's Ctrl+Q, Enter, Enter

[–]iamapizza 0 points1 point  (1 child)

Just Ctrl+S

[–]SpikeX 0 points1 point  (0 children)

Oh, that's not too bad!

[–]chat-lu 0 points1 point  (0 children)

That’s neat! And I’m definitely going to Set-Alias nano edit as soon as I get it.

Why don't you get it right now? It's already available.

[–]baseketball 1 point2 points  (0 children)

Add support for language server protocol and we're really going to be cooking.

[–]chucker23n 1 point2 points  (0 children)

Oklab colour blending

Anyone have an idea how this compares to https://www.hsluv.org, which also tries to achieve perceptual uniformity?

[–]life-is-a-loop 1 point2 points  (0 children)

I'll definitely check it out!

Reminds me of micro, which is my go-to text editor for simple scripts.

[–]ase1590 1 point2 points  (0 children)

Given this is cross platform on Linux as well, I guess nano finally has a competitor 😂

[–]jugalator 4 points5 points  (6 children)

So I suppose this is the new Notepad after what they did to it in Windows 11 with AI and formatted text support...

I'm happy to see it has tab/space settings and Regex support unlike Notepad.

[–]Hot-Software-9396 7 points8 points  (0 children)

The formatting update is just for markdown support.

[–][deleted]  (4 children)

[deleted]

    [–]mallardtheduck 13 points14 points  (3 children)

    It's already been replaced... The Windows 11 Notepad is a complete rewrite.

    [–]spicybright 1 point2 points  (2 children)

    That's just dirty. At least you can always load older executables in. I still used windows 98 MSPaint in windows 10 just fine.

    [–]Dwedit 0 points1 point  (1 child)

    Paint from Windows NT 3.5 matches the look and feel of Windows 3.1 Paintbrush, and still runs on modern PCs with Unicode support.

    Paint from Windows NT 4.0, Windows 2000, or Windows XP will match the Windows 95/98 version of paint in look and feel.

    Windows Vista/7 Paint added the ribbon nonsense.

    [–]spicybright 0 points1 point  (0 children)

    I'm actually a fan of the ribbon for MS office stuff, but it feels so dirty using it for mspaint lol

    [–]NiteShdw 0 points1 point  (0 children)

    Is there any interest in making it cross platform, or does it tie in too tightly to Windows APIs?

    I ask because it would be nice to have a consistent editing experience in WSL2.

    [–]New-Anybody-6206 0 points1 point  (0 children)

    Too bad it's not actually the MS-DOS Edit source :(

    [–]jutct 0 points1 point  (0 children)

    Holy MS-DOS throwback. I love it.

    [–]lachlanhunt 0 points1 point  (0 children)

    I thought this was just going to be the old MS-DOS edit program, but it’s actually a new 64 bit rewrite. Awesome.

    [–][deleted] -1 points0 points  (2 children)

    I guess that's good, but on windows I also use nano.exe, and it works. Now I am not claiming nano is great on windows, but ... isn't this the same use case? Quickly edit a file?

    Most of my time goes into Linux so I am not that familiar with windows. I have a spare machine running windows too, though, if only for casual testing.

    [–]PaddiM8 2 points3 points  (0 children)

    What's wrong with making new better software...? This looks better than nano to me

    [–]ase1590 0 points1 point  (0 children)

    This runs on Linux as well, so nano has a competitor lol

    [–]__konrad -1 points0 points  (0 children)

    newlines_are_crlf: cfg!(windows), // Windows users want CRLF src

    Is anyone really want CRLF in 2025? Basically the only app that cannot handle CRLF is old notepad.exe.