aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_cmds2.c6
-rw-r--r--src/nvim/fileio.c30
-rw-r--r--src/nvim/if_cscope.c17
-rw-r--r--src/nvim/option.c96
-rw-r--r--src/nvim/os/os_defs.h1
-rw-r--r--src/nvim/quickfix.c20
-rw-r--r--src/nvim/tui/terminfo.c28
-rw-r--r--src/nvim/tui/tui.c29
-rw-r--r--src/nvim/version.c167
-rw-r--r--src/nvim/vim.h3
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