Author Topic: Anyone know how to make a good text UNDO function?  (Read 3004 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Anyone know how to make a good text UNDO function?
« on: January 25, 2021, 12:41:04 pm »
Rob put together a great one for the QB64 IDE. You can undo every keystroke and edits like cut/copy/paste. In my WP app, I have made a keylogger,  so one idea is to ref that for the undo stuff. It's a bit complicated, as algorithms would need to be made for backspace and delete, not so difficult, but cut/copy/paste seems like it would be a bear to calculate. I've seen plenty of apps, like Notepad, that offer only a single undo event. So if you paste something, you can undo it, but not whatever else you did before the paste. I might just go in that direction, for simplicity sake.

Edit: I probably should stress that IDE editors don't wrap text, so maybe an IDE editor undo method might not be suitable for a text editor. Also, I use arrays to keep track of each line of text.

Any ideas?

Pete
« Last Edit: January 25, 2021, 12:44:36 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #1 on: January 25, 2021, 12:51:33 pm »
My idea for Undo for WP is to make copy of text at every keystroke. Undo just pulls the last copy made... so you can make undo go back as far as last save? Storage and time might be problem, exhaust RAM memory or use temp files to store text versions.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #2 on: January 25, 2021, 01:24:52 pm »
That crossed my mind, too. As we both see, yes, what a memory hog that would be. I would think in a large doc printed on a narrow page, that might mean looping through 100,000 arrays every time a key is pressed. I would think the performance of the key repeat rate would slow up way too much to take that approach, as well as the memory usage. For instance, let's say we took this approach for just 1 given line of text needing one multidimsional array...

do
i = i + 1
REDIM _PRESERVE x$(1, i)
x$(1, i) = INKEY$
loop

Now with each undo... i = i  - 1 and clear and reprint the screen with the previous array. It works in theory, but even with one line and say 80 characters across, we 1 + 2 + ...80  so 80*(1+80) / 2 = 3.24 KB for just one line of undo text!

Using disk storage with binary seems like it might be an alternative, maybe with indexing to create a single file for the whole undo process... instead of thousands of temporary files, which would be a joke. Now I'm wondering if Rob did exactly that?

Thanks for the reply. I love brainstorming things out,

Pete

Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Anyone know how to make a good text UNDO function?
« Reply #3 on: January 25, 2021, 01:37:25 pm »
Quick question: How large are the files you’re going to be working with?

For small files, I’d just do save files.  For example, each time you hit ENTER, your program saves a file in a temp directory, with a number to it.  Write a 100 line program, you have 100 text files saved.  Hit CTRL-Z, you just load file #99 and go with it.  Hit CTRL-Z again, just load file #98.  The idea is you can undo the last line of action.  (Or word, if I want to save on spaces as well.)

Even large files can use such a method (after all, what’s the largest BAS file you’ve ever seen?  10 MB source code?) — just set a limit to the max number of files you save.  (Set a 100 MB limit, and you can undo the last 10 actions of even a 10 MB file.)

Believe it or not, this is basically how QB64 does things.  Look in config.txt, and you’ll see that it comes with a 100MB undo file size, by default.  It’s simple, and it’s a surefire way to be able to undo and redo your actions, without fail.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #4 on: January 25, 2021, 01:55:35 pm »
More like 100,000 lines+. This is why I'm batting ideas around before I put too much time and effort int something I just pitch in the end.

I thought about the single line method, as you mentioned, but a problem with a WP you don't get with a code editor is wrap. Wrap requires you keep every changed line, not just the line you are working on. That makes many of those temp files multiple lines.

As is, I probably will need temp files for the undo cut/paste stuff, which I could use with some sort of reverse keylogger routine. I also need to focus on a REDO feature at the same time I consider these methods.

Usually when I find myself in these situations I build a life in miniature model to see if letting grow up is worth the parenting skills that will go into it. And no jokes about, "Hey look, another one of Pete's special needs programs."

Thanks for the info, and insight as to how it's done in the QB IDE. I have a lot to consider, before moving forward on this.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #5 on: January 25, 2021, 02:18:59 pm »
Quote
More like 100,000 lines+

Might look into STx linked list method and Editor for that.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #6 on: January 25, 2021, 02:29:57 pm »
Ugh, you just caught me. Ya know, I had a response to this half-typed that made an attempt to not use linked lists, but deleted it for its futility, and then moved on hoping bplus would just "have an answer" of some kind. That was 5 minutes ago.

Code with an "undo" feature, or anything like it, needs access to a "third dimension". Files are a brute force way to do this, and will work, but will probably gonna kill your hard drive one day. Lists let you abstract away what is touching what, so things that are "deleted" are really just put into another list, remembering where they came from.

Emphasis on "remembering where they came from". I'm willing to bet Pete treats the text in one big, master array, where the way the text is stored is ultimately mixed with the way it is displayed. Without calling it the wrong answer, it fails to separate the mechanism of storage and editing, form the mechanism of plotting (something with word wrapping that cares where the cursor is). It's literally as hard as editing the text in a book that's already printed.

So how to bail this out? One way is hidden characters. When you delete a character, wrap it in braces, and put a little small number in the braces along with the character. Same goes for adding text: braces (maybe a different kind), and a number.

Of course, your display routines (that decides on wrapping) must ignore the actual braces, and if they correspond to deleted content, ignore the content too.

Typing text, or pasting big chunks follow the same model. Whatever is added, put something around it, with a number.

The index numbers might have to managed, perhaps incremented or decremented as a "fleet", to keep FIFO working (this number should not be infinite). Pick 1000 or something. After the text is "old" enough, it loses the braces and is flattened.

Anyway, I'm doing a bad job explaining this because its a bad idea.

Is it too late to start over?


« Last Edit: January 25, 2021, 02:38:26 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #7 on: January 25, 2021, 02:57:01 pm »
Bill, haven't you heard, "There is  no such thing as a bad idea, just..." Oh wait, you just proved that old saying wrong. Dammit, now on top of all they other work I have to do, I have to go look up another old saying.

I use an array for each line of text. The array keeps track of a paragraph symbol, and adds a CHR$(10) past the printable text field.

While indexing in the text itself would require a ton of re-write work, working with a temp file would only require applying the proper indexing to the temporary file(s).

Pete

Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #8 on: January 25, 2021, 03:22:59 pm »
Depends on how fast you want to fry your drive. They call brute force "brute" for a reason.
You're not done when it works, you're done when it's right.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Anyone know how to make a good text UNDO function?
« Reply #9 on: January 25, 2021, 03:47:58 pm »
Depends on how fast you want to fry your drive. They call brute force "brute" for a reason.

Two easy ways around this:

1) Simply use a RAM Drive.  Speedy and no wear on hardware.

2) Use a _MEMBLOCK or string to hold the information internally.  You might have a program that uses a few hundred MB of memory, but in today’s world of new PC’s, that’s hardly a concern.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #10 on: January 25, 2021, 03:50:40 pm »
Quote
Simply use a RAM Drive.  Speedy and no wear on hardware.

I've always kinda liked that ^ idea. Pete this is your solution if you get to set up the drives on every computer this product runs on. Are you planning to distribute it?
« Last Edit: January 25, 2021, 03:55:26 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Anyone know how to make a good text UNDO function?
« Reply #11 on: January 25, 2021, 04:09:15 pm »
I've been posting updates on this project at my forum. Bob said he liked what I had so far, better than Notepad. Of course at the current stage, it doesn't have the full features yet. I've made a few WPs for my own personal uses within my programs, and a few less involved ones for fun. This one feels like it might be something others could use at some point, so I would rather it be plug and play, rather than it only works, if... So the addition of a RAM drive is nix. Other products, like Open Office (wherever that thing went???) Word, etc., seem to work fine for very large docs, without the need of a RAM drive addition.

As for the _MEMBLOCK stuff, I considered that as a possible use. I made a graphics GUI that mapped a lot of stuff to memory, but I made that memory mapping myself. I've never worked with the _MEMBLOCK feature(s) yet, so I'd have to mess around with some rudimentary stuff, to figure it out and apply it.

I think one of the main goals of any good usable text writer is its ability to keep up with the user. If you can out type the product, it wasn't put together well enough to be of any practical use. Rob hit this wall once in the QB IDE, and then between faster computers and tweaks in his coding method, it got back on track to keeping up with user input. On a side note, I really wish he used the scrollbar routine I emailed him. It's was better than what we have, even currently, well, as current as v1.3. I haven't checked the latest, yet.

In the meantime, while considering what to do about undo, I'm working out the directory tree stuff. I just posted something Dav might find useful, for a similar project he is working on.

Hey guys, just to let you know, I really, really appreciate all the comments, suggestions, and ideas.

Thanks,

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/