Compare commits

...

4 Commits

Author SHA1 Message Date
Ernie Rael
9f53e7bd7f patch 8.2.4776: GTK: 'lines' and 'columns' may change during startup
Problem:    GTK: 'lines' and 'columns' may change during startup.
Solution:   Ignore stale GTK resize events. (Ernie Rael, closes #10179)
2022-04-17 18:27:49 +01:00
Bram Moolenaar
280aebfd35 patch 8.2.4775: SpellBad highlighting does not work in Konsole
Problem:    SpellBad highlighting does not work in Konsole.
Solution:   Do not keep t_8u defined for Konsole.  Redraw when t_8u is reset.
            (closes #10177)
2022-04-17 17:34:42 +01:00
Bram Moolenaar
8b91e71441 patch 8.2.4774: crash when using a number for lambda name
Problem:    Crash when using a number for lambda name.
Solution:   Check the type of the lambda reference.
2022-04-17 15:06:35 +01:00
Bram Moolenaar
a9549c9e8f patch 8.2.4773: build failure without the +eval feature
Problem:    Build failure without the +eval feature.
Solution:   Use other error message.  Avoid warnings.
2022-04-17 14:18:11 +01:00
8 changed files with 207 additions and 24 deletions

View File

@@ -420,7 +420,7 @@ cin_islabel_skip(char_u **s)
}
/*
* Recognize a "public/private/protected" scope declaration label.
* Recognize a scope declaration label from the 'cinscopedecls' option.
*/
static int
cin_isscopedecl(char_u *p)
@@ -440,7 +440,7 @@ cin_isscopedecl(char_u *p)
for (cinsd = curbuf->b_p_cinsd; *cinsd; )
{
len = copy_option_part(&cinsd, cinsd_buf, cinsd_len, ",");
len = copy_option_part(&cinsd, cinsd_buf, (int)cinsd_len, ",");
if (STRNCMP(s, cinsd_buf, len) == 0)
{
skip = cin_skipcomment(s + len);

View File

@@ -3259,3 +3259,7 @@ EXTERN char e_nfa_regexp_missing_value_in_chr[]
INIT(= N_("E1273: (NFA regexp) missing value in '\\%%%c'"));
EXTERN char e_no_script_file_name_to_substitute_for_script[]
INIT(= N_("E1274: No script file name to substitute for \"<script>\""));
#ifdef FEAT_EVAL
EXTERN char e_string_or_function_required_for_arrow_parens_expr[]
INIT(= N_("E1275: String or function required for ->(expr)"));
#endif

View File

@@ -4102,19 +4102,23 @@ eval_lambda(
++*arg;
ret = eval1(arg, rettv, evalarg);
*arg = skipwhite_and_linebreak(*arg, evalarg);
if (**arg == ')')
{
++*arg;
}
else
if (**arg != ')')
{
emsg(_(e_missing_closing_paren));
ret = FAIL;
return FAIL;
}
if (rettv->v_type != VAR_STRING && rettv->v_type != VAR_FUNC
&& rettv->v_type != VAR_PARTIAL)
{
emsg(_(e_string_or_function_required_for_arrow_parens_expr));
return FAIL;
}
++*arg;
}
if (ret != OK)
return FAIL;
else if (**arg != '(')
if (**arg != '(')
{
if (verbose)
{

View File

@@ -396,6 +396,130 @@ static int using_gnome = 0;
# define using_gnome 0
#endif
/*
* Keep a short term resize history so that stale gtk responses can be
* discarded.
* When a gtk_window_resize() request is sent to gtk, the width/height of
* the request is saved. Recent stale requests are kept around in a list.
* See https://github.com/vim/vim/issues/10123
*/
#if 0 // Change to 1 to enable ch_log() calls for debugging.
# ifdef FEAT_JOB_CHANNEL
# define ENABLE_RESIZE_HISTORY_LOG
# endif
#endif
/*
* History item of a resize request.
* Width and height are of gui.mainwin.
*/
typedef struct resize_history {
int used; // If true, can't match for discard. Only matches once.
int width;
int height;
#ifdef ENABLE_RESIZE_HISTORY_LOG
int seq; // for ch_log messages
#endif
struct resize_history *next;
} resize_hist_T;
// never NULL during execution
static resize_hist_T *latest_resize_hist;
// list of stale resize requests
static resize_hist_T *old_resize_hists;
/*
* Used when calling gtk_window_resize().
* Create a resize request history item, put previous request on stale list.
* Width/height are the size of the request for the gui.mainwin.
*/
static void
alloc_resize_hist(int width, int height)
{
// alloc a new resize hist, save current in list of old history
resize_hist_T *prev_hist = latest_resize_hist;
resize_hist_T *new_hist = ALLOC_CLEAR_ONE(resize_hist_T);
new_hist->width = width;
new_hist->height = height;
latest_resize_hist = new_hist;
// previous hist item becomes head of list
prev_hist->next = old_resize_hists;
old_resize_hists = prev_hist;
#ifdef ENABLE_RESIZE_HISTORY_LOG
new_hist->seq = prev_hist->seq + 1;
ch_log(NULL, "gui_gtk: New resize seq %d (%d, %d) [%d, %d]",
new_hist->seq, width, height, (int)Columns, (int)Rows);
#endif
}
/*
* Free everything on the stale resize history list.
* This list is empty when there are no outstanding resize requests.
*/
static void
clear_resize_hists()
{
#ifdef ENABLE_RESIZE_HISTORY_LOG
int i = 0;
#endif
if (latest_resize_hist)
latest_resize_hist->used = TRUE;
while (old_resize_hists != NULL)
{
resize_hist_T *next_hist = old_resize_hists->next;
vim_free(old_resize_hists);
old_resize_hists = next_hist;
#ifdef ENABLE_RESIZE_HISTORY_LOG
i++;
#endif
}
#ifdef ENABLE_RESIZE_HISTORY_LOG
ch_log(NULL, "gui_gtk: free %d hists", i);
#endif
}
// true if hist item is unused and matches w,h
#define MATCH_WIDTH_HEIGHT(hist, w, h) \
(!hist->used && hist->width == w && hist->height == h)
/*
* Search the resize hist list.
* Return true if the specified width,height match an item in the list that
* has never matched before. Mark the matching item as used so it will
* not match again.
*/
static int
match_stale_width_height(int width, int height)
{
resize_hist_T *hist = old_resize_hists;
for (hist = old_resize_hists; hist != NULL; hist = hist->next)
if (MATCH_WIDTH_HEIGHT(hist, width, height))
{
#ifdef ENABLE_RESIZE_HISTORY_LOG
ch_log(NULL, "gui_gtk: discard seq %d, cur seq %d",
hist->seq, latest_resize_hist->seq);
#endif
hist->used = TRUE;
return TRUE;
}
return FALSE;
}
#if defined(EXITFREE)
static void
free_all_resize_hist()
{
clear_resize_hists();
vim_free(latest_resize_hist);
}
#endif
/*
* GTK doesn't set the GDK_BUTTON1_MASK state when dragging a touch. Add this
* state when dragging.
@@ -593,6 +717,7 @@ gui_mch_free_all(void)
#if defined(USE_GNOME_SESSION)
vim_free(abs_restart_command);
#endif
free_all_resize_hist();
}
#endif
@@ -709,7 +834,7 @@ property_event(GtkWidget *widget,
xev.xproperty.window = commWindow;
xev.xproperty.state = PropertyNewValue;
serverEventProc(GDK_WINDOW_XDISPLAY(gtk_widget_get_window(widget)),
&xev, 0);
&xev, 0);
}
return FALSE;
}
@@ -720,8 +845,8 @@ property_event(GtkWidget *widget,
*/
static void
gtk_settings_xft_dpi_changed_cb(GtkSettings *gtk_settings UNUSED,
GParamSpec *pspec UNUSED,
gpointer data UNUSED)
GParamSpec *pspec UNUSED,
gpointer data UNUSED)
{
// Create a new PangoContext for this screen, and initialize it
// with the current font if necessary.
@@ -4006,7 +4131,36 @@ form_configure_event(GtkWidget *widget UNUSED,
GdkEventConfigure *event,
gpointer data UNUSED)
{
int usable_height = event->height;
int usable_height = event->height;
// Resize requests are made for gui.mainwin,
// get it's dimensions for searching if this event
// is a response to a vim request.
GdkWindow *win = gtk_widget_get_window(gui.mainwin);
int w = gdk_window_get_width(win);
int h = gdk_window_get_height(win);
#ifdef ENABLE_RESIZE_HISTORY_LOG
ch_log(NULL, "gui_gtk: form_configure_event: (%d, %d) [%d, %d]",
w, h, (int)Columns, (int)Rows);
#endif
// Look through history of recent vim resize reqeusts.
// If this event matches:
// - "latest resize hist" We're caught up;
// clear the history and process this event.
// If history is, old to new, 100, 99, 100, 99. If this event is
// 99 for the stale, it is matched against the current. History
// is cleared, we my bounce, but no worse than before.
// - "older/stale hist" If match an unused event in history,
// then discard this event, and mark the matching event as used.
// - "no match" Figure it's a user resize event, clear history.
// NOTE: clear history is default, then all incoming events are processed
if (!MATCH_WIDTH_HEIGHT(latest_resize_hist, w, h)
&& match_stale_width_height(w, h))
// discard stale event
return TRUE;
clear_resize_hists();
#if GTK_CHECK_VERSION(3,22,2) && !GTK_CHECK_VERSION(3,22,4)
// As of 3.22.2, GdkWindows have started distributing configure events to
@@ -4329,15 +4483,16 @@ gui_mch_open(void)
* manager upon us and should not interfere with what VIM is requesting
* upon startup.
*/
latest_resize_hist = ALLOC_CLEAR_ONE(resize_hist_T);
g_signal_connect(G_OBJECT(gui.formwin), "configure-event",
G_CALLBACK(form_configure_event), NULL);
G_CALLBACK(form_configure_event), NULL);
#ifdef FEAT_DND
// Set up for receiving DND items.
gui_gtk_set_dnd_targets();
g_signal_connect(G_OBJECT(gui.drawarea), "drag-data-received",
G_CALLBACK(drag_data_received_cb), NULL);
G_CALLBACK(drag_data_received_cb), NULL);
#endif
// With GTK+ 2, we need to iconify the window before calling show()
@@ -4516,6 +4671,7 @@ gui_mch_set_shellsize(int width, int height,
width += get_menu_tool_width();
height += get_menu_tool_height();
alloc_resize_hist(width, height); // track the resize request
if (gtk_socket_id == 0)
gtk_window_resize(GTK_WINDOW(gui.mainwin), width, height);
else

View File

@@ -2343,7 +2343,7 @@ get_cmd_output(
|| (len = ftell(fd)) == -1 // get size of temp file
|| fseek(fd, 0L, SEEK_SET) == -1) // back to the start
{
semsg(_(e_cannot_read_from_str), tempname);
semsg(_(e_cannot_read_from_str_2), tempname);
if (fd != NULL)
fclose(fd);
goto done;

View File

@@ -4775,9 +4775,10 @@ handle_version_response(int first, int *arg, int argc, char_u *tp)
// vandyke SecureCRT sends 1;136;0
}
// Konsole sends 0;115;0
else if (version == 115 && arg[0] == 0 && arg[2] == 0)
term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES;
// Konsole sends 0;115;0 - but t_u8 does not actually work, therefore
// commented out.
// else if (version == 115 && arg[0] == 0 && arg[2] == 0)
// term_props[TPR_UNDERLINE_RGB].tpr_status = TPR_YES;
// GNU screen sends 83;30600;0, 83;40500;0, etc.
// 30600/40500 is a version number of GNU screen. DA2 support is added
@@ -4806,9 +4807,15 @@ handle_version_response(int first, int *arg, int argc, char_u *tp)
// Unless the underline RGB color is expected to work, disable "t_8u".
// It does not work for the real Xterm, it resets the background color.
// This may cause some flicker. Alternative would be to set "t_8u"
// here if the terminal is expected to support it, but that might
// conflict with what was set in the .vimrc.
if (term_props[TPR_UNDERLINE_RGB].tpr_status != TPR_YES && *T_8U != NUL)
{
set_string_option_direct((char_u *)"t_8u", -1, (char_u *)"",
OPT_FREE, 0);
redraw_later(CLEAR);
}
// Only set 'ttymouse' automatically if it was not set
// by the user already.
@@ -5957,7 +5964,7 @@ replace_termcodes(
int i;
int slen;
int key;
int dlen = 0;
size_t dlen = 0;
char_u *src;
int do_backslash; // backslash is a special character
int do_special; // recognize <> key codes
@@ -5977,7 +5984,7 @@ replace_termcodes(
* In the rare case more might be needed ga_grow() must be called again.
*/
ga_init2(&ga, 1L, 100);
if (ga_grow(&ga, STRLEN(src) * 6 + 1) == FAIL) // out of memory
if (ga_grow(&ga, (int)(STRLEN(src) * 6 + 1)) == FAIL) // out of memory
{
*bufp = NULL;
return from;
@@ -6044,8 +6051,8 @@ replace_termcodes(
// Turn "<SID>name.Func"
// into "scriptname#Func".
len = STRLEN(si->sn_autoload_prefix);
if (ga_grow(&ga, STRLEN(src) * 6 + len + 1)
== FAIL)
if (ga_grow(&ga,
(int)(STRLEN(src) * 6 + len + 1)) == FAIL)
{
ga_clear(&ga);
*bufp = NULL;
@@ -6064,7 +6071,7 @@ replace_termcodes(
result[dlen++] = (int)KS_EXTRA;
result[dlen++] = (int)KE_SNR;
sprintf((char *)result + dlen, "%ld", sid);
dlen += (int)STRLEN(result + dlen);
dlen += STRLEN(result + dlen);
result[dlen++] = '_';
continue;
}

View File

@@ -66,6 +66,10 @@ function Test_lambda_fails()
echo assert_fails('echo 10->{a -> a + 2}', 'E107:')
call assert_fails('eval 0->(', "E110: Missing ')'")
call assert_fails('eval 0->(3)()', "E1275:")
call assert_fails('eval 0->([3])()', "E1275:")
call assert_fails('eval 0->({"a": 3})()', "E1275:")
call assert_fails('eval 0->(xxx)()', "E121:")
endfunc
func Test_not_lamda()

View File

@@ -746,6 +746,14 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4776,
/**/
4775,
/**/
4774,
/**/
4773,
/**/
4772,
/**/