summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Bini <rev@alienbuntu.local>2021-05-06 06:42:54 (GMT)
committerMichele Bini <rev@alienbuntu.local>2021-05-06 08:50:12 (GMT)
commit7612b22db5977d6e36f185a2de5cfe1424178879 (patch)
tree39e4b16d8f600c3b86ac3bd1cbea4c317250d1c2
parenta9988a219f53c8b7a1029dc0f2e98c59f84f3964 (diff)
Added features: DEVTTY, STDIO
-rw-r--r--nanobox.c146
1 files changed, 134 insertions, 12 deletions
diff --git a/nanobox.c b/nanobox.c
index cd83a20..3847965 100644
--- a/nanobox.c
+++ b/nanobox.c
@@ -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)