@87flowers@mk.absturztau.be I use my own text editor, and what I use is simply two buffers, the first stores everything before the cursor, and the second stores everything after the cursor /but mirrored in reverse/. For example, assuming | is where the cursor is at, to represent the following file:

Hello,_|World!\n

Buf1 would contain:

Hello,_\0 -- *buf1_end
^
|
*buf1

And Buf2 would contain:

\n!dlroW\0 -- *buf2_end
^
|
*buf2

All navigation becomes a simple act of copying chars and then moving the \0 end marker. Wrote a couple of low-level functions to abstract this away, and my entire editor now deals in next_line(), prev_line(), goto_line(int num), and goto_start_of_file(), etc. Never had any performance issues at all, everything is super snappy, on a decade old thinkpad, even editing files as big as 50MiBs.