diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ex_cmds2.c | 6 | ||||
-rw-r--r-- | src/nvim/fileio.c | 30 | ||||
-rw-r--r-- | src/nvim/if_cscope.c | 17 | ||||
-rw-r--r-- | src/nvim/option.c | 96 | ||||
-rw-r--r-- | src/nvim/os/os_defs.h | 1 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 20 | ||||
-rw-r--r-- | src/nvim/tui/terminfo.c | 28 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 29 | ||||
-rw-r--r-- | src/nvim/version.c | 167 | ||||
-rw-r--r-- | src/nvim/vim.h | 3 |
10 files changed, 319 insertions, 78 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 9b8e463aee..ec4ce63e17 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -3199,8 +3199,14 @@ static char_u *get_one_sourceline(struct source_cookie *sp) ga_grow(&ga, 120); buf = (char_u *)ga.ga_data; +retry: + errno = 0; if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len, sp->fp) == NULL) { + if (errno == EINTR) { + goto retry; + } + break; } len = ga.ga_len + (int)STRLEN(buf + ga.ga_len); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index ae6c3f96e3..1f4cd22754 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -4443,22 +4443,32 @@ char *modname(const char *fname, const char *ext, bool prepend_dot) /// @return true for end-of-file. bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL { - char *eof; -#define FGETS_SIZE 200 - char tbuf[FGETS_SIZE]; + char *retval; + assert(size > 0); buf[size - 2] = NUL; - eof = fgets((char *)buf, size, fp); + + do { + errno = 0; + retval = fgets((char *)buf, size, fp); + } while (retval == NULL && errno == EINTR); + if (buf[size - 2] != NUL && buf[size - 2] != '\n') { - buf[size - 1] = NUL; /* Truncate the line */ + char tbuf[200]; - /* Now throw away the rest of the line: */ + buf[size - 1] = NUL; // Truncate the line. + + // Now throw away the rest of the line: do { - tbuf[FGETS_SIZE - 2] = NUL; - ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp); - } while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n'); + tbuf[sizeof(tbuf) - 2] = NUL; + errno = 0; + retval = fgets((char *)tbuf, sizeof(tbuf), fp); + if (retval == NULL && errno != EINTR) { + break; + } + } while (tbuf[sizeof(tbuf) - 2] != NUL && tbuf[sizeof(tbuf) - 2] != '\n'); } - return eof == NULL; + return retval ? false : feof(fp); } /// Read 2 bytes from "fd" and turn them into an int, MSB first. diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 6834e7a802..3c02f5acbd 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -553,9 +553,15 @@ static int cs_cnt_matches(size_t idx) char *buf = xmalloc(CSREAD_BUFSIZE); for (;; ) { + errno = 0; if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) { - if (feof(csinfo[idx].fr_fp)) + if (errno == EINTR) { + continue; + } + + if (feof(csinfo[idx].fr_fp)) { errno = EIO; + } cs_reading_emsg(idx); @@ -1380,9 +1386,16 @@ static char *cs_parse_results(size_t cnumber, char *buf, int bufsize, char *p; char *name; +retry: + errno = 0; if (fgets(buf, bufsize, csinfo[cnumber].fr_fp) == NULL) { - if (feof(csinfo[cnumber].fr_fp)) + if (errno == EINTR) { + goto retry; + } + + if (feof(csinfo[cnumber].fr_fp)) { errno = EIO; + } cs_reading_emsg(cnumber); diff --git a/src/nvim/option.c b/src/nvim/option.c index 65ab7a54a6..913d27d508 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -105,6 +105,9 @@ typedef enum { */ #define VAR_WIN ((char_u *)-1) +static char *p_term = NULL; +static char *p_ttytype = NULL; + /* * These are the global values for options which are also local to a buffer. * Only to be used in option.c! @@ -4530,13 +4533,17 @@ int findoption_len(const char *const arg, const size_t len) bool is_tty_option(const char *name) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - return (name[0] == 't' && name[1] == '_') || strcmp(name, "term") == 0; + return (name[0] == 't' && name[1] == '_') + || strequal(name, "term") + || strequal(name, "ttytype"); } #define TCO_BUFFER_SIZE 8 +/// @param name TUI-related option +/// @param[out,allocated] value option string value bool get_tty_option(char *name, char **value) { - if (!strcmp(name, "t_Co")) { + if (strequal(name, "t_Co")) { if (value) { if (t_colors <= 1) { *value = xstrdup(""); @@ -4548,9 +4555,16 @@ bool get_tty_option(char *name, char **value) return true; } - if (!strcmp(name, "term") || !strcmp(name, "ttytype")) { + if (strequal(name, "term")) { if (value) { - *value = xstrdup("nvim"); + *value = p_term ? xstrdup(p_term) : xstrdup("nvim"); + } + return true; + } + + if (strequal(name, "ttytype")) { + if (value) { + *value = p_ttytype ? xstrdup(p_ttytype) : xstrdup("nvim"); } return true; } @@ -4566,25 +4580,25 @@ bool get_tty_option(char *name, char **value) return false; } -bool set_tty_option(const char *name, const char *value) +bool set_tty_option(const char *name, char *value) { - if (!strcmp(name, "t_Co")) { - int colors = atoi(value); - - // Only reinitialize colors if t_Co value has really changed to - // avoid expensive reload of colorscheme if t_Co is set to the - // same value multiple times - if (colors != t_colors) { - t_colors = colors; - // We now have a different color setup, initialize it again. - init_highlight(true, false); + if (strequal(name, "term")) { + if (p_term) { + xfree(p_term); } + p_term = value; + return true; + } + if (strequal(name, "ttytype")) { + if (p_ttytype) { + xfree(p_ttytype); + } + p_ttytype = value; return true; } - return (is_tty_option(name) || !strcmp(name, "term") - || !strcmp(name, "ttytype")); + return false; } /// Find index for an option @@ -4597,21 +4611,18 @@ static int findoption(const char *const arg) return findoption_len(arg, strlen(arg)); } -/* - * Get the value for an option. - * - * Returns: - * Number or Toggle option: 1, *numval gets value. - * String option: 0, *stringval gets allocated string. - * Hidden Number or Toggle option: -1. - * hidden String option: -2. - * unknown option: -3. - */ -int -get_option_value ( +/// Gets the value for an option. +/// +/// @returns: +/// Number or Toggle option: 1, *numval gets value. +/// String option: 0, *stringval gets allocated string. +/// Hidden Number or Toggle option: -1. +/// hidden String option: -2. +/// unknown option: -3. +int get_option_value( char_u *name, long *numval, - char_u **stringval, /* NULL when only checking existence */ + char_u **stringval, ///< NULL when only checking existence int opt_flags ) { @@ -4619,32 +4630,31 @@ get_option_value ( return 0; } - int opt_idx; - char_u *varp; - - opt_idx = findoption((const char *)name); + int opt_idx = findoption((const char *)name); if (opt_idx < 0) { // Unknown option. return -3; } - varp = get_varp_scope(&(options[opt_idx]), opt_flags); + char_u *varp = get_varp_scope(&(options[opt_idx]), opt_flags); if (options[opt_idx].flags & P_STRING) { - if (varp == NULL) /* hidden option */ + if (varp == NULL) { // hidden option return -2; + } if (stringval != NULL) { *stringval = vim_strsave(*(char_u **)(varp)); } return 0; } - if (varp == NULL) /* hidden option */ + if (varp == NULL) { // hidden option return -1; - if (options[opt_idx].flags & P_NUM) + } + if (options[opt_idx].flags & P_NUM) { *numval = *(long *)varp; - else { - /* Special case: 'modified' is b_changed, but we also want to consider - * it set when 'ff' or 'fenc' changed. */ + } else { + // Special case: 'modified' is b_changed, but we also want to consider + // it set when 'ff' or 'fenc' changed. if ((int *)varp == &curbuf->b_changed) { *numval = curbufIsChanged(); } else { @@ -4791,8 +4801,8 @@ char *set_option_value(const char *const name, const long number, const char *const string, const int opt_flags) FUNC_ATTR_NONNULL_ARG(1) { - if (set_tty_option(name, string)) { - return NULL; + if (is_tty_option(name)) { + return NULL; // Fail silently; many old vimrcs set t_xx options. } int opt_idx; diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index 923a362b41..87f8d214bd 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -4,6 +4,7 @@ #include <ctype.h> #include <stdio.h> #include <stdlib.h> +#include <sys/param.h> #include <sys/stat.h> #include <sys/types.h> diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index b9228e15b9..1fc585f0c9 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -570,7 +570,12 @@ static int qf_get_next_file_line(qfstate_T *state) { size_t growbuflen; +retry: + errno = 0; if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) { + if (errno == EINTR) { + goto retry; + } return QF_END_OF_INPUT; } @@ -590,8 +595,12 @@ static int qf_get_next_file_line(qfstate_T *state) growbuflen = state->linelen; for (;;) { + errno = 0; if (fgets((char *)state->growbuf + growbuflen, (int)(state->growbufsiz - growbuflen), state->fd) == NULL) { + if (errno == EINTR) { + continue; + } break; } state->linelen = STRLEN(state->growbuf + growbuflen); @@ -612,9 +621,14 @@ static int qf_get_next_file_line(qfstate_T *state) while (discard) { // The current line is longer than LINE_MAXLEN, continue reading but // discard everything until EOL or EOF is reached. - if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL - || STRLEN(IObuff) < IOSIZE - 1 - || IObuff[IOSIZE - 1] == '\n') { + errno = 0; + if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) { + if (errno == EINTR) { + continue; + } + break; + } + if (STRLEN(IObuff) < IOSIZE - 1 || IObuff[IOSIZE - 1] == '\n') { break; } } diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index 75e9a2d8da..fdc33f0a77 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -9,6 +9,7 @@ #include <unibilium.h> #include "nvim/log.h" +#include "nvim/memory.h" #include "nvim/tui/terminfo.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -94,51 +95,72 @@ bool terminfo_is_term_family(const char *term, const char *family) /// Loads a built-in terminfo db when we (unibilium) failed to load a terminfo /// record from the environment (termcap systems, unrecognized $TERM, …). /// We do not attempt to detect xterm pretenders here. -static unibi_term *terminfo_builtin(const char *term) +/// +/// @param term $TERM value +/// @param[out,allocated] termname decided builtin 'term' name +/// @return [allocated] terminfo structure +static unibi_term *terminfo_builtin(const char *term, char **termname) { if (terminfo_is_term_family(term, "xterm")) { + *termname = xstrdup("builtin_xterm"); return unibi_from_mem((const char *)xterm_256colour_terminfo, sizeof xterm_256colour_terminfo); } else if (terminfo_is_term_family(term, "screen")) { + *termname = xstrdup("builtin_screen"); return unibi_from_mem((const char *)screen_256colour_terminfo, sizeof screen_256colour_terminfo); } else if (terminfo_is_term_family(term, "tmux")) { + *termname = xstrdup("builtin_tmux"); return unibi_from_mem((const char *)tmux_256colour_terminfo, sizeof tmux_256colour_terminfo); } else if (terminfo_is_term_family(term, "rxvt")) { + *termname = xstrdup("builtin_rxvt"); return unibi_from_mem((const char *)rxvt_256colour_terminfo, sizeof rxvt_256colour_terminfo); } else if (terminfo_is_term_family(term, "putty")) { + *termname = xstrdup("builtin_putty"); return unibi_from_mem((const char *)putty_256colour_terminfo, sizeof putty_256colour_terminfo); } else if (terminfo_is_term_family(term, "linux")) { + *termname = xstrdup("builtin_linux"); return unibi_from_mem((const char *)linux_16colour_terminfo, sizeof linux_16colour_terminfo); } else if (terminfo_is_term_family(term, "interix")) { + *termname = xstrdup("builtin_interix"); return unibi_from_mem((const char *)interix_8colour_terminfo, sizeof interix_8colour_terminfo); } else if (terminfo_is_term_family(term, "iterm") || terminfo_is_term_family(term, "iterm2") || terminfo_is_term_family(term, "iTerm.app") || terminfo_is_term_family(term, "iTerm2.app")) { + *termname = xstrdup("builtin_iterm"); return unibi_from_mem((const char *)iterm_256colour_terminfo, sizeof iterm_256colour_terminfo); } else if (terminfo_is_term_family(term, "st")) { + *termname = xstrdup("builtin_st"); return unibi_from_mem((const char *)st_256colour_terminfo, sizeof st_256colour_terminfo); } else if (terminfo_is_term_family(term, "gnome") || terminfo_is_term_family(term, "vte")) { + *termname = xstrdup("builtin_vte"); return unibi_from_mem((const char *)vte_256colour_terminfo, sizeof vte_256colour_terminfo); } else { + *termname = xstrdup("builtin_ansi"); return unibi_from_mem((const char *)ansi_terminfo, sizeof ansi_terminfo); } } -unibi_term *terminfo_from_builtin(const char *term) +/// @param term $TERM value +/// @param[out,allocated] termname decided builtin 'term' name +/// @return [allocated] terminfo structure +unibi_term *terminfo_from_builtin(const char *term, char **termname) { - unibi_term *ut = terminfo_builtin(term); + unibi_term *ut = terminfo_builtin(term, termname); + if (*termname == NULL) { + *termname = xstrdup("builtin_?"); + } // Disable BCE by default (for built-in terminfos). #7624 // https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545 unibi_set_bool(ut, unibi_back_color_erase, false); diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index c2e597c36c..724d59b15a 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -23,6 +23,7 @@ #include "nvim/map.h" #include "nvim/main.h" #include "nvim/memory.h" +#include "nvim/option.h" #include "nvim/api/vim.h" #include "nvim/api/private/helpers.h" #include "nvim/event/loop.h" @@ -166,6 +167,13 @@ static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, return unibi_run(str, data->params, buf, len); } +static void termname_set_event(void **argv) +{ + char *termname = argv[0]; + set_tty_option("term", termname); + // Do not free termname, it is freed by set_tty_option. +} + static void terminfo_start(UI *ui) { TUIData *data = ui->data; @@ -190,12 +198,20 @@ static void terminfo_start(UI *ui) data->unibi_ext.reset_cursor_style = -1; data->out_fd = 1; data->out_isatty = os_isatty(data->out_fd); - // setup unibilium + + // Set up unibilium/terminfo. const char *term = os_getenv("TERM"); data->ut = unibi_from_env(); + char *termname = NULL; if (!data->ut) { - data->ut = terminfo_from_builtin(term); + data->ut = terminfo_from_builtin(term, &termname); + } else { + termname = xstrdup(term); } + // Update 'term' option. + loop_schedule_deferred(&main_loop, + event_create(termname_set_event, 1, termname)); + // None of the following work over SSH; see :help TERM . const char *colorterm = os_getenv("COLORTERM"); const char *termprg = os_getenv("TERM_PROGRAM"); @@ -344,7 +360,7 @@ static void tui_scheduler(Event event, void *d) { UI *ui = d; TUIData *data = ui->data; - loop_schedule(data->loop, event); + loop_schedule(data->loop, event); // `tui_loop` local to tui_main(). } #ifdef UNIX @@ -940,10 +956,9 @@ static void tui_scroll(UI *ui, Integer count) } cursor_goto(ui, saved_row, saved_col); - if (!scroll_clears_to_current_colour && grid->bg != -1) { - // Scrolling may leave wrong background in the cleared area on non-bge - // terminals. Update the cleared area of the terminal if its builtin - // scrolling facility was used and bg color is not the default. + if (!scroll_clears_to_current_colour) { + // Scrolling will leave wrong background in the cleared area on non-BCE + // terminals. Update the cleared area. clear_region(ui, clear_top, clear_bot, grid->left, grid->right); } } else { diff --git a/src/nvim/version.c b/src/nvim/version.c index 736cdd0a77..9ef35e66f8 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -78,8 +78,157 @@ NULL // clang-format off static const int included_patches[] = { + 1357, + // 1356, + // 1355, + // 1354, + // 1353, + // 1352, + // 1351, + // 1350, + // 1349, + // 1348, + // 1347, + // 1346, + // 1345, + // 1344, + // 1343, + // 1342, + // 1341, + // 1340, + // 1339, + // 1338, + // 1337, + // 1336, + // 1335, + // 1334, + // 1333, + // 1332, + // 1331, + // 1330, + // 1329, + // 1328, + // 1327, + // 1326, + // 1325, + // 1324, + // 1323, + // 1322, + // 1321, + // 1320, + // 1319, + // 1318, + // 1317, + // 1316, + // 1315, + // 1314, + // 1313, + // 1312, + // 1311, + // 1310, + // 1309, + // 1308, + // 1307, + // 1306, + // 1305, + // 1304, + // 1303, + // 1302, + // 1301, + // 1300, + // 1299, + // 1298, + // 1297, + // 1296, + // 1295, + // 1294, + // 1293, + // 1292, + // 1291, + // 1290, + // 1289, + // 1288, + // 1287, + // 1286, + // 1285, + // 1284, + // 1283, + // 1282, + // 1281, + // 1280, + // 1279, + // 1278, + // 1277, + // 1276, + // 1275, + // 1274, + // 1273, + // 1272, + // 1271, + // 1270, + // 1269, + // 1268, + // 1267, + // 1266, + // 1265, + // 1264, + // 1263, + // 1262, + // 1261, + // 1260, + // 1259, + // 1258, + // 1257, + // 1256, + // 1255, + // 1254, + // 1253, + // 1252, + // 1251, + // 1250, + // 1249, + // 1248, + // 1247, + // 1246, + // 1245, + // 1244, + // 1243, + // 1242, + // 1241, + // 1240, + // 1239, + // 1238, + // 1237, + // 1236, + // 1235, + // 1234, + // 1233, + // 1232, + // 1231, 1230, 1229, + // 1228, + // 1227, + // 1226, + // 1225, + // 1224, + // 1223, + // 1222, + // 1221, + // 1220, + // 1219, + // 1218, + // 1217, + // 1216, + // 1215, + // 1214, + // 1213, + // 1212, + // 1211, + // 1210, + // 1209, + // 1208, + // 1207, 1206, // 1026, 1025, @@ -805,7 +954,7 @@ static const int included_patches[] = { 305, // 304, // 303, - // 302, NA + // 302 NA // 301, 300, // 299, @@ -927,7 +1076,7 @@ static const int included_patches[] = { // 183 NA 182, 181, - // 180, + // 180 NA 179, 178, 177, @@ -937,11 +1086,11 @@ static const int included_patches[] = { // 173 NA 172, // 171, - // 170, - // 169, + // 170 NA + // 169 NA 168, 167, - // 166, + // 166 NA 165, 164, // 163 NA @@ -966,7 +1115,7 @@ static const int included_patches[] = { // 144 NA 143, 142, - // 141, + // 141 NA 140, // 139 NA // 138 NA @@ -1011,7 +1160,7 @@ static const int included_patches[] = { 99, // 98 NA // 97 NA - // 96, + 96, // 95 NA // 94 NA // 93 NA @@ -1086,10 +1235,10 @@ static const int included_patches[] = { // 24 NA 23, // 22 NA - // 21, + // 21 NA 20, 19, - // 18, + // 18 NA 17, // 16 NA // 15 NA diff --git a/src/nvim/vim.h b/src/nvim/vim.h index e196dd7714..b535e380d1 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -307,7 +307,8 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() // Lowest number used for window ID. Cannot have this many windows per tab. #define LOWEST_WIN_ID 1000 -#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && defined(S_ISCHR) +// BSD is supposed to cover FreeBSD and similar systems. +#if (defined(BSD) || defined(__FreeBSD_kernel__)) && defined(S_ISCHR) # define OPEN_CHR_FILES #endif |