# HG changeset patch # User vimboss # Date 1105220985 0 # Node ID 2b4debdc8d2c73d1fc37b750010e3a4098b035af # Parent 014ba200db86945994a3bfd39920ff1b2d7f88da updated for version 7.0035 diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -30,8 +30,6 @@ be worked on, but only if you sponsor Vi *known-bugs* -------------------- Known bugs and current work ----------------------- -Add mouse patch from Marcin Dalecki. - Use 'ignorecase' for ":vimgrep"? When allocating a new variable, a search is done for an empty entry. May @@ -72,6 +70,7 @@ PLANNED FOR VERSION 7.0: - new DATA TYPES: - None? (or use empty string?) - dictionary + range(start, end, stride) creates a listable dict. Add type checking? See ~/vim/ideas.txt. - Add SPELLCHECKER, with easy to add support for many languages. 8 Add spell checking. Use "ispell -a" somehow. @@ -278,7 +277,7 @@ Awaiting updated patches: 8 "fg" and "bg" don't work in an xterm. Get default colors from xterm with an ESC sequence. Ideas in: ~/vim/patches/vikas.xtermcolors . 7 Add "DefaultFG" and "DefaultBG" for the colors of the menu. (Marcin - Dalecki has a patch for Motif) + Dalecki has a patch for Motif and Carbon) - Add possibility to highlight specific columns (for Fortran). Or put a line in between columns (e.g. for 'textwidth'). Patch to add 'hlcolumn' from Vit Stradal, 2004 May 20. @@ -569,10 +568,8 @@ 5 When starting gvim with all the defa Motif GUI: -8 Popup menu ordering is wrong. 7 Use XmStringCreateLocalized() instead of XmStringCreateSimple()? David Harrison says it's OK (it exists in Motif 1.2). -8 The texts in the find/replace dialog don't use the right font. 8 Lesstif: When deleting a menu that's torn off, the torn off menu becomes very small instead of disappearing. When closing it, Vim crashes. (Phillipps) @@ -1069,8 +1066,6 @@ I can't reproduce these (if you can, let 9 NT 4.0 on NTFS file system: Editing ".bashrc" (drag and drop), file disappears. Editing ".xyz" is OK. Also, drag&drop only works for three files. (McCollister) -8 Motif: Tear-off menu item crashes Vim on some machines. (Netherton) It - works fine for me, maybe it's a Motif problem. Problems that will (probably) not be solved: @@ -1334,7 +1329,7 @@ 7 Use ideas for nl_langinfo() from Mar For Windows, the charset_pairs[] table could be used. But how do we know if a font exists? - Do keyboard conversion from 'termencoding' to 'encoding' with - convert_input() for Mac GUI, RiscOS GUI, BeOS GUI. + convert_input() for Mac GUI and RiscOS GUI. - Add mnemonics from RFC1345 longer than two characters. Support CTRL-K _{mnemonic}_ 7 In "-- INSERT (lang) --" show the name of the keymap used instead of @@ -2021,11 +2016,6 @@ 6 Separate the part of Vim that does t things. 7 Motif: For a confirm() dialog should be ignored when no default button selected, should close the dialog. -- Motif steals from us, to pop up menus with the keyboard. How do we - get it back if we want it? It's already solved for GTK. -- Paste in Insert mode should not do autowrap etc. Or maybe this should be - changeable with an option? -- Put a nice picture in the icon (but how do we do that?). 7 When using a pseudo-tty Vim should behave like some terminal (vt52 looks simple enough). Terminal codes to/from shell should be translated. - Would it be useful to be able to quit the GUI and go back to the terminal diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -324,6 +324,7 @@ static long list_len __ARGS((listvar *l) static int list_equal __ARGS((listvar *l1, listvar *l2, int ic)); static int tv_equal __ARGS((typeval *tv1, typeval *tv2, int ic)); static listitem *list_find __ARGS((listvar *l, long n)); +static long list_idx_of_item __ARGS((listvar *l, listitem *item)); static listitem *list_find_ext __ARGS((listvar *l, long *ip)); static void list_append __ARGS((listvar *l, listitem *item)); static int list_append_tv __ARGS((listvar *l, typeval *tv)); @@ -440,6 +441,8 @@ static void f_mapcheck __ARGS((typeval * static void f_match __ARGS((typeval *argvars, typeval *rettv)); static void f_matchend __ARGS((typeval *argvars, typeval *rettv)); static void f_matchstr __ARGS((typeval *argvars, typeval *rettv)); +static void f_max __ARGS((typeval *argvars, typeval *rettv)); +static void f_min __ARGS((typeval *argvars, typeval *rettv)); static void f_mode __ARGS((typeval *argvars, typeval *rettv)); static void f_nextnonblank __ARGS((typeval *argvars, typeval *rettv)); static void f_nr2char __ARGS((typeval *argvars, typeval *rettv)); @@ -1540,8 +1543,8 @@ ex_let_one(arg, tv, copy, endchars) } /* - * Set a variable with an index: "name[expr]", "name[expr][expr]", etc. - * Only works if "name" is an existing List. + * Set a variable with an index: "name[expr]", "name[expr:expr]", + * "name[expr][expr]", etc. Only works if "name" is an existing List. * "ip" points to the first '['. * Returns a pointer to just after the last used ']'; NULL for error. */ @@ -1557,9 +1560,15 @@ set_var_idx(name, ip, rettv, copy, endch int c1; char_u *p; typeval var1; + typeval var2; + int range = FALSE; typeval *tv; - long n; - listitem *item; + long n1 = 0, n2 = 0; + int empty1, empty2 = FALSE; + listitem *item = NULL; + listitem *ni; + listitem *ri; + listvar *l = NULL; c1 = *ip; *ip = NUL; @@ -1579,28 +1588,122 @@ set_var_idx(name, ip, rettv, copy, endch p = NULL; break; } - p = skipwhite(p + 1); - if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ - { + if (range) + { + EMSG(_("E708: [:] must come last")); p = NULL; break; } + + /* Get the index [expr] or the first index [expr: ]. */ + p = skipwhite(p + 1); + if (*p == ':') + empty1 = TRUE; + else + { + empty1 = FALSE; + if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ + { + p = NULL; + break; + } + } + + /* Optionally get the second index [ :expr]. */ + if (*p == ':') + { + if (rettv->v_type != VAR_LIST || rettv->vval.v_list == NULL) + { + EMSG(_("E709: [:] requires a List value")); + p = NULL; + if (!empty1) + clear_tv(&var1); + break; + } + p = skipwhite(p + 1); + if (*p == ']') + empty2 = TRUE; + else + { + empty2 = FALSE; + if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ + { + p = NULL; + if (!empty1) + clear_tv(&var1); + break; + } + } + range = TRUE; + } + else + range = FALSE; + if (*p != ']') { EMSG(_(e_missbrac)); - clear_tv(&var1); + if (!empty1) + clear_tv(&var1); + if (range && !empty2) + clear_tv(&var2); p = NULL; break; } - n = get_tv_number(&var1); - clear_tv(&var1); - item = list_find(tv->vval.v_list, n); + + /* + * Get the number and item for the only or first index. + */ + if (empty1) + n1 = 0; + else + { + n1 = get_tv_number(&var1); + clear_tv(&var1); + } + l = tv->vval.v_list; + item = list_find(l, n1); if (item == NULL) { - EMSGN(_(e_listidx), n); + EMSGN(_(e_listidx), n1); p = NULL; + if (range && !empty2) + clear_tv(&var2); break; } + + /* + * May need to find the item or absolute index for the second index of + * a range. + * When no index given: "empty2" is TRUE. + * Otherwise "n2" is set to the second index. + */ + if (range && !empty2) + { + n2 = get_tv_number(&var2); + clear_tv(&var2); + if (n2 < 0) + { + ni = list_find(l, n2); + if (ni == NULL) + { + EMSGN(_(e_listidx), n2); + p = NULL; + break; + } + n2 = list_idx_of_item(l, ni); + } + + /* Check that n2 isn't before n1. */ + if (n1 < 0) + n1 = list_idx_of_item(l, item); + if (n2 < n1) + { + EMSGN(_(e_listidx), n2); + p = NULL; + break; + } + } + tv = &item->li_tv; } @@ -1611,11 +1714,47 @@ set_var_idx(name, ip, rettv, copy, endch EMSG(_(e_letunexp)); p = NULL; } - else - { + else if (range) + { + /* + * Assign the List values to the list items. + */ + for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) + { + clear_tv(&item->li_tv); + copy_tv(&ri->li_tv, &item->li_tv); + ri = ri->li_next; + if (ri == NULL || (!empty2 && n2 == n1)) + break; + if (item->li_next == NULL) + { + /* Need to add an empty item. */ + ni = listitem_alloc(); + if (ni == NULL) + { + ri = NULL; + break; + } + ni->li_tv.v_type = VAR_NUMBER; + ni->li_tv.vval.v_number = 0; + list_append(l, ni); + } + item = item->li_next; + ++n1; + } + if (ri != NULL) + EMSG(_("E710: List value has more items than target")); + else if (empty2 ? item != NULL && item->li_next != NULL : n1 != n2) + EMSG(_("E711: List value has not enough items")); + } + else + { + /* + * Assign the value to the variable or list item. + */ clear_tv(tv); if (copy) - copy_tv(tv, rettv); + copy_tv(rettv, tv); else { *tv = *rettv; @@ -3785,6 +3924,28 @@ list_find(l, n) } /* + * Locate "item" list "l" and return its index. + * Returns -1 when "item" is not in the list. + */ + static long +list_idx_of_item(l, item) + listvar *l; + listitem *item; +{ + long idx = 0; + listitem *li; + + if (l == NULL) + return -1; + idx = 0; + for (li = l->lv_first; li != NULL && li != item; li = li->li_next) + ++idx; + if (li == NULL) + return -1; + return idx;; +} + +/* * Like list_find(), but also find an item just past the end. * "*ip" is the item to find. * When found "*ip" is set to zero, when not found "*ip" is non-zero. @@ -4253,6 +4414,8 @@ static struct fst {"match", 2, 4, f_match}, {"matchend", 2, 4, f_matchend}, {"matchstr", 2, 4, f_matchstr}, + {"max", 1, 1, f_max}, + {"min", 1, 1, f_min}, {"mode", 0, 0, f_mode}, {"nextnonblank", 1, 1, f_nextnonblank}, {"nr2char", 1, 1, f_nr2char}, @@ -8085,6 +8248,67 @@ f_matchstr(argvars, rettv) find_some_match(argvars, rettv, 2); } +static void max_min __ARGS((typeval *argvars, typeval *rettv, int domax)); + + static void +max_min(argvars, rettv, domax) + typeval *argvars; + typeval *rettv; + int domax; +{ + listvar *l; + listitem *li; + long n = 0; + long i; + + if (argvars[0].v_type == VAR_LIST) + { + l = argvars[0].vval.v_list; + if (l != NULL) + { + li = l->lv_first; + if (li != NULL) + { + n = get_tv_number(&li->li_tv); + while (1) + { + li = li->li_next; + if (li == NULL) + break; + i = get_tv_number(&li->li_tv); + if (domax ? i > n : i < n) + n = i; + } + } + } + } + else + EMSG(_(e_listreq)); + rettv->vval.v_number = n; +} + +/* + * "max()" function + */ + static void +f_max(argvars, rettv) + typeval *argvars; + typeval *rettv; +{ + max_min(argvars, rettv, TRUE); +} + +/* + * "min()" function + */ + static void +f_min(argvars, rettv) + typeval *argvars; + typeval *rettv; +{ + max_min(argvars, rettv, FALSE); +} + /* * "mode()" function */ @@ -10247,10 +10471,17 @@ f_type(argvars, rettv) typeval *argvars; typeval *rettv; { - if (argvars[0].v_type == VAR_NUMBER) - rettv->vval.v_number = 0; - else - rettv->vval.v_number = 1; + int n; + + switch (argvars[0].v_type) + { + case VAR_NUMBER: n = 0; break; + case VAR_STRING: n = 1; break; + case VAR_FUNC: n = 2; break; + case VAR_LIST: n = 3; break; + default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; + } + rettv->vval.v_number = n; } /* diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -6249,25 +6249,12 @@ gui_mch_get_rgb(guicolor_T pixel) } /* - * Get current y mouse coordinate in text window. - * Return -1 when unknown. + * Get current mouse coordinates in text window. */ - int -gui_mch_get_mouse_x(void) + void +gui_mch_getmouse(int *x, int *y) { - int win_x; - - gdk_window_get_pointer(gui.drawarea->window, &win_x, NULL, NULL); - return win_x; -} - - int -gui_mch_get_mouse_y(void) -{ - int win_y; - - gdk_window_get_pointer(gui.drawarea->window, NULL, &win_y, NULL); - return win_y; + gdk_window_get_pointer(gui.drawarea->window, x, y, NULL); } void diff --git a/src/gui_x11.c b/src/gui_x11.c --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -3276,33 +3276,23 @@ gui_x11_callbacks(textArea, vimForm) } /* - * Get current y mouse coordinate in text window. - * Return -1 when unknown. + * Get current mouse coordinates in text window. */ - int -gui_mch_get_mouse_x() + void +gui_mch_getmouse(int *x, int *y) { int rootx, rooty, winx, winy; Window root, child; unsigned int mask; if (gui.wid && XQueryPointer(gui.dpy, gui.wid, &root, &child, - &rootx, &rooty, &winx, &winy, &mask)) - return winx; - return -1; -} - - int -gui_mch_get_mouse_y() -{ - int rootx, rooty, winx, winy; - Window root, child; - unsigned int mask; - - if (gui.wid && XQueryPointer(gui.dpy, gui.wid, &root, &child, - &rootx, &rooty, &winx, &winy, &mask)) - return winy; - return -1; + &rootx, &rooty, &winx, &winy, &mask)) { + *x = winx; + *y = winy; + } else { + *x = -1; + *y = -1; + } } void diff --git a/src/proto/gui_riscos.pro b/src/proto/gui_riscos.pro --- a/src/proto/gui_riscos.pro +++ b/src/proto/gui_riscos.pro @@ -53,8 +53,7 @@ void gui_mch_start_blink __ARGS((void)); void process_event __ARGS((int event, int *block)); void gui_mch_show_popupmenu __ARGS((vimmenu_T *menu)); long_u gui_mch_get_rgb __ARGS((guicolor_T pixel)); -int gui_mch_get_mouse_x __ARGS((void)); -int gui_mch_get_mouse_y __ARGS((void)); +void gui_mch_getmouse __ARGS((int *x, int *y)); void gui_mch_setmouse __ARGS((int x, int y)); void gui_mch_drawsign __ARGS((int row, int col, int typenr)); void gui_mch_destroy_sign __ARGS((XImage *sign)); diff --git a/src/proto/gui_x11.pro b/src/proto/gui_x11.pro --- a/src/proto/gui_x11.pro +++ b/src/proto/gui_x11.pro @@ -57,8 +57,7 @@ void gui_mch_stop_blink __ARGS((void)); void gui_mch_start_blink __ARGS((void)); long_u gui_mch_get_rgb __ARGS((guicolor_T pixel)); void gui_x11_callbacks __ARGS((Widget textArea, Widget vimForm)); -int gui_mch_get_mouse_x __ARGS((void)); -int gui_mch_get_mouse_y __ARGS((void)); +void gui_mch_getmouse __ARGS((int *x, int *y)); void gui_mch_setmouse __ARGS((int x, int y)); XButtonPressedEvent *gui_x11_get_last_mouse_event __ARGS((void)); void gui_mch_drawsign __ARGS((int row, int col, int typenr));