~luxferre/nne

aa8b5d3ee175189d750a4dbf5104c8471abae590 — luxferre 7 months ago 1aeace3
Implemented help screen
2 files changed, 53 insertions(+), 4 deletions(-)

M README.md
M nne.c
M README.md => README.md +2 -1
@@ 112,6 112,7 @@ Cut lines    |`mod D [number] Return`  |Cut N lines (starting from current row) 
Paste        |`mod p` or `mod v`       |Paste the line(s) from the clipboard into the current position
Undo (pseudo)|`mod u`                  |Discard all unsaved changes and reload the file contents
Shell command|`mod e [command] Return` |Save current file, run an external shell command and reopen the file
Help         |`mod h`                  |Displays on-screen help (press Return to get back to normal mode)

## FAQ



@@ 119,7 120,7 @@ Shell command|`mod e [command] Return` |Save current file, run an external shell

Well, there are several reasons why nne was created:

1. **Minimum overhead**. A text editor is the most important tool on every system, and it's crucial that it does not itself get in the way in terms of resource consumption. Most well-known and established text editors, however, are already bloated beyond repair, up to the point that x86_64 static builds of Vim and Vis against musl libc are sized 3433600 and 644288 bytes respectively. And these are only two examples. On top of that, their codebase already is so large that it cannot be easily (or at all) maintained by a single person. On the contrary, nne weighs around 68k bytes when statically linked with musl, and the sub-1000 SLOC limit (that actually turned out to be sub-750) makes it easy to comprehend by anyone familiar with ANSI C whoever will be reading its source code.
1. **Minimum overhead**. A text editor is the most important tool on every system, and it's crucial that it does not itself get in the way in terms of resource consumption. Most well-known and established text editors, however, are already bloated beyond repair, up to the point that x86_64 static builds of Vim and Vis against musl libc are sized 3433600 and 644288 bytes respectively. And these are only two examples. On top of that, their codebase already is so large that it cannot be easily (or at all) maintained by a single person. On the contrary, nne weighs around 68k bytes when statically linked with musl, and the sub-1000 SLOC limit (that actually turned out to be sub-770) makes it easy to comprehend by anyone familiar with ANSI C whoever will be reading its source code.
2. **Maximum portability**. This editor is designed to be source-compatible with any POSIX environment and with any architecture a POSIX environment can run on. There is no OS-specific code and no external dependencies. You don't need to find or build any libtermkey, terminfo, ncurses and other nonsense for the target architecture you want to compile nne for. It also doesn't require a specific build system: just a simple command line to compile a single file. By the way, it also doesn't contain any compiler-specific quirks: any C89-compatible compiler can build nne binary in a POSIX environment (GCC, Clang, zig cc, tcc).
3. **Maximum freedom**. Public domain deserves a decent lightweight text editor, just like it deserves SQLite, oksh and pdpmake. Besides mg (whose portability is questionable as of now), vce (that can't into UTF-8) and ue (that is straight up unusable on modern terminals), there were no notable text editors released into public domain.


M nne.c => nne.c +51 -3
@@ 24,7 24,7 @@
#define NNE_CSZ sizeof(uint) /* single text character internal size */
/* max amount of chars to be input/output on prompts/statuses */
#ifndef NNE_IOBUFSZ
#define NNE_IOBUFSZ 1000 
#define NNE_IOBUFSZ 2000 
#endif
#ifndef NNE_TABWIDTH
#define NNE_TABWIDTH 2


@@ 84,6 84,49 @@ static uint nne_scr_row; /* current wrapped cursor vertical position */
static uint nne_buflines; /* amount of lines loaded into the buffer */
static int  nne_line_offset = 0; /* offset from the start to the screen */

/* help screen */

static char* nne_help_screen = "\x1b[s\
---------------------------- nne shortcut help ---------------------------\
\x1b[1B\x1b[74D\
|                                                                        |\
\x1b[1B\x1b[74D\
|Save       Esc Esc s, Esc Esc w     Line jump    Esc Esc l [num] Return |\
\x1b[1B\x1b[74D\
|Quit       Esc Esc q                Brace match  Esc Esc 5              |\
\x1b[1B\x1b[74D\
|Tab char   Esc Esc Tab              Find text    Esc Esc / [text] Return|\
\x1b[1B\x1b[74D\
|Delete     Del,  Esc Esc Bksp       Copy line    Esc Esc y              |\
\x1b[1B\x1b[74D\
|Page Up    PgUp, Esc Esc Up         Copy lines   Esc Esc Y [num] Return |\
\x1b[1B\x1b[74D\
|Page Down  PgDn, Esc Esc Down       Cut line     Esc Esc d              |\
\x1b[1B\x1b[74D\
|Home       Home, Esc Esc 0          Cut lines    Esc Esc D [num] Return |\
\x1b[1B\x1b[74D\
|End        End,  Esc Esc 4          Paste        Esc Esc p, Esc Esc v   |\
\x1b[1B\x1b[74D\
|Next word  Esc Esc Right            Discard/undo Esc Esc u              |\
\x1b[1B\x1b[74D\
|Prev word  Esc Esc Left             Run shell    Esc Esc e [cmd] Return |\
\x1b[1B\x1b[74D\
|File start Esc Esc 8                This help    Esc Esc h              |\
\x1b[1B\x1b[74D\
|File end   Esc Esc 9                                                    |\
\x1b[1B\x1b[74D\
|                                                                        |\
\x1b[1B\x1b[74D\
|                      Created by Luxferre in 2023                       |\
\x1b[1B\x1b[74D\
|                      Released into public domain                       |\
\x1b[1B\x1b[74D\
|                                                                        |\
\x1b[1B\x1b[74D\
|                    Press Return to exit this screen                    |\
\x1b[1B\x1b[74D\
--------------------------------------------------------------------------\x1b[u";

/* elementary routines */ 

/* generic routines to output string constants */


@@ 474,10 517,10 @@ void render() { /* main screen rendering function */
    scrbuf_append(nne_msgbuf);
    nne_status_override = 0;
  }
  else scrbuf_append(nnmsg(0, CURSET "%c %s %u,%u %02u%% %ux%u", nne_termh, 1,
  else scrbuf_append(nnmsg(0, CURSET "%c %s %u,%u %02u%% %ux%u | %s", nne_termh, 1,
    (nne_mode == NNE_CMD) ? 'C' : '-', nne_fname, nne_row, nne_col,
    (100*nne_pos/(nne_real_len <= 2 ? 2 : nne_real_len - 2)),
    nne_termw, nne_termh));
    nne_termw, nne_termh, "Press Esc Esc h to get help"));
  scrbuf_append(nnmsg(0, CURSET CURSHOW "\0", nne_scry, nne_scrx));
  /* actually draw the screen buffer until the first zero byte */
  nnputs(nne_scrbuf);


@@ 750,6 793,11 @@ int nne_action(int key) {
      case K_DOWN: motion_pgdn(); break;
      case K_BACKSPACE: motion_del(); break;
      case '\t': nne_inschar('\t'); break; /* insert literal tab */
      case 'h': /* help screen */
        nnmsg(1, CURSET "%s", (nne_termh >> 1) - 10, (nne_termw >> 1) - 37,
          nne_help_screen);
        r = nne_prompt(""); /* pause editing, wait for Return key */
        break;
    }
    nne_mode = NNE_NORMAL; /* exit the modcommand mode afterwards */
  }