To: vim_dev@googlegroups.com Subject: Patch 8.0.1026 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1026 Problem: GTK on-the-spot input has problems. (Gerd Wachsmuth) Solution: Support over-the-spot. (Yukihiro Nakadaira, Ketn Takata, closes #1215) Files: runtime/doc/mbyte.txt, runtime/doc/options.txt, src/edit.c, src/ex_getln.c, src/mbyte.c, src/misc1.c, src/option.c, src/option.h, src/screen.c, src/undo.c, src/testdir/gen_opt_test.vim *** ../vim-8.0.1025/runtime/doc/mbyte.txt 2016-09-12 12:45:26.000000000 +0200 --- runtime/doc/mbyte.txt 2017-08-30 21:33:45.785135261 +0200 *************** *** 832,837 **** --- 832,840 ---- Currently, GUI Vim supports three styles, |OverTheSpot|, |OffTheSpot| and |Root|. + When compiled with |+GUI_GTK| feature, GUI Vim supports two styles, + |OnTheSpot| and |OverTheSpot|. You can select the style with the 'imstyle' + option. *. on-the-spot *OnTheSpot* Preedit Area and Status Area are performed by the client application in *** ../vim-8.0.1025/runtime/doc/options.txt 2017-08-16 23:14:03.543122736 +0200 --- runtime/doc/options.txt 2017-08-30 21:33:45.785135261 +0200 *************** *** 4272,4277 **** --- 4368,4390 ---- < NOTE: This function is invoked very often. Keep it fast. + *'imstyle'* *'imst'* + 'imstyle' 'imst' number (default 1) + global + {not in Vi} + {only available when compiled with |+xim| and + |+GUI_GTK|} + This option specifies the input style of Input Method. + Set to zero if you want to use on-the-spot style. + Set to one if you want to use over-the-spot style. + See: |xim-input-style| + + For a long time on-the-spot sytle had been used in GTK version of vim, + however, it is known that it causes troubles when using mappings, + |single-repeat|, etc. Therefore over-the-spot style becomes the + default now. This should work fine for most people, however if you + have any problem with it, try using on-the-spot style. + *'include'* *'inc'* 'include' 'inc' string (default "^\s*#\s*include") global or local to buffer |global-local| *** ../vim-8.0.1025/src/edit.c 2017-08-16 22:45:57.673684093 +0200 --- src/edit.c 2017-08-30 21:33:45.789135234 +0200 *************** *** 9683,9689 **** #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) /* Only call start_arrow() when not busy with preediting, it will * break undo. K_LEFT is inserted in im_correct_cursor(). */ ! if (!im_is_preediting()) #endif { start_arrow_with_change(&tpos, end_change); --- 9683,9689 ---- #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) /* Only call start_arrow() when not busy with preediting, it will * break undo. K_LEFT is inserted in im_correct_cursor(). */ ! if (p_imst == IM_OVER_THE_SPOT || !im_is_preediting()) #endif { start_arrow_with_change(&tpos, end_change); *** ../vim-8.0.1025/src/ex_getln.c 2017-08-06 15:22:10.301211970 +0200 --- src/ex_getln.c 2017-08-30 21:33:45.789135234 +0200 *************** *** 3468,3474 **** windgoto(msg_row, msg_col); #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) ! redrawcmd_preedit(); #endif #ifdef MCH_CURSOR_SHAPE mch_update_cursor(); --- 3468,3475 ---- windgoto(msg_row, msg_col); #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) ! if (p_imst == IM_ON_THE_SPOT) ! redrawcmd_preedit(); #endif #ifdef MCH_CURSOR_SHAPE mch_update_cursor(); *** ../vim-8.0.1025/src/mbyte.c 2017-08-30 13:22:24.540288850 +0200 --- src/mbyte.c 2017-08-30 21:33:45.793135205 +0200 *************** *** 4788,4793 **** --- 4788,4798 ---- static unsigned int im_activatekey_keyval = GDK_VoidSymbol; static unsigned int im_activatekey_state = 0; + static GtkWidget *preedit_window = NULL; + static GtkWidget *preedit_label = NULL; + + static void im_preedit_window_set_position(void); + void im_set_active(int active) { *************** *** 4825,4830 **** --- 4830,4838 ---- area.height = gui.char_height; gtk_im_context_set_cursor_location(xic, &area); + + if (p_imst == IM_OVER_THE_SPOT) + im_preedit_window_set_position(); } } *************** *** 4855,4866 **** --- 4863,4969 ---- gui_mch_mousehide(TRUE); } + static void + im_preedit_window_set_position(void) + { + int x, y, w, h, sw, sh; + + if (preedit_window == NULL) + return; + + sw = gdk_screen_get_width(gtk_widget_get_screen(preedit_window)); + sh = gdk_screen_get_height(gtk_widget_get_screen(preedit_window)); + #if GTK_CHECK_VERSION(3,0,0) + gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y); + #else + gdk_window_get_origin(gui.drawarea->window, &x, &y); + #endif + gtk_window_get_size(GTK_WINDOW(preedit_window), &w, &h); + x = x + FILL_X(gui.col); + y = y + FILL_Y(gui.row); + if (x + w > sw) + x = sw - w; + if (y + h > sh) + y = sh - h; + gtk_window_move(GTK_WINDOW(preedit_window), x, y); + } + + static void + im_preedit_window_open() + { + char *preedit_string; + char buf[8]; + PangoAttrList *attr_list; + PangoLayout *layout; + GdkColor color; + gint w, h; + + if (preedit_window == NULL) + { + preedit_window = gtk_window_new(GTK_WINDOW_POPUP); + preedit_label = gtk_label_new(""); + gtk_container_add(GTK_CONTAINER(preedit_window), preedit_label); + } + + gtk_widget_modify_font(preedit_label, gui.norm_font); + + vim_snprintf(buf, sizeof(buf), "#%06X", gui.norm_pixel); + gdk_color_parse(buf, &color); + gtk_widget_modify_fg(preedit_label, GTK_STATE_NORMAL, &color); + + vim_snprintf(buf, sizeof(buf), "#%06X", gui.back_pixel); + gdk_color_parse(buf, &color); + gtk_widget_modify_bg(preedit_window, GTK_STATE_NORMAL, &color); + + gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL); + + if (preedit_string[0] != NUL) + { + gtk_label_set_text(GTK_LABEL(preedit_label), preedit_string); + gtk_label_set_attributes(GTK_LABEL(preedit_label), attr_list); + + layout = gtk_label_get_layout(GTK_LABEL(preedit_label)); + pango_layout_get_pixel_size(layout, &w, &h); + h = MAX(h, gui.char_height); + gtk_window_resize(GTK_WINDOW(preedit_window), w, h); + + gtk_widget_show_all(preedit_window); + + im_preedit_window_set_position(); + } + + g_free(preedit_string); + pango_attr_list_unref(attr_list); + } + + static void + im_preedit_window_close() + { + if (preedit_window != NULL) + gtk_widget_hide(preedit_window); + } + + static void + im_show_preedit() + { + im_preedit_window_open(); + + if (p_mh) /* blank out the pointer if necessary */ + gui_mch_mousehide(TRUE); + } + static void im_delete_preedit(void) { char_u bskey[] = {CSI, 'k', 'b'}; char_u delkey[] = {CSI, 'k', 'D'}; + if (p_imst == IM_OVER_THE_SPOT) + { + im_preedit_window_close(); + return; + } + if (State & NORMAL) { im_preedit_cursor = 0; *************** *** 4933,4971 **** xim_log("im_commit_cb(): %s\n", str); #endif ! /* The imhangul module doesn't reset the preedit string before ! * committing. Call im_delete_preedit() to work around that. */ ! im_delete_preedit(); ! ! /* Indicate that preediting has finished. */ ! if (preedit_start_col == MAXCOL) { ! init_preedit_start_col(); ! commit_with_preedit = FALSE; ! } ! /* The thing which setting "preedit_start_col" to MAXCOL means that ! * "preedit_start_col" will be set forcedly when calling ! * preedit_changed_cb() next time. ! * "preedit_start_col" should not reset with MAXCOL on this part. Vim ! * is simulating the preediting by using add_to_input_str(). when ! * preedit begin immediately before committed, the typebuf is not ! * flushed to screen, then it can't get correct "preedit_start_col". ! * Thus, it should calculate the cells by adding cells of the committed ! * string. */ ! if (input_conv.vc_type != CONV_NONE) ! { ! im_str = string_convert(&input_conv, (char_u *)str, &len); ! g_return_if_fail(im_str != NULL); ! } ! else ! im_str = (char_u *)str; ! clen = mb_string2cells(im_str, len); ! if (input_conv.vc_type != CONV_NONE) ! vim_free(im_str); ! preedit_start_col += clen; /* Is this a single character that matches a keypad key that's just * been pressed? If so, we don't want it to be entered as such - let --- 5036,5077 ---- xim_log("im_commit_cb(): %s\n", str); #endif ! if (p_imst == IM_ON_THE_SPOT) { ! /* The imhangul module doesn't reset the preedit string before ! * committing. Call im_delete_preedit() to work around that. */ ! im_delete_preedit(); ! /* Indicate that preediting has finished. */ ! if (preedit_start_col == MAXCOL) ! { ! init_preedit_start_col(); ! commit_with_preedit = FALSE; ! } ! /* The thing which setting "preedit_start_col" to MAXCOL means that ! * "preedit_start_col" will be set forcedly when calling ! * preedit_changed_cb() next time. ! * "preedit_start_col" should not reset with MAXCOL on this part. Vim ! * is simulating the preediting by using add_to_input_str(). when ! * preedit begin immediately before committed, the typebuf is not ! * flushed to screen, then it can't get correct "preedit_start_col". ! * Thus, it should calculate the cells by adding cells of the committed ! * string. */ ! if (input_conv.vc_type != CONV_NONE) ! { ! im_str = string_convert(&input_conv, (char_u *)str, &len); ! g_return_if_fail(im_str != NULL); ! } ! else ! im_str = (char_u *)str; ! clen = mb_string2cells(im_str, len); ! ! if (input_conv.vc_type != CONV_NONE) ! vim_free(im_str); ! preedit_start_col += clen; ! } /* Is this a single character that matches a keypad key that's just * been pressed? If so, we don't want it to be entered as such - let *************** *** 4990,5003 **** if (add_to_input) im_add_to_input((char_u *)str, slen); ! /* Inserting chars while "im_is_active" is set does not cause a change of ! * buffer. When the chars are committed the buffer must be marked as ! * changed. */ ! if (!commit_with_preedit) ! preedit_start_col = MAXCOL; ! /* This flag is used in changed() at next call. */ ! xim_changed_while_preediting = TRUE; if (gtk_main_level() > 0) gtk_main_quit(); --- 5096,5112 ---- if (add_to_input) im_add_to_input((char_u *)str, slen); ! if (p_imst == IM_ON_THE_SPOT) ! { ! /* Inserting chars while "im_is_active" is set does not cause a ! * change of buffer. When the chars are committed the buffer must be ! * marked as changed. */ ! if (!commit_with_preedit) ! preedit_start_col = MAXCOL; ! /* This flag is used in changed() at next call. */ ! xim_changed_while_preediting = TRUE; ! } if (gtk_main_level() > 0) gtk_main_quit(); *************** *** 5031,5037 **** im_delete_preedit(); /* Indicate that preediting has finished */ ! preedit_start_col = MAXCOL; xim_has_preediting = FALSE; #if 0 --- 5140,5147 ---- im_delete_preedit(); /* Indicate that preediting has finished */ ! if (p_imst == IM_ON_THE_SPOT) ! preedit_start_col = MAXCOL; xim_has_preediting = FALSE; #if 0 *************** *** 5092,5100 **** char_u *p; int i; ! gtk_im_context_get_preedit_string(context, ! &preedit_string, NULL, ! &cursor_index); #ifdef XIM_DEBUG xim_log("im_preedit_changed_cb(): %s\n", preedit_string); --- 5202,5215 ---- char_u *p; int i; ! if (p_imst == IM_ON_THE_SPOT) ! gtk_im_context_get_preedit_string(context, ! &preedit_string, NULL, ! &cursor_index); ! else ! gtk_im_context_get_preedit_string(context, ! &preedit_string, NULL, ! NULL); #ifdef XIM_DEBUG xim_log("im_preedit_changed_cb(): %s\n", preedit_string); *************** *** 5102,5167 **** g_return_if_fail(preedit_string != NULL); /* just in case */ ! /* If preedit_start_col is MAXCOL set it to the current cursor position. */ ! if (preedit_start_col == MAXCOL && preedit_string[0] != '\0') { ! xim_has_preediting = TRUE; ! ! /* Urgh, this breaks if the input buffer isn't empty now */ ! init_preedit_start_col(); } ! else if (cursor_index == 0 && preedit_string[0] == '\0') { ! xim_has_preediting = FALSE; ! /* If at the start position (after typing backspace) ! * preedit_start_col must be reset. */ ! preedit_start_col = MAXCOL; ! } ! im_delete_preedit(); ! /* ! * Compute the end of the preediting area: "preedit_end_col". ! * According to the documentation of gtk_im_context_get_preedit_string(), ! * the cursor_pos output argument returns the offset in bytes. This is ! * unfortunately not true -- real life shows the offset is in characters, ! * and the GTK+ source code agrees with me. Will file a bug later. ! */ ! if (preedit_start_col != MAXCOL) ! preedit_end_col = preedit_start_col; ! str = (char_u *)preedit_string; ! for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i) ! { ! int is_composing; - is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p))); /* ! * These offsets are used as counters when generating and ! * to delete the preedit string. So don't count composing characters ! * unless 'delcombine' is enabled. */ ! if (!is_composing || p_deco) { ! if (i < cursor_index) ! ++im_preedit_cursor; ! else ! ++im_preedit_trailing; } ! if (!is_composing && i >= cursor_index) { ! /* This is essentially the same as im_preedit_trailing, except ! * composing characters are not counted even if p_deco is set. */ ! ++num_move_back; } - if (preedit_start_col != MAXCOL) - preedit_end_col += utf_ptr2cells(p); - } - - if (p > str) - { - im_add_to_input(str, (int)(p - str)); - im_correct_cursor(num_move_back); } g_free(preedit_string); --- 5217,5298 ---- g_return_if_fail(preedit_string != NULL); /* just in case */ ! if (p_imst == IM_OVER_THE_SPOT) { ! if (preedit_string[0] == NUL) ! { ! xim_has_preediting = FALSE; ! im_delete_preedit(); ! } ! else ! { ! xim_has_preediting = TRUE; ! im_show_preedit(); ! } } ! else { ! /* If preedit_start_col is MAXCOL set it to the current cursor position. */ ! if (preedit_start_col == MAXCOL && preedit_string[0] != '\0') ! { ! xim_has_preediting = TRUE; ! /* Urgh, this breaks if the input buffer isn't empty now */ ! init_preedit_start_col(); ! } ! else if (cursor_index == 0 && preedit_string[0] == '\0') ! { ! xim_has_preediting = FALSE; ! /* If at the start position (after typing backspace) ! * preedit_start_col must be reset. */ ! preedit_start_col = MAXCOL; ! } ! im_delete_preedit(); /* ! * Compute the end of the preediting area: "preedit_end_col". ! * According to the documentation of gtk_im_context_get_preedit_string(), ! * the cursor_pos output argument returns the offset in bytes. This is ! * unfortunately not true -- real life shows the offset is in characters, ! * and the GTK+ source code agrees with me. Will file a bug later. */ ! if (preedit_start_col != MAXCOL) ! preedit_end_col = preedit_start_col; ! str = (char_u *)preedit_string; ! for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i) { ! int is_composing; ! ! is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p))); ! /* ! * These offsets are used as counters when generating and ! * to delete the preedit string. So don't count composing characters ! * unless 'delcombine' is enabled. ! */ ! if (!is_composing || p_deco) ! { ! if (i < cursor_index) ! ++im_preedit_cursor; ! else ! ++im_preedit_trailing; ! } ! if (!is_composing && i >= cursor_index) ! { ! /* This is essentially the same as im_preedit_trailing, except ! * composing characters are not counted even if p_deco is set. */ ! ++num_move_back; ! } ! if (preedit_start_col != MAXCOL) ! preedit_end_col += utf_ptr2cells(p); } ! ! if (p > str) { ! im_add_to_input(str, (int)(p - str)); ! im_correct_cursor(num_move_back); } } g_free(preedit_string); *************** *** 5310,5316 **** } im_is_active = FALSE; im_commit_handler_id = 0; ! preedit_start_col = MAXCOL; xim_has_preediting = FALSE; } --- 5441,5448 ---- } im_is_active = FALSE; im_commit_handler_id = 0; ! if (p_imst == IM_ON_THE_SPOT) ! preedit_start_col = MAXCOL; xim_has_preediting = FALSE; } *************** *** 5465,5471 **** } } ! preedit_start_col = MAXCOL; xim_has_preediting = FALSE; } --- 5597,5604 ---- } } ! if (p_imst == IM_ON_THE_SPOT) ! preedit_start_col = MAXCOL; xim_has_preediting = FALSE; } *************** *** 5570,5588 **** { int imresult = gtk_im_context_filter_keypress(xic, event); ! /* Some XIM send following sequence: ! * 1. preedited string. ! * 2. committed string. ! * 3. line changed key. ! * 4. preedited string. ! * 5. remove preedited string. ! * if 3, Vim can't move back the above line for 5. ! * thus, this part should not parse the key. */ ! if (!imresult && preedit_start_col != MAXCOL ! && event->keyval == GDK_Return) { ! im_synthesize_keypress(GDK_Return, 0U); ! return FALSE; } /* If XIM tried to commit a keypad key as a single char., --- 5703,5724 ---- { int imresult = gtk_im_context_filter_keypress(xic, event); ! if (p_imst == IM_ON_THE_SPOT) { ! /* Some XIM send following sequence: ! * 1. preedited string. ! * 2. committed string. ! * 3. line changed key. ! * 4. preedited string. ! * 5. remove preedited string. ! * if 3, Vim can't move back the above line for 5. ! * thus, this part should not parse the key. */ ! if (!imresult && preedit_start_col != MAXCOL ! && event->keyval == GDK_Return) ! { ! im_synthesize_keypress(GDK_Return, 0U); ! return FALSE; ! } } /* If XIM tried to commit a keypad key as a single char., *** ../vim-8.0.1025/src/misc1.c 2017-08-30 13:22:24.540288850 +0200 --- src/misc1.c 2017-08-30 21:33:45.793135205 +0200 *************** *** 2730,2741 **** changed(void) { #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) ! /* The text of the preediting area is inserted, but this doesn't ! * mean a change of the buffer yet. That is delayed until the ! * text is committed. (this means preedit becomes empty) */ ! if (im_is_preediting() && !xim_changed_while_preediting) ! return; ! xim_changed_while_preediting = FALSE; #endif if (!curbuf->b_changed) --- 2730,2744 ---- changed(void) { #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) ! if (p_imst == IM_ON_THE_SPOT) ! { ! /* The text of the preediting area is inserted, but this doesn't ! * mean a change of the buffer yet. That is delayed until the ! * text is committed. (this means preedit becomes empty) */ ! if (im_is_preediting() && !xim_changed_while_preediting) ! return; ! xim_changed_while_preediting = FALSE; ! } #endif if (!curbuf->b_changed) *** ../vim-8.0.1025/src/option.c 2017-08-28 22:43:00.774266657 +0200 --- src/option.c 2017-08-30 21:33:45.797135178 +0200 *************** *** 1606,1618 **** #endif SCRIPTID_INIT}, {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE, ! # if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK) (char_u *)&p_imsf, PV_NONE, {(char_u *)"", (char_u *)NULL} ! # else (char_u *)NULL, PV_NONE, {(char_u *)NULL, (char_u *)0L} ! # endif SCRIPTID_INIT}, {"include", "inc", P_STRING|P_ALLOCED|P_VI_DEF, #ifdef FEAT_FIND_ID --- 1606,1627 ---- #endif SCRIPTID_INIT}, {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE, ! #if defined(FEAT_EVAL) && defined(FEAT_XIM) && defined(FEAT_GUI_GTK) (char_u *)&p_imsf, PV_NONE, {(char_u *)"", (char_u *)NULL} ! #else (char_u *)NULL, PV_NONE, {(char_u *)NULL, (char_u *)0L} ! #endif ! SCRIPTID_INIT}, ! {"imstyle", "imst", P_NUM|P_VI_DEF|P_SECURE, ! #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) ! (char_u *)&p_imst, PV_NONE, ! {(char_u *)IM_OVER_THE_SPOT, (char_u *)0L} ! #else ! (char_u *)NULL, PV_NONE, ! {(char_u *)0L, (char_u *)0L} ! #endif SCRIPTID_INIT}, {"include", "inc", P_STRING|P_ALLOCED|P_VI_DEF, #ifdef FEAT_FIND_ID *************** *** 8990,8995 **** --- 8999,9013 ---- #endif } + #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) + /* 'imstyle' */ + else if (pp == &p_imst) + { + if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT) + errmsg = e_invarg; + } + #endif + else if (pp == &p_window) { if (p_window < 1) *** ../vim-8.0.1025/src/option.h 2017-08-17 11:22:41.836109216 +0200 --- src/option.h 2017-08-30 21:33:45.797135178 +0200 *************** *** 581,586 **** --- 581,589 ---- EXTERN char_u *p_imak; /* 'imactivatekey' */ EXTERN char_u *p_imaf; /* 'imactivatefunc' */ EXTERN char_u *p_imsf; /* 'imstatusfunc' */ + EXTERN long p_imst; /* 'imstyle' */ + # define IM_ON_THE_SPOT 0L + # define IM_OVER_THE_SPOT 1L #endif #ifdef USE_IM_CONTROL EXTERN int p_imcmdline; /* 'imcmdline' */ *** ../vim-8.0.1025/src/screen.c 2017-08-26 23:43:23.978903346 +0200 --- src/screen.c 2017-08-30 21:33:45.797135178 +0200 *************** *** 5197,5203 **** /* XIM don't send preedit_start and preedit_end, but they send * preedit_changed and commit. Thus Vim can't set "im_is_active", use * im_is_preediting() here. */ ! if (xic != NULL && lnum == wp->w_cursor.lnum && (State & INSERT) && !p_imdisable --- 5197,5204 ---- /* XIM don't send preedit_start and preedit_end, but they send * preedit_changed and commit. Thus Vim can't set "im_is_active", use * im_is_preediting() here. */ ! if (p_imst == IM_ON_THE_SPOT ! && xic != NULL && lnum == wp->w_cursor.lnum && (State & INSERT) && !p_imdisable *** ../vim-8.0.1025/src/undo.c 2017-08-23 22:32:30.536388857 +0200 --- src/undo.c 2017-08-30 21:33:45.797135178 +0200 *************** *** 2984,2990 **** if (curbuf->b_u_synced || (!force && no_u_sync > 0)) return; #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) ! if (im_is_preediting()) return; /* XIM is busy, don't break an undo sequence */ #endif if (get_undolevel() < 0) --- 2984,2990 ---- if (curbuf->b_u_synced || (!force && no_u_sync > 0)) return; #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) ! if (p_imst == IM_ON_THE_SPOT && im_is_preediting()) return; /* XIM is busy, don't break an undo sequence */ #endif if (get_undolevel() < 0) *** ../vim-8.0.1025/src/testdir/gen_opt_test.vim 2017-07-22 17:03:57.371802012 +0200 --- src/testdir/gen_opt_test.vim 2017-08-30 21:51:09.925922122 +0200 *************** *** 31,36 **** --- 31,37 ---- \ 'history': [[0, 1, 100], [-1, 10001]], \ 'iminsert': [[0, 1], [-1, 3, 999]], \ 'imsearch': [[-1, 0, 1], [-2, 3, 999]], + \ 'imstyle': [[0, 1], [-1, 2, 999]], \ 'lines': [[2, 24], [-1, 0, 1]], \ 'linespace': [[0, 2, 4], ['']], \ 'numberwidth': [[1, 4, 8, 10], [-1, 0, 11]], *** ../vim-8.0.1025/src/version.c 2017-08-30 21:57:58.003077451 +0200 --- src/version.c 2017-08-30 21:58:48.490725323 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 1026, /**/ -- Seen it all, done it all, can't remember most of it. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///