Skip to content(if available)orjump to list(if available)

Edit is now open source

Edit is now open source

190 comments

·May 19, 2025

lhecker

Hey all! I made this! I really hope you like it and if you don't, please open an issue: https://github.com/microsoft/edit

To respond to some of the questions or those parts I personally find interesting:

The custom TUI library is so that I can write a plugin model around a C ABI. Existing TUI frameworks that I found and were popular usually didn't map well to plain C. Others were just too large. The arena allocator exists primarily because building trees in Rust is quite annoying otherwise. It doesn't use bumpalo, because I took quite the liking to "scratch arenas" (https://nullprogram.com/blog/2023/09/27/) and it's really not that difficult to write such an allocator.

Regarding the choice of Rust, I actually wrote the prototype in C, C++, Zig, and Rust! Out of these 4 I personally liked Zig the most, followed by C, Rust, and C++ in that order. Since Zig is not internally supported at Microsoft just yet (chain of trust, etc.), I continued writing it in C, but after a while I became quite annoyed by the lack of features that I came to like about Zig. So, I ported it to Rust over a few days, as it is internally supported and really not all that bad either. The reason I didn't like Rust so much is because of the rather weak allocator support and how difficult building trees was. I also found the lack of cursors for linked lists in stable Rust rather irritating if I'm honest. But I would say that I enjoyed it overall.

We decided against nano, kilo, micro, yori, and others for various reasons. What we wanted was a small binary so we can ship it with all variants of Windows without extra justifications for the added binary size. It also needed to have decent Unicode support. It should've also been one built around VT output as opposed to Console APIs to allow for seamless integration with SSH. Lastly, first class support for Windows was obviously also quite important. I think out of the listed editors, micro was probably the one we wanted to use the most, but... it's just too large. I proposed building our own editor and while it took me roughly twice as long as I had planned, it was still only about 4 months (and a bit for prototyping last year).

As GuinansEyebrows put it, it's definitely quite a bit of "NIH" in the project, but I also spent all of my weekends on it and I think all of Christmas, simply because I had fun working on it. So, why not have fun learning something new, writing most things myself? I definitely learned tons working on this, which I can now use in other projects as well.

If you have any questions, let me know!

steveklabnik

I’d love to hear about the use of nightly features. I haven’t had time to dig into the usage, but that was something I was surprised by!

lhecker

Up until around 2 months ago the project actually built with stable Rust. But as I had to get the project ready for release it became a recurring annoyance to write shims for things I needed (e.g. `maybe_uninit_fill` to conveniently fill the return value of my arena allocator). My breaking point was the aforementioned `LinkedList` API and its lack of cursors in stable Rust. I know it's silly, but this, combined with the time pressure, and combined with the lack of `allocator_api` in stable, just kind of broke me. I deleted all my shims the same day (or sometime around it at least), switched to nightly Rust and called it a day.

It definitely helped me with my development speed, because I had a much larger breadth of APIs available to me all at once. Now that the project is released, I'll probably stay with the nightly version for another few months until after `let_chains` is out in stable, because I genuinely love that quality-of-life feature so much and just don't want to live without it anymore. Afterward, I'll make sure it builds in stable Rust. There's not really any genuine reason it needs nightly, except for... time.

Apropos custom helpers, I think it may be worth optimizing `Vec::splice`. I wrote myself a custom splice function to reduce the binary size: https://github.com/microsoft/edit/blob/e8d40f6e7a95a6e19765f...

The differences can be quite significant: https://godbolt.org/z/GeoEnf5M7

steveklabnik

Thank you!

> I know it's silly,

Nah, what's silly is LinkedList.

> I think it may be worth optimizing `Vec::splice`.

If this is upstream-able, you should try! Generally upstream is interested in optimizations. sort and float parsing are two things I remember changing significantly over the years. I didn't check to see what the differences are and how easy that actually would be...

anacrolix

The quirkiness of Zig is real. I'd love for Zig to win out but it's just too weird, and it's not progressing in a consistent direction. I can appreciate you falling back to Rust.

dnautics

> it's not progressing in a consistent direction

I've maintained a project in zig since either 0.4 or 0.5 and i dont think this is the case at all. supporting 0.12 -> 0.13 was no lines of code, iirc, and 0.13->0.14 was just making sure my zig parser could handle the new case feature (that lets you write a duff's device).

zig may seem quirky but it's highly internally consistent, and not far off from C. every difference with c was made for good reasons (e.g. `var x:u8` vs `char x` gives you context free parsing)

i would say my gripes are:

1. losing async

2. not making functions const declarations like javascript (but i get why they want the sugar)

Gb35643

Thanks for this. Don't ask why but i just defaulted to Edit on Linux. I noticed there's no locking for edited files. Not even a notification saying "This file has been modified elsewhere since you opened it. Do you still want to save"

Can you confirm this? Is it some thing you intend to add? Curious to know why, if the answer is no

marler8997

I checked the git history to see if you included the Zig version but looks like first revision is rust...

In the Zig version did you use my zigwin32 project or did you go with something else? Also, how did you like the Zig build system vs rusts?

lhecker

Back then (a year ago?) I simply included the Windows.h header into a Zig file. Is that not possible anymore? It worked great back then for me IIRC!

Overall, I liked the build system. What I found annoying is that I had to manually search for the Windows SDK path in build.zig just so I can addIncludePath it. I needed that so I can add ICU as a dependency.

The only thing that bothered me apart from that was that producing LTO'd, stripped release builds while retaining debug symbols in a separate file was seemingly impossible. This was extra bad for Windows, where conventionally debug information is always kept in a separate file (a PDB). That just didn't work and it'd be great if that was fixed since back then (or in the near term).

alexrp

> Since Zig is not internally supported at Microsoft just yet (chain of trust, etc.)

Is there something about Zig in particular that makes this the case, or is it just an internal politics thing?

lhecker

I don't know why, but I'm quite certain it's neither of the two. If anything, it has probably to do with commitment: When a company as large as MS adopts a new language internally, it's like spinning up an entire startup internally, dedicated to developing and supporting just that new language, due to the scale at which things are run across so many engineers and projects.

90s_dev

1. What do you like about Zig more than Rust?

2. How did you ensure your Zig/C memory was freed properly?

3. What do you not like about Rust?

lhecker

> What do you like about Zig more than Rust?

It's been quite a while now, but:

- Great allocator support

- Comptime is better than macros

- Better interop with C

- In the context of the editor, raw byte slices work way better than validated strings (i.e. `str` in Rust) even for things I know are valid UTF8

- Constructing structs with .{} is neat

- Try/catch is kind of neat (try blocks in Rust will make this roughly equivalent I think, but that's unstable so it doesn't count)

- Despite being less complete, somehow the utility functions in Zig just "clicked" better with me - it somehow just felt nice reading the code

There's probably more. But overall, Zig feels like a good fit for writing low-level code, which is something I personally simply enjoy. Rust sometimes feels like the opposite, particularly due to the lack of allocators in most of its types. And because of the many barriers in place to write performant code safely. Example: The `Read` trait doesn't work on `MaybeUninit<u8>` yet and some people online suggest to just zero-init the read buffer because the cost is lower than the syscall. Well, they aren't entirely wrong, yet this isn't an attitude I often encounter in the Zig area.

> How did you ensure your Zig/C memory was freed properly?

Most allocations happened either in the text buffer (= one huge linear allocator) or in arenas (also linear allocators) so freeing was a matter of resetting the allocator in a few strategical places (i.e. once per render frame). This is actually very similar to the current Rust code which performs no heap allocations in a steady state either. Even though my Zig/C code had bugs, I don't remember having memory issues in particular.

> What do you not like about Rust?

I don't yet understand the value of forbidding multiple mutable aliases, particularly at a compiler level. My understanding was that the difference is only a few percent in benchmarks. Is that correct? There are huge risks you run into when writing unsafe Rust: If you accidentally create aliasing mutable pointers, you can break your code quite badly. I thought the language's goal is to be safe. Is the assumption that no one should need to write unsafe code outside of the stdlib and a few others? I understand if that's the case, but then the language isn't a perfect fit for me, because I like writing performant code and that often requires writing unsafe code, yet I don't want to write actual literal unsafe code. If what I said is correct, I think I'd personally rather have an unsafe attribute to mark certain references as `noalias` explicitly.

Another thing is the difficulty of using uninitialized data in Rust. I do understand that this involves an attribute in clang which can then perform quite drastic optimizations based on it, but this makes my life as a programmer kind of difficult at times. When it comes to `MaybeUninit`, or the previous `mem::uninit()`, I feel like the complexity of compiler engineering is leaking into the programming language itself and I'd like to be shielded from that if possible. At the end of the day, what I'd love to do is declare an array in Rust, assign it no value, `read()` into it, and magically reading from said array is safe. That's roughly how it works in C, and I know that it's also UB there if you do it wrong, but one thing is different: It doesn't really ever occupy my mind as a problem. In Rust it does.

Also, as I mentioned, `split_off` and `remove` from `LinkedList` use numeric indices and are O(n), right? `linked_list_cursors` is still marked as unstable. That's kind of irritating if I'm honest, even if it's kind of silly to complain about this in particular.

In all fairness, what bothers me the most when it comes to Zig is that the language itself often feels like it's being obtuse for no reason. Loops for instance read vastly different to most other modern languages and it's unclear to me why that's useful. Files-as-structs is also quite confusing. I'm not a big fan of this "quirkiness" and I'd rather use a language that's more similar to the average.

At the end of the day, both Zig and Rust do a fine job in their own right.

ameliaquining

The design intent of unsafe Rust is that its usage should be rare and well-encapsulated, but supported in any domain. Alleviating a performance bottleneck is a fine reason to use unsafe, as long as it only appears at the site of the bottleneck and doesn't unnecessarily leak into the rest of the codebase.

The most basic reason why you can't have unrestricted mutable aliasing is because then the following code, which contains a use-after-free bug, would be legal:

    let mut val = Some("Hello".to_owned());
    let outer_mut = &mut val;
    let inner_mut = val.as_mut().unwrap();
    *outer_mut = None;
    println!("{}", inner_mut);
If, as is sometimes the case, you need some kind of mutable aliasing in your program, the intended solution is to use an interior-mutability API (which under the hood causes LLVM's noalias attribute to be omitted). Which one to use depends on the precise details of your use case; some (e.g., RefCell) carry performance costs, while others (e.g., Cell) are zero-cost but work only for certain types or access patterns. Having to figure this out is annoying, but such is the price of memory safety without runtime garbage collection. In the worst-case scenario you can use UnsafeCell, which as the name suggests is unsafe, but works with any type with no performance cost. UnsafeCell is also a little bit heavy on boilerplate/syntactic salt, which people used to C sometimes find annoying; there isn't that much drive to fix this because, as per above, it's supposed to be rarely used.

The "few percent in benchmarks" thing sounds like it's referring to the rule that it's UB to use unsafe code to make aliased &mut references even if you don't actually use those references in a problematic way. Lifting that rule would preclude certain compiler optimizations, and as per above would not fix the real problem; you still couldn't have unrestricted mutable aliasing. It would only alleviate the verbosity cost, and that could be done in a different way without the performance cost (like by adding special concise syntax for UnsafeCell) if it were deemed important enough.

The uninitialized-memory situation is pretty widely agreed to be unsatisfactory. Unfortunately it is hard to fix. Ideally the compiler would do flow-control analysis so that you can read from memory that was uninitialized only if it has definitely been written to since then. Unfortunately this would be a big complicated difficult-to-implement type system feature, and the need to make it unwind-safe (analogous to the concept of exception safety in C++) adds much, much more complication and difficulty on top of that. You could imagine an intermediate solution, wherein reading from uninitialized memory gets you a valid-but-unspecified value of the applicable type instead of UB, but that also has some difficulties, such as unsoundness in conjunction with MADV_FREE; see https://internals.rust-lang.org/t/freeze-maybeuninit-t-maybe... if you're curious for more details.

Again, the point here is not "the current design is optimal", it's "improving on the current design is a difficult engineering problem that no one has solved yet".

I think people who need cursors over linked lists use a third-party library from crates.io for this, but it's quite reasonable to think that the standard library should have this. Most of the time when a smallish feature like that remains unstable it's because nobody has cared enough about it to shepherd it through the stabilization process (perhaps because it's not a hard blocker if you can use the third-party library instead). Possibly that process is too slow and heavyweight, but of course enacting a big process change in a massively multiplayer engineering project that's governed by consensus is an even harder problem.

Cloudef

I think files as struct makes lots of sense. As it doesnt have to treat files in any special way then.

mwcampbell

I wonder if you used GitHub Copilot or some other LLM-based code generation tool to write any of the code. If not, that's a lot of code to write from scratch while presumably under pressure to ship, and I'm impressed.

lhecker

I did use Copilot a lot, just not its edit/agent modes. I found that they perform quite poorly on this type of project. What I use primarily is its autocompletion - it genuinely cured my RSI - and sometimes the chat to ask a couple questions.

What you expressed is a sentiment I've seen in quite a few places now. I think people would be shocked to learn how much time I spent on just the editing model (= cursor movement and similar behavior that's unique to this editor = a small part of the app) VS everything else. It's really not all that difficult to write a few FFI abstractions, or a UI framework, compared to that. "Pressure to ship" is definitely true, but it's not like Microsoft is holding a gun to my chest, telling me to complete the editor in 2 months flat. I also consider it important to not neglect one's own progress at becoming more experienced. How would one do that if not by challenging oneself with learning new things, right? Basically, I think I struck a balance that was... "alright".

avestura

It was very interesting to me that you liked Zig the most. Thank you for making this!

computatrum

It not only written in Rust, but they avoid basically any dependencies to third-party crates (beside the obligatory windows-sys/libc), optimizing probably for binary size. To achieve this, they seem to re-implement considerable parts of the rust ecosystem (own TUI library implementation, own unicode handling, own arena implementation, ...).

porcoda

I’m guessing this isn’t just to optimize for binary size. If you have the resources to avoid third party dependencies you eliminate the burden of having to build a trust case for the third party supply chain. That is the number one reason we sometimes reimplement things instead of using third party packages where I work: the risk from dependencies along with the effort required to establish that we can trust them is sometimes (not always) greater than just replacing it in house.

criddell

Microsoft has recently said AI writes 30% of their code. Reimplementing things isn’t as expensive as it once was.

ItsHarper

That was absolutely not what was said. The way it was phrased indicates it only applies to a subset of projects, plus there were weasel words to indicate that maybe it's not actually quite that high, plus AI was not explicitly mentioned and it easily could include a lot of traditionally-generated code.

al_borland

I ran across the dashboard where I work that is tracking Copilot usage. According to the dashboard 22% of suggestions are accepted. I assume Microsoft is quoting a similar stat. This is VERY misleading, as more often than not, the suggestion is trash, but has 1 thing in it I want for reference to look up something that might actually help me. I accept the suggestion, which increases that stat, but AI didn’t ultimately write the resulting code that went to production.

mplanchard

I took a glance around this project, and it seems to be really high quality Rust. I would be shocked if it was AI-generated to any significant degree, given my own less-than-impressive results trying to get LLMs to write Rust.

Edit: I see the author isn’t very familiar with Rust, which makes it even more impressive.

dymk

Maybe a tenth the total cost is getting the code into the terminal, the other nine tenths is maintaining way more code than you'd otherwise have to.

geysersam

How much cost reduction does 30% ai written code translate to? It's easy to imagine that ai doesn't write the most expensive lines of code. So it might correspond to 10% cost reduction.

10% is nothing to scoff at, but I don't think it should factor into the decision to rewrite existing packages or trust third parties if you're very security minded.

alternatex

Microsoft has no metric to track this and I can guarantee you that statement is for marketing purposes.

null

[deleted]

el_sinchi

[dead]

cerved

I'd guess legal reasons

01HNNWZ0MV43FF

I'd say the windows crate is even technically first-party since the OS vendor publishes it

arghwhat

Yay for finally having a default text editor that works over ssh. Managing windows servers over ssh is a bit of a pain without.

They could just have packaged nano, but oh well.

p4bl0

I wholeheartedly agreee. Nano is quite awesome, it is battle-tested and already has more features than needed for a basic text editor. Actually, Nano is too often frowned upon as too-basic, but is actually has a few advanced features that basic editors do not have (e.g., keyboard macros). I'd argue that Nano is simple rather than basic :).

I tried discussing it here a few months ago but it did not took off: https://news.ycombinator.com/item?id=41289773

Sammi

I love nano and used it as my terminal editor on Linux.

Edit seems super approachable to newbies with it's mouse support in the menus. I love that and would love to see it in nano.

p4bl0

Just put

    set mouse
in your ~/.nanorc and then you can click on all the UI elements, including the actions/functions at the bottom of the screen, which play the roles of the menu in Nano.

fastasucan

Try micro

red_admiral

I was about to say, I use nano regularly, both locally and over ssh (to machines which have it installed, which is pretty much all of them). This looks nice and I love old-style console UIs, I fondly remember EDIT.COM and NC.EXE, and still use `mc` regularly with one pane pointing at a sshfs.

Ages ago I had to maintain a .BAT file, editing in EDIT.COM, that threw stuff at EDLIN.COM (roughly MS version of `ed`). Those where the ... not-so-good old days.

These days, with windows versions of `nano` and `busybox` you have some power tools without a full linux install.

zozbot234

This could be a great text-mode IDE with the addition of some LSP, tree-sitter and DAP support. There is already an open issue about possibly adding support for tree-sitter grammars for fast syntax highlighting, but they do mention that this requires some sort of optional plugin system to avoid bloating up the codebase severely (for example, the tree-sitter grammars within the Helix editor take up hundreds of megabytes, which is obviously unacceptable here).

arghwhat

That just feels like scope creep. Notepad would also be neat with some better keybinding support, plugins, lsp, ... - but then it wouldn't be notepad, and theres countless not notepads out there.

Tools like nano (well, pico) exist to provide a reliable and always available minimum feature set. If you expand it, then you end up with something that is neither the minimum nor capable enough to sensibly compete with fully fledged alternatives.

divbzero

Well, Notepad is introducing AI support which already feels like scope creep to me…

https://support.microsoft.com/en-us/windows/enhance-your-wri...

eviks

No, it would still be notepad, but a higher quality one where especially users who don’t know better wouldn’t have to suffer as much from bad/lacking functionality

Y_Y

What on earth needs hundreds of megabytes to describe its grammar?

Even the hundreds of kilobytes used in the official grammars seems bulky to me. https://github.com/tree-sitter/tree-sitter-java/releases

6c696e7578

I am truly behind the times. I didn't know you can ssh into a Windows system.

e12e

Since windows 10/windows server 2019 afaik.

https://news.ycombinator.com/item?id=15904265

6c696e7578

Thanks! It always bugged me that Windows didn't have a sshd, since it's so popular outside of Windows. I thought the reason for it not being added would be admitting a failure somewhere - RDP not winning or something. Seemed odd to prevent a way into Windows Server.

emmelaich

You can also run a ssh server in WSL2. You'll need to proxy connections to it or run a vpn though to have it visible from the outside. I use tailscale.

yjftsjthsd-h

Ah, that makes sense then; I was really confused at first because I couldn't figure out why Windows would want a built-in text-mode editor. I suppose if folks are seriously using SSH to access Windows machines ... then I have other questions about why not RDP, but if that's a real thing people are doing then adding a built-in editor for them makes sense.

arghwhat

SSH is ubiquitous, lightweight, and now works for all machines equally.

SSH is integrated with everything and can be used to manage, transfer files/mount remote folders, forward ports in either direction, or proxy any network traffic through the remote end for debugging/access. You can open a remote folder directly in vscode, Zed or similar over SSH.

RDP to a standard Windows server (this was previously called "core" - having a desktop environment is a non-default add-on now) is silly as you're RDP'ing to solely see a cmd.exe window that asks you to use console-based configuration (sconfig.exe).

RDP to a windows server with "Desktop Experience" is silly because it is comparatively sluggish, streaming a (likely unaccelerated) video feed of heavier GUI applications vs. sending just a few text strings back and forth during editing.

Not to mention that containerized windows has no graphical stack and requires a text-centric workflow.

luma

This might be the most obvious use case: https://learn.microsoft.com/en-us/windows-server/administrat...

I'm a powershell bigot and spend most of my windows admin life in a terminal (or vscode) so my take is to simply use psremoting but ssh is there if you need.

arghwhat

I prefer SSH because it fits into a standard workflow with far larger ecosystem (my file manager and editors can browse SSH directly, traffic can easily be routed over SSH in either direction), and is already what I'd use for the majority of servers and machines.

psremoting would be limited specifically to remote PowerShell on windows, which is comparatively limited. Even if I was purely a Windows admin I'd consider the SSH approach more powerful.

90s_dev

bpshaver

jftuga

Micro is nice because it is a single-file, stand-alone executable that has mouse support, macro record/playback and syntax highlighting. (I haven't checked Nano recently). It is great for making quick edits to json configs, shell scripts, python scripts, etc. Syntax highlighting and line numbering are key. If I need to make a really quick edit, it is much faster to use this than waiting for VS Code or PyCharm to load. You also stay focused. By this I mean, your eyes don't leave the terminal window that you are currently working in. This allows me to more quickly complete the task at hand.

rendaw

I was impressed that they actually looked at other editors in the ecosystem, I wasn't expecting that. Aside from WSL stuff does Windows distribute any other 3rd party utilities?

TiredOfLife

openssh, curl, bsdtar (also Windows built in archive support is libarchive)

TZubiri

It's such a simple program that it's better to roll a proprietary program that is well integrated with windows

You can use nano over wsl if you want

arghwhat

> You can use nano over wsl if you want

No, not when ssh'ing to a server to manage it. Pulling in a Linux VM to get a simple text editor also makes no sense.

There is also nothing to integrate - it's a basic text editor for a terminal with no fancy features. It either edits text or it doesn't.

TZubiri

you gotta make sure that hotkeys get passed in every keyboard configuration. Ctrl, CTRL Shift, Ctrl Caps, Alt, how do tabs work? Etc..

That something looks simple but is actually difficult is an error we all make

massysett

Nitpick - this is a text user oriented (TUI) or a screen editor, not a CLI editor. A CLI editor is ed(1), or ex(1), or EDLIN for MS-DOS lineage.

dbuxton

I can't wait for the Rust port of QBasic Gorillas

red_admiral

This is a denial-of-service attack on my productivity :)

I fondly remember the times of editing the explosion radius to "tactical nuclear banana".

andrewstuart

Edit for DOS was my favorite editor.

All the keys worked as you expect. You could select text with shift. It had find and a replace. That’s a lot more than most editors give you without config fiddling and arcane key commands.

Those simple things get almost everything I need for operating system maintenance.

Edit was the pure distilled essence of an editor.

It was a work of art really.

sedatk

It was okay when it came out because the alternative was EDLIN (DOS version of ed). But IIRC, it had a 64KB file size limitation which was a problem.

JdeBP

It came out with MS-DOS 5, and by that time there were loads of alternatives already available. There were ports of Unix and Big Iron editor programs.

There were loads of native PC text editors, too. SemWare's QEdit had been around since 1985, for example. DR-DOS had had EDITOR for a while, which might indeed have spurred Microsoft into action.

Boxer was a contemporary with MS-DOS EDIT, but that name was a pun on the name of an earlier widespread DOS text editor named Brief, also around for years before EDIT came along.

90s_dev

Interesting how we always go in circles.

edit.cmd was one of the first programs I ever used.

Now it's back rewritten as a Windows 10+ program in Rust?

Yet it looks and works just the same as 30 years ago!

nichos

You probably mean edit.com, which is what I thought of when I saw this post.

https://en.m.wikipedia.org/wiki/MS-DOS_Editor

MonkeyClub

And it is, according to their GH page, an homage to EDIT.COM.

trinix912

I wonder what prevented them from porting the ms-dos EDIT.COM to 64bit Windows back then. There's still EDLIN.COM in the 32bit version.

tadfisher

They canceled the 64-bit port of NTVDM (virtual DOS machine), which is what handles all those INT 21h syscalls from DOS applications. Without that, there's honestly not much to port, and it's easier to just make a new NT-native CLI app.

90s_dev

Did they cancel it because dosbox exists? If so, that's smart.

kmeisthax

Most likely because Microsoft didn't consider it a valuable use of engineering time in general.

AMD's 64-bit extensions explicitly forbade dropping to 16-bit code. Once you enter 64-bit mode you lose access to all the modes which NTVDM needs to run MS-DOS or 3.x apps.

AFAIK the virtualization extensions added in 64-bit (known as VT-x etc) do allow 16-bit code, but that would require rebuilding NTVDM as a Hyper-V client (ala WSL2) instead of using 32-bit protected mode as a way to virtualize 16-bit code. However, these extensions didn't exist until way later and they didn't get support for booting 16-bit guests until later than that.

You could software emulate x86 to do NTVDM stuff. In fact, there's a FOSS program that does this, called WineVDM[0]. The MIPS/Alpha/PPC ports of NT used software emulation in NTVDM, so it is feasible.

[0] https://github.com/otya128/winevdm

Interestingly, they also recommend using DOSBox for DOS apps.

zozbot234

DOS-era codebases are just terrible in a modern context, they would have to rewrite it from scratch anyway. The TUI IDE included within FreePascal is basically bitrotting due to this very reason.

MonkeyClub

The new Microsoft Edit is good. It's not as good as EDIT.COM, but it gets the job done.

A couple of peeves: it lacks word count (which would be very useful), and there is no way to escape to shell (which would render it more usable for light scripting tasks).

I don't mind it too much, but I dislike how it hijacks the selected terminal font in Windows Terminal, how you can't hit Esc to close the menus in a Linux terminal, and how not all functions can be accessed using the keyboard with direct shortcuts.

For example, to change which file you're editing, you have to select View > Focus Statusbar, press the left arrow, hit Enter to select the list of edited files, select the file you want to switch to, and press enter. I wonder why there's no shortcut for that, which would be a common use case.

For a side project, it's very nice all around. If these issues were to be fixed, it would be a perfectly adequate editor.

Then the only feature missing would be an embedded Lisp interpreter used for automation and extensibility. :)

Edit: It has no telemetry, right?

ladyanita22

Why is it not as good as EDIT.COM?

andyferris

I have to say, I really miss MS-DOS TUI apps like edit, the qbasic editor, and xtree-gold.

The linux-terminal based ones just seem a bit off in comparison. Maybe it's mouse and keyboard support in terminals (shift-enter support, anyone?) aren't great? People have different aesthetics? I don't know...

Next stop: VS-EDIT would be pretty cool :) (This with LSPs)

JdeBP

It's definitely for that reason. It is amazingly hard to portably do something as trivial in the DOS world as recognize [Shift]+[Ins]. The terminal paradigm is very different to the console paradigm in some areas.

In the days when a Tektronix terminal was a real physical thing that one sat in front of, the TUIs that one used didn't look at all like the ones in the contemporary personal computer world. Ironically, an old Tektronix or DEC VT user transported into the future would be very at ease with what you get in the Linux-based operating system world today.

All that said, the Windows Terminal people have worked pretty hard to get even some of the obscure ECMA-48, ITU T-416, DEC VT, and XTerm stuff into Windows Terminal, so at least TUI applications writers who are prepared to write all of the bizarre hooplah to have things like recognition of [Control]+[Home] and correctly operating reverse video, actually will get them.

int_19h

DOS was the golden age for TUI apps because its ultimate API was both simple and powerful: direct video memory access in text mode. So you just get a linear chunk of memory where each character on screen corresponds to two bytes: one for the glyph, one for foreground/background color (4 bits each). For input you had some BIOS helper interrupts, but then again it was easy enough to read scancodes directly (and they were standardized on PC).

So you can handle any key or key combo however you want, and you can put any characters anywhere you want without weird corner cases like autoscrolling.

null

[deleted]

thaumasiotes

Weird choice of name for their new software, given there is already a pretty prominent editor from Microsoft named "edit".

https://en.wikipedia.org/wiki/MS-DOS_Editor

They seem to have given it the same name because they want to preserve the command. But the headline is... misleading.

DangitBobby

I love that it has a toolbar with shortcut keys highlighted at the top. I wish more TUI programs had that, especially vim!

jerrygenser

Zellij is a good example of a tui with shortcuts in the UI. Helped me learn them way better than I would have otherwise

Sammi

Yes! GUI menus with keyboard shortcuts written on the menu items are a great way to explore and learn new software.