Text editor

Hello everyone, I'm writing a simple text editor as an experiment, modeled mainly after 4coder which is my editor of choice.
When I say "modeled" I mean having 1% of its features, since I wouldn't be able to write something THAT awesome anyway XD

It's still very wonky, especially the undo/redo and clipboard functionality. It can only read/write ASCII, doesn't yet respect line endings and works only with mono-spaced fonts. If there's any interest in this, I'll try to address the most heavy bugs and set up a repository for the source. I'm writing it on Windows but it works on Linux too for the most part.

Ctrl + o to open a file browser
Ctrl + zero to switch between panels
Ctrl + space to set the marker
Ctrl + k to clear the current buffer
ArrowUp/ArrowDown/Return/Backspace/Esc/(type to filter) to navigate the file browser

Some basic text editing/navigation such as PgUp/PgDown/Home/End/Copy/Paste work for the most part (very buggy), but it's still missing others like Ctrl+arrows, etc.

I've temporarily mapped Ctrl + s to save the current buffer as "example.txt" in the current directory, instead of saving the actual opened file. That's to prevent any unwanted behavior on precious files.

EDIT: Last update Jan/19/2020
download from dropbox


Edited by John on
Cool!

I'd be interested in how you (and others) implement textbuffers, so insertions at arbitrary points are fast. Do you use a gap buffer? Some linked-list-with-chunks-thing? Just a single allocation, and memcpy to make space for inserts? I guess the last approach would be fast enough for most code files...
Hi seventh-chord! (BTW cool name, I used to build guitars and have made a couple of 7strings. EDIT: oops its seventh-chord, not seven-string... excuse my confusion :p)

I've done a little research before beginning this project and it seems that the gap-buffer method is one of the most popular implementations.
I went with a doubly linked-list because it seemed to me the most easier to produce a working prototype quickly. In my implementation, the head is a dummy node (called a sentinel node formally) that doesn't actually hold any text. It's just points to the first line node. The last line-node's "next" field has a NULL value which indicates the end of the buffer.
When a new line is created, a default memory block for its text field is allocated. I went with 64B. When it's filled with characters, that block is re-allocated with another 64B chunk and so on.
When a line is merged with a previous line or when a paste operation is performed, I simply calculate the closest quantity of chunks needed and do a realloc. Similarly, when a line is split in 2 or when a bunch of characters get deleted, the bigger chunk shrinks.
So each line has it's own capacity made of multiples of 64B.

Although it is surprisingly fast (reading a 100000+ loc file in a split second, most text operations are fast), it makes things more complicated for operations like undo/redo and multi-line clipboard handling. (That's why it's buggy as hell XD)

I hope that helps and I'll be happy to answer any questions!

Edited by John on
Thanks for your reply!

I'm actually also writing a text editor, mostly as a learning experience. Currently I am still trying to implement all the features I would need to actively use it, so I haven't put much thought into optimizing anything yet: I just store buffers as a big continuous allocation, and do inserts with two 'memcpy's. So far I haven't run into issues with that approach in my rudimentary testing, but my gut feeling tells me it will eventually come back to bite me (maybe that just means i need to improve my gut though...)

Regarding undo/redo, I only modify my buffers through an 'insert'- and a 'delete'-function, and whenever I call them I also log the parameters. When undoing, I run back the log, calling 'delete' for each 'insert' and vice versa. Except for the fact that I have to store the deleted strings so insertions work, this approach means undo/redo doesn't add any extra complexity at the buffer layer. I see how that might be more complicated when you don't store offsets as a single number, but as a line+column pair, which might change as the result of an edit.

I also downloaded your editor and tried it out a bit, so I can confirm it works on other machines than yours :)

(Also, when will you showcase your handmade guitars here? :P)
Really nice of you sharing your ideas and will love to try your editor!

The way I did undo/redo is like this: I have an array of structs where each entry is a "text operation" (insert, delete, paste, merge lines, etc).
It records the operation "type", line/column, and the character stream that was inserted/deleted/etc.

Inserts are actually a bit more complicated, because when you type a continuous stream of alphanumeric characters , it is considered a single operation. So when this stream is interrupted by a non alphanumeric character, or when insertion is done on another position, the current operation is "locked" and another one is created.

The array is of fixed size (MAX_UNDO_STEPS) and is wrapped around when filled, so it always has MAX_UNDO_STEPS worth of operations. It serves the purpose of both undo and redo, because when i undo an operation I commit the changes to the buffer but the entry in the array doesn't get deleted. BTW, I accidentally set the undo steps to 5 in the exe I uploaded, because I was testing things. It should be a lot more obviously!

seventh-chord

(Also, when will you showcase your handmade guitars here? :P)


Haha, I'll definitely get kicked if I post anything other than programming stuff here XD
I hope a single pic doesn't cause any trouble though!
Updated the link in the first post with a new version.

I've added some basic mouse functionality that allows to resize the panels and set the cursor to wherever the mouse pointer clicks.
Made some fixes here and there and also added a config file. I temporarily disabled the undo/redo functionality as it had memory leaks.
I'll now mainly focus on fixing the clipboard and undo/redo stuff, and some drawing issues like the cursor rendering out of the panel's bounds when resizing the window/panels, etc.

If anyone has tested it and has noticed any other issues I'd be grateful if you reported them here.
I tried it and it works on my machine (Windows 7).

It crashed when I try to close it (there was a file with unsaved changes).
Apart from that it's always using +- 1.5% of my CPU even when it doesn't have the focus or not doing anything. I don't have the window compositor on in windows.
Thank you very much for trying it out Simon!
Ah, you're right about the CPU usage. I only took care of it only when the window is minimized (which goes to 0%). Hopefully that will be easy to fix. I don't know about the crash on exit, I haven't witnessed anything like that on Windows 10. I'll have to set a Win7 VM to try it out.
Thanks for your report!
Updated first post with new version.
Added key-bindings in the config file. Fixed some bugs in the file browser and some rendering issues. A couple of improvements here and there.
Compiled on a debian VM and it's working! It needs sdl2, freetype and (libsdl2-ttf) to run.
Here's a link to the linux build.

Got access to the source, because he's my father! Hi dad.
I like this thread :-)
miked
Compiled on a debian VM and it's working! It needs sdl2, freetype and (libsdl2-ttf) to run.
Here's a link to the linux build.

Got access to the source, because he's my father! Hi dad.


^ Compiled on a Mother VM and it's working. He needs food, money and love to run.
Hey son!

abnercoimbre
I like this thread :-)


Abner! I got motivated by watching your text-editor video series. You made things look easy and then I discovered they're not XD
I also made sure to name the "caret" as "cursor" (those who have watched the series will get the pun :p)
This is awesome! Honestly, it was somewhere between six months and a year before I attempted the first undo/redo in 4coder. It seems you have a great handle on what you're doing and are moving along at a great pace!

I demand ongoing screenshots to motivate me not to fall behind and so that I can steal your best ideas :D

I'm joking, kind of, I do hope you keep this up and keep sharing progress! I'm going to try to check it out for real later today.
Allen thank you so much for the kind words! Without exaggeration, you've made one of the best pieces of software I've seen in years. Fast, efficient and a joy to use. Mine is just a hobbyist's adventure that tries to look like, but could never function like 4coder.

I'm hoping to fix the serious issues, add a couple of features and then release the source. Maybe then, any experienced members of the community can turn it into something useful.
Reworked the clipboard system. It seems to produce correct results, although paste is still too slow.
Also added some basic mouse scrolling.

Updated link is on the first post.