Shop OBEX P1 Docs P2 Docs Learn Events
Terminal Text Editor on the Propeller in C/C++ — Parallax Forums

Terminal Text Editor on the Propeller in C/C++

DavidZemonDavidZemon Posts: 2,973
edited 2016-04-16 14:21 in Propeller 1
I believe a few languages on the Propeller have text editors available, but C/C++ is not one of them. It's something I've wanted to do for quite some time but never bothered researching enough to figure it out for myself.

The time has come; I'm going to give it a shot.

I don't really know where to start, but I think the two largest problems will be memory usage and character insertion delays.

I've found a potentially helpful article here: http://electronics.stackexchange.com/questions/53823/text-editing-memory-management. It mentions an external memory module, but I'd love to see an implementation that can be run on the Quickstart - without SD card or SRAM - so I'll be creating this with the goal of a configurable editor, capable of running on a Quickstart as well as utilizing larger amounts of memory when possible.

Any suggestions are more than welcome! Pointers to existing text editors on a microcontroller would be much appreciated as well.

Progress will be track in this thread and this GitHub issue for PropWare.
Commits will go to the feature/26 branch.
«1

Comments

  • My first question should be: does the built-in terminal in propeller-load support all of the control characters that will be needed by a basic text editor? I'm not sure what all control characters I'll need, so perhaps a better question would be: what control characters does propeller-load not support? Once that list is built, I can cross-reference it later as needed.
  • Does propeller-load support determine the height and width of the terminal?
  • DavidZemon wrote: »
    Does propeller-load support determine the height and width of the terminal?
    The built-in terminal mode in propeller-load only supports whatever the Windows command prompt window supports or whatever platform you're running on. It doesn't do anything at all with control characters.

  • What about the arrow keys? Any time I press one of the arrow keys, it exits terminal mode. Can that be disabled via a command-line switch?
  • If not, I'm thinking a vi-style interface might work best so as to avoid needing the arrow keys.
  • ElectrodudeElectrodude Posts: 1,657
    edited 2016-04-16 02:15
    A vi-interface probably won't fix your arrow-key-closing-the-connection problems. Arrow keys are encoded in terminals as escape sequences (e.g. up is "^[[A", where "^[" is escape). If arrow keys are closing your connection, the escape key probably will also. And escape is probably the most important key in vi.


    Open a terminal and run "cat". Then push arrow keys and escape and function keys and such and see what you get. Note that there will be a ~1 second delay after pushing the escape key, because the terminal is unsure if the escape it just got was a real escape or just part of an escape sequence.

    Then, hit ^D or ^C to quit cat, and then type escape, [, A. You'll see that it has the same effect as pressing the up arrow key. Try typing other things you got while in cat (except type escape instead of ^[ ), and it'll have the same effect. You need to do the whole sequence within a second or so for it to work.



    Text editors usually store the file being edited as an array or linked list of lines. That way, if you insert a character in the middle of the file, only the rest of that line needs to be shifted over.
  • Hm... form feed isn't working. How do you write a text editor without form feed, and without knowing exactly how large the terminal is?
  • ElectrodudeElectrodude Posts: 1,657
    edited 2016-04-17 02:36
    Why don't you try a real terminal emulator instead of propeller-load's terminal mode? (nevermind, there's apparently no difference, propeller-load's terminal mode is just pass-through)

    Have you tried seeing if there's an ANSI escape sequence for form feed, and trying that instead?
  • I have not. I'll look into it, thanks
  • Looks like I might have some luck after reading this wiki article
    https://en.m.wikipedia.org/wiki/ANSI_escape_code
  • A text editor doesn't (necessarily) have to be full screen -- early Basic's, for example, had a very simple line editor and organized the input based on explicit line numbers. There's also edlin, or Unix's ed.

    (A full screen editor would be fantastic, of course, but we're also dealing with a very tiny memory space,)
  • David, this is a very interesting project, I always wanted to have a text editor on the propeller (something like the C64 editor would be wonderful) but never found the time to start looking into it.

    I wrote the full screen text editor using ANSI/VT-100 escape sequences a very long time ago for my Fidonet BBS project and more recently attempted to rewrite it in C++ but never finished it, I'm attaching the source code in the hope it is useful to you. I wasn't touching it for quite a while but should work decently well, I remember an insidious bug that loses the correct text insertion pointer and never fixed it. The editor was tested on linux only and should work on the linux terminal or any ANSI/VT-100 terminal emulator, supports colors and arrow keys, the text is built in a string variable with '\r' as line separator. There are classes that helps to deal with the input/output interface, terminal is what abstracts the i/o and provides a standard interface, it converts commands to ANSI sequences.

    Hope this helps, and feel free to ask, it was quite a long time since I worked with terminal emulations but should remember how they works.

    For the curious, the AVATAR emulation handled by the terminal is this http://ftsc.org/docs/fsc-0025.001
  • kwinnkwinn Posts: 8,697
    ersmith wrote: »
    A text editor doesn't (necessarily) have to be full screen -- early Basic's, for example, had a very simple line editor and organized the input based on explicit line numbers. There's also edlin, or Unix's ed.

    (A full screen editor would be fantastic, of course, but we're also dealing with a very tiny memory space,)

    My first microcomputer (8080, 16K ram, 2 88KB fdd) ran CPM and a full screen text editor (Magic Wand iirc) so it is doable in a small memory space. SD cards are also much faster than those early 5.25" floppy drives, so that can be used to deal with some of the problems a small memory space creates.
  • Using the the escape sequence to clear the screen worked wonderfully. For the moment, I'm using asdw and hjkl for cursor movement. So to calibrate your screen size, you simply move the cursor to the bottom-right of your terminal and then press enter.

    After that, I like the idea of storing data as lines in memory, and I have a dynamically allocated StringBuilder class which I can use as an easy-access buffer. Avoiding dynamic memory allocation would be great, but it's already included in the FatFS class, so I had to give up that dream real quick.

    So, once I have a basic, scrollable file viewer ("less" style), I'll move into the editor space.

    GitHub link coming soon - need to work out a small kink in the calibration first.
  • DavidZemon wrote: »
    What about the arrow keys? Any time I press one of the arrow keys, it exits terminal mode. Can that be disabled via a command-line switch?
    The ESC key causes an exit from terminal mode. All of the function keys generate escape sequences so I guess any will cause terminal mode to exit. There is no way to avoid that currently. I suggest you use an actual terminal emulator like TeraTerm.

  • David Betz wrote: »
    DavidZemon wrote: »
    What about the arrow keys? Any time I press one of the arrow keys, it exits terminal mode. Can that be disabled via a command-line switch?
    The ESC key causes an exit from terminal mode. All of the function keys generate escape sequences so I guess any will cause terminal mode to exit. There is no way to avoid that currently. I suggest you use an actual terminal emulator like TeraTerm.

    Good to know. I'll stick with propeller-load until I get to the editing a file. For the viewing aspect, asdw and hjkl are working fine.
  • First code is in the feature/26 branch:
    https://github.com/parallaxinc/PropWare/tree/feature/26
  • Alright, basic viewing features are complete. Shortcuts "g" and "G" are implemented for jumping to the beginning and end of the file - I'm working on "0" and "$" for the start and end of a line now.

    Next up is fixing a usability quirk when moving the cursor up and down at the end of lines that have different lengths. Once that is fixed, I'll start working on edit features I think.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2016-04-17 21:33
    Oh, I forgot to mention, the main file is Examples/PropWare_PWEdit/PWEdit_Demo.cpp and I've attached an elf and .binary file in the next post.

    The demo is hardcoded to search for a file named "small.txt" in the root directory of partition 0 of a FAT16/FAT32 SD card mounted on MOSI=24,MISO=22,SCLK=23,CS=25 (ActivityBoard pinout).
  • Elf & Binary in this zip:
  • The code looks pretty nice (I can't actually test it because I don't have a working SD at the moment).

    I wonder if there's a Propeller standard for a filesystem in EEPROM? A lot of boards do have 64K EEPROMs so there's a small amount of room for storing things, and it would be handy to have a standard for accessing that.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2016-04-18 15:30
    ersmith wrote: »
    The code looks pretty nice (I can't actually test it because I don't have a working SD at the moment).

    I wonder if there's a Propeller standard for a filesystem in EEPROM? A lot of boards do have 64K EEPROMs so there's a small amount of room for storing things, and it would be handy to have a standard for accessing that.

    Once I can write files to SD, I plan to create FileReader and FileWriter classes with an EEPROM backing. It'd be great to find an existing standard for an EEPROM filesystem, but I haven't seen one yet (nor have I looked).

    I never thought of it until you mentioned it with relation to your new interpreters. It'll be great there!
  • Do you have a feel yet as to whether you'll be able to fit your editor and an interpreter and still have a reasonable amount of space for user code?
  • David Betz wrote: »
    Do you have a feel yet as to whether you'll be able to fit your editor and an interpreter and still have a reasonable amount of space for user code?

    Right now, code + data size is around 18k, and that's with CMM even. If you're writing a reallllyyyy small file, then sure, lots of room :)

    I'm afraid this is likely reserved for XMM models :(. But, perhaps the EEPROM version will be much lighter weight. I think the SD/FAT routines are about 12k of the total size.
  • This is the exact problem I had with my ebasic interpreter. I could fit a simple line editor and the interpreter into hub memory in CMM mode with a little space for a user program but once I added filesystem save/restore, I pretty much ran out of space. I'm sure it would have been much worse if I had tried doing a screen editor like you've done. I didn't do much with ebasic after that since it seems almost no one uses XMM or even has a board to support it. One disappointing thing is that you don't really get much additional code space going from CMM to XMM-EEPROM with a 64K EEPROM because all XMM code is essentially LMM code and takes up a lot more space than CMM. It would be nice to have an XCMM mode but that would have its own problems. I really wish XMMC with an externa SPI flash chip had been better accepted. The only board that Parallax makes that supports it is the C3 and that is being discontinued.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2016-04-19 03:47
    'Tis a real problem indeed.

    I've just added the FileWriter code in, which means that the total code size won't grow much more between now and when it has at least a basic but complete set of features. It is sitting at 21,800 bytes. (Note: it is 23,212 as shown in GitHub - to get 21,800, I removed the HD44780 debugger.)

    There is one rather... uh.... glaring bug that I haven't dealt with yet. An empty line will cause undefined behavior. I realized my test file doesn't have any empty lines so this isn't something I bothered coding for yet :P.

    The framework for a basic vim-style command prompt has been dropped in place. Right now, all that is supported is ":w", ":wq", ":q" and ":q!". The following keys are also available in "normal" mode:

    a/h = Move cursor left
    s/j = Move cursor down
    d/l = Move cursor right
    w/k = Move cursor up
    0 = To line start
    $ = To line end
    g = To file start
    G = To file end

    All that's left for this very basic editor is fixing the empty line bug, and implementing the "insert mode" which shouldn't be hard since I took Electrodude's suggestion and used a doubly linked list (std::list actually) for the in-memory file buffer.

    I am hopeful that the finished product will be around 22-22.5 kB.
  • I've lost track of what is in that ~22k bytes. Does that include an interpreter? Which one?
  • David Betz wrote: »
    I've lost track of what is in that ~22k bytes. Does that include an interpreter? Which one?

    No :(

    But again, implementing a super simple eeprom filesystem should get another ~15k back I think
  • DavidZemon wrote: »
    David Betz wrote: »
    I've lost track of what is in that ~22k bytes. Does that include an interpreter? Which one?

    No :(

    But again, implementing a super simple eeprom filesystem should get another ~15k back I think
    That's probably true. Maybe I should try that with ebasic as well. Have you found code for a simple EEPROM filesystem or are you going to roll your own?

  • David Betz wrote: »
    DavidZemon wrote: »
    David Betz wrote: »
    I've lost track of what is in that ~22k bytes. Does that include an interpreter? Which one?

    No :(

    But again, implementing a super simple eeprom filesystem should get another ~15k back I think
    That's probably true. Maybe I should try that with ebasic as well. Have you found code for a simple EEPROM filesystem or are you going to roll your own?

    Haven't started looking yet. I'll do a short look, but not hopeful that I'll find anything. For the sake of space, it will probably be extremely simple. I'm thinking no filesystem to start with - just a file with the 32k address hardcoded as the first address, and maybe a 4-byte header for the size and that's it. No name, just a start address of 32k and a 4-byte header. Should make for very small code size.
Sign In or Register to comment.