diff options
| author | Michele Bini <rev@alienbuntu.local> | 2021-05-06 06:42:54 (GMT) |
|---|---|---|
| committer | Michele Bini <rev@alienbuntu.local> | 2021-05-06 08:50:12 (GMT) |
| commit | 7612b22db5977d6e36f185a2de5cfe1424178879 (patch) | |
| tree | 39e4b16d8f600c3b86ac3bd1cbea4c317250d1c2 | |
| parent | a9988a219f53c8b7a1029dc0f2e98c59f84f3964 (diff) | |
Added features: DEVTTY, STDIO
| -rw-r--r-- | nanobox.c | 146 |
1 files changed, 134 insertions, 12 deletions
@@ -170,7 +170,7 @@ //config: Unless you want more (or less) frequent "undo points" while typing, //config: you should probably leave this unchanged. //config: -#define ENABLE_FEATURE_NANO_INDENT_SENSITIVE 1 +// #define ENABLE_FEATURE_NANO_INDENT_SENSITIVE 1 //config:config FEATURE_NANO_INDENT_SENSITIVE //config: bool "Make common operations indent-sensitive" //config: default y @@ -179,6 +179,16 @@ //config: This option makes the HOME and RETURN key behave differently //config: depending on the current indentation level. //config: +#define ENABLE_FEATURE_NANO_DEVTTY 1 +#define ENABLE_FEATURE_NANO_STDIO 1 +//config:config FEATURE_NANO_STDIO_C +//config: bool "Support -c flag for operating on standard input/output" +//config: default y +//config: depends on NANO, NANO_DEVTTY +//config: help +//config: Support -c flags for reading a file on standard input, and +//config: writing it back on standard output. +//config: // #define ENABLE_FEATURE_NANO_FOLDING 1 //config:config FEATURE_NANO_FOLDING //config: bool "Support code folding" @@ -621,6 +631,9 @@ static void catch_sig(int); // catch ctrl-C and alarm time-outs #if ENABLE_FEATURE_NANO_SETOPTS static void showmatching(char *); // show the matching pair () [] {} #endif +#if ENABLE_FEATURE_NANO_STDIO +int nano_stdio_mode = 0; +#endif #if ENABLE_FEATURE_NANO_YANKMARK || ENABLE_FEATURE_NANO_SEARCH || ENABLE_FEATURE_NANO_CRASHME // might reallocate text[]! use p += string_insert(p, ...), // and be careful to not use pointers into potentially freed text[]! @@ -657,9 +670,19 @@ static int crashme = 0; #if ENABLE_FEATURE_NANO_HIGHLIGHT #endif +#if ENABLE_FEATURE_NANO_DEVTTY +FILE *devtty; +int nano_stdin_fd; +# define NANO_STDOUT devtty +# define NANO_STDIN_FD nano_stdin_fd +#else +# define NANO_STDOUT stdout +# define NANO_STDIN_FD STDIN_FILENO +#endif + static void write1(const char *out) { - fputs(out, stdout); + fputs(out, NANO_STDOUT); } int main(int argc, char **argv) @@ -694,7 +717,7 @@ int main(int argc, char **argv) // 1- process $HOME/.exrc file (not inplemented yet) // 2- process EXINIT variable from environment // 3- process command line args - while ((c = getopt(argc, argv, "hCRH")) != -1) { + while ((c = getopt(argc, argv, "hcCRH")) != -1) { switch (c) { #if ENABLE_FEATURE_NANO_CRASHME case 'C': @@ -706,6 +729,11 @@ int main(int argc, char **argv) SET_READONLY_MODE(readonly_mode); break; #endif +#if ENABLE_FEATURE_NANO_STDIO + case 'c': + nano_stdio_mode = 1; + break; +#endif case 'H': show_help(); /* fall through */ @@ -716,6 +744,7 @@ int main(int argc, char **argv) } // The argv array can be used by the ":next" and ":rewind" commands + // FIXME: this functionality could be made optional (multi-file editing) and is currently not accessible anyway! argv += optind; argc -= optind; @@ -723,12 +752,24 @@ int main(int argc, char **argv) save_argc = argc; optind = 0; // "Save cursor, use alternate screen buffer, clear screen" +#if ENABLE_FEATURE_NANO_DEVTTY + devtty = fopen("/dev/tty", "a+"); + nano_stdin_fd = fileno(devtty); +#endif +#if ENABLE_FEATURE_NANO_STDIO + if (nano_stdio_mode) { + edit_file(NULL); + } else { +#endif write1("\033[?1049h"); while (1) { edit_file(argv[optind]); /* param might be NULL */ if (++optind >= argc) break; } +#if ENABLE_FEATURE_NANO_STDIO + } +#endif // "Use normal screen buffer, restore cursor" write1("\033[?1049l"); //----------------------------------------------------------- @@ -747,10 +788,16 @@ static int init_text_buffer(char *fn) text_size = 10240; screenbegin = dot = end = text = xzalloc(text_size); +#if ENABLE_FEATURE_NANO_STDIO + if (!nano_stdio_mode) { +#endif if (fn != current_filename) { free(current_filename); current_filename = xstrdup(fn); } +#if ENABLE_FEATURE_NANO_STDIO + } +#endif rc = file_insert(fn, text, 1); if (rc < 0) { // file doesnt exist. Start empty buf with dummy line @@ -770,7 +817,7 @@ static int init_text_buffer(char *fn) #if ENABLE_FEATURE_NANO_WIN_RESIZE static int query_screen_dimensions(void) { - int err = get_terminal_width_height(STDIN_FILENO, &columns, &rows); + int err = get_terminal_width_height(NANO_STDIN_FD, &columns, &rows); if (rows > MAX_SCR_ROWS) rows = MAX_SCR_ROWS; if (columns > MAX_SCR_COLS) @@ -801,7 +848,7 @@ static void edit_file(char *fn) uint64_t k; write1("\033[999;999H" "\033[6n"); fflush(NULL); - k = read_key(STDIN_FILENO, readbuffer, /*timeout_ms:*/ 100); + k = read_key(NANO_STDIN_FD, readbuffer, /*timeout_ms:*/ 100); if ((int32_t)k == KEYCODE_CURSOR_POS) { uint32_t rc = (k >> 32); columns = (rc & 0x7fff); @@ -1905,7 +1952,7 @@ static char *text_yank(char *p, char *q) // copy text into a register static void rawmode(void) { // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals - set_termios_to_raw(STDIN_FILENO, &term_orig, TERMIOS_RAW_CRNL); + set_termios_to_raw(NANO_STDIN_FD, &term_orig, TERMIOS_RAW_CRNL); erase_char = term_orig.c_cc[VERASE]; } @@ -1970,7 +2017,7 @@ static int mysleep(int hund) // sleep for 'hund' 1/100 seconds or stdin ready if (hund != 0) fflush(NULL); - pfd[0].fd = STDIN_FILENO; + pfd[0].fd = NANO_STDIN_FD; pfd[0].events = POLLIN; return safe_poll(pfd, 1, hund*10) > 0; } @@ -1985,7 +2032,7 @@ static int get_one_char(void) // read (maybe cursor) key from stdin // on nonblocking stdin. // Note: read_key sets errno to 0 on success. again: - c = read_key(STDIN_FILENO, readbuffer, /*timeout:*/ -1); + c = read_key(NANO_STDIN_FD, readbuffer, /*timeout:*/ -1); if (c == -1) { // EOF/error if (errno == EAGAIN) // paranoia goto again; @@ -2084,13 +2131,33 @@ static int file_insert(const char *fn, char *p, int initial) if (p > end) p = end; +#if ENABLE_FEATURE_NANO_STDIO + if (nano_stdio_mode) { + fd = STDIN_FILENO; + } else { +#endif fd = open(fn, O_RDONLY); +#if ENABLE_FEATURE_NANO_STDIO + } +#endif + if (fd < 0) { if (!initial) status_line_bold_errno(fn); return cnt; } +#if ENABLE_FEATURE_NANO_STDIO + if (nano_stdio_mode) { + size = 0x100; + while (TRUE) { + p += text_hole_make(p, size); + cnt = full_read(fd, p, size); + if (cnt != size) break; + p += cnt; + } + } else { +#endif /* Validate file */ if (fstat(fd, &statbuf) < 0) { status_line_bold_errno(fn); @@ -2103,17 +2170,36 @@ static int file_insert(const char *fn, char *p, int initial) size = (statbuf.st_size < INT_MAX ? (int)statbuf.st_size : INT_MAX); p += text_hole_make(p, size); cnt = full_read(fd, p, size); +#if ENABLE_FEATURE_NANO_STDIO + } +#endif if (cnt < 0) { status_line_bold_errno(fn); p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert } else if (cnt < size) { // There was a partial read, shrink unused space p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO); +#if ENABLE_FEATURE_NANO_STDIO + if (!nano_stdio_mode) { +#endif status_line_bold("can't read '%s'", fn); +#if ENABLE_FEATURE_NANO_STDIO + } +#endif + } fi: +#if ENABLE_FEATURE_NANO_STDIO + if (!nano_stdio_mode) { +#endif close(fd); +#if ENABLE_FEATURE_NANO_STDIO + } +#endif +#if ENABLE_FEATURE_NANO_STDIO + if (!nano_stdio_mode) { +#endif #if ENABLE_FEATURE_NANO_READONLY if (initial && ((access(fn, W_OK) < 0) || @@ -2125,6 +2211,9 @@ static int file_insert(const char *fn, char *p, int initial) SET_READONLY_FILE(readonly_mode); } #endif +#if ENABLE_FEATURE_NANO_STDIO + } +#endif return cnt; } @@ -2132,6 +2221,11 @@ static int file_write(char *fn, char *first, char *last) { int fd, cnt, charcnt; +#if ENABLE_FEATURE_NANO_STDIO + if (nano_stdio_mode) { + fd = STDOUT_FILENO; + } else { +#endif if (fn == 0) { status_line_bold("No current filename"); return -2; @@ -2141,18 +2235,33 @@ static int file_write(char *fn, char *first, char *last) * Might reduce amount of data lost on power fail etc. */ fd = open(fn, (O_WRONLY | O_CREAT), 0666); +#if ENABLE_FEATURE_NANO_STDIO + } +#endif if (fd < 0) return -1; cnt = last - first + 1; charcnt = full_write(fd, first, cnt); +#if ENABLE_FEATURE_NANO_STDIO + if (!nano_stdio_mode) { +#endif ftruncate(fd, charcnt); +#if ENABLE_FEATURE_NANO_STDIO + } +#endif if (charcnt == cnt) { // good write //modified_count = FALSE; } else { charcnt = 0; } +#if ENABLE_FEATURE_NANO_STDIO + if (!nano_stdio_mode) { +#endif close(fd); +#if ENABLE_FEATURE_NANO_STDIO + } +#endif return charcnt; } @@ -2598,7 +2707,7 @@ static void refresh(int full_screen) memcpy(sp+cs, out_buf+cs, ce-cs+1); place_cursor(li, cs); // write line out to terminal - fwrite(&sp[cs], ce - cs + 1, 1, stdout); + fwrite(&sp[cs], ce - cs + 1, 1, NANO_STDOUT); } } @@ -2823,6 +2932,9 @@ static void do_cmd(int c) #endif break; case CTRL_CODE('O'): +#if ENABLE_FEATURE_NANO_STDIO + if (nano_stdio_mode) break; +#endif undo_queue_commit(); if (get_filename()) save_file(); break; @@ -2838,6 +2950,9 @@ static void do_cmd(int c) #endif case CTRL_CODE('X'): undo_queue_commit(); +#if ENABLE_FEATURE_NANO_STDIO + if (nano_stdio_mode) { save_file(); } else +#endif if (modified_count != 0) { go_bottom_and_clear_to_eol(); write1("Save? [y/n]"); @@ -3134,7 +3249,7 @@ static void crash_test() printf("\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s", totalcmds, last_input_char, msg, ESC_BOLD_TEXT, ESC_NORM_TEXT); fflush_all(); - while (safe_read(STDIN_FILENO, d, 1) > 0) { + while (safe_read(NANO_STDIN_FD, d, 1) > 0) { if (d[0] == '\n' || d[0] == '\r') break; } @@ -3153,6 +3268,11 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh { struct winsize win; int err; +#if ENABLE_FEATURE_NANO_STDIO + if (fd == -1) { + fd = nano_stdin_fd; + } +#else int close_me = -1; if (fd == -1) { @@ -3167,7 +3287,7 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh else close_me = fd = open("/dev/tty", O_RDONLY); } - +#endif win.ws_row = 0; win.ws_col = 0; /* I've seen ioctl returning 0, but row/col is (still?) 0. @@ -3178,8 +3298,10 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh if (width) *width = wh_helper(win.ws_col, 80, "COLUMNS", &err); +#if !ENABLE_FEATURE_NANO_STDIO if (close_me >= 0) close(close_me); +#endif return err; } @@ -3223,7 +3345,7 @@ int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags) int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) { - return tcsetattr(STDIN_FILENO, TCSANOW, tp); + return tcsetattr(NANO_STDIN_FD, TCSANOW, tp); } static int wh_helper(int value, int def_val, const char *env_name, int *err) |
