# HG changeset patch # User vimboss # Date 1134425150 0 # Node ID 35cef95a6b7646d045b97bd4a54bb90000b5a753 # Parent d220eb88e4e45a18694ea2320c736a6fd9ab6cae updated for version 7.0168 diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.0aa. Last change: 2005 Dec 11 +*todo.txt* For Vim version 7.0aa. Last change: 2005 Dec 12 VIM REFERENCE MANUAL by Bram Moolenaar @@ -30,24 +30,6 @@ be worked on, but only if you sponsor Vi *known-bugs* -------------------- Known bugs and current work ----------------------- -When editing a file "a" that is a symbolic link to "b", while another Vim is -editing "b", there is no warning. Follow symlink to make swap file name? -Patch from Stefano Zacchiroli. Updated by James Vega, Dec 2. - -Using pipes for filter commands: provide some way to type a password, keep -stderr in/out open for this? (Konstanti Rozinov) -New problem: password is echoed. Put terminal in cooked mode and don't read -from terminal? - -Allow the user to handle the situation that a swap file already exists. -Option to define a function to be called? Function would return the character -that the dialog provides. Would make it possible to bring the other Vim to -the foreground and abort the edit. Or hard-code this? - -To support mapping to be used as {motion}: Add operator that -executes a user defined function. '[ and '] marks are at start and end of -text. ":map :set opfunc=MyOpgy". - Patch from Yasuhiro Matsumoto: ":e ++enc=xxx" keeps encoding for conversion errors and illegal bytes. Make default to replace bad bytes/characters with '?' and allow for two alternatives: diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.0aa. Last change: 2005 Dec 11 +*version7.txt* For Vim version 7.0aa. Last change: 2005 Dec 12 VIM REFERENCE MANUAL by Bram Moolenaar @@ -29,6 +29,7 @@ Scroll back in messages |new-scroll-ba POSIX compatibility |new-posix| Debugger support |new-debug-support| Remote file explorer |new-netrw-explore| +Define an operator |new-define-operator| Various new items |new-items-7| IMPROVEMENTS |improvements-7| @@ -167,7 +168,7 @@ The 'spellsuggest' option specifies the The |[s| and |]s| commands can be used to move to the next or previous error. The |zg| and |zw| commands can be used to add good and wrong words. -The |z?| command can be used to correct the word. +The |z=| command can be used to correct the word. The |:mkspell| command is used to generate a Vim spell file from word lists. The "undercurl" highlighting attribute was added to nicely point out spelling @@ -341,6 +342,18 @@ and a GUI dialog is not possible. The netrw plugin is maintained by Charles Campbell. +Define an operator *new-define-operator* +------------------ + +Previously it was not possible to define your own operator; a command that is +followed by a {motion}. Vim 7 introduces the 'operatorfunc' option and the +|g@| operator. This makes it possible to define a mapping that works like an +operator. The actual work is then done by a function, which is invoked +through the |g@| operator. + +See |:map-operator| for the explanation and an example. + + Various new items *new-items-7* ----------------- @@ -573,17 +586,19 @@ Mac: GUI font selector. (Peter Cucka) Mac: support for multi-byte characters. (Da Woon Jung) +Mac: Support the xterm mouse in the non-GUI version. + +Mac: better integration with Xcode. Post a fake mouse-up event after the odoc +event and the drag receive handler to work around a stall after Vim loads a +file. Fixed an off-by-one line number error. (Da Woon Jung) + +Added the t_SI and t_EI escape sequences for starting and ending Insert mode. GUI font selector for Motif. (Marcin Dalecki) Nicer toolbar buttons for Motif. (Marcin Dalecki) Mnemonics for the Motif find/replace dialog. (Marcin Dalecki) -Mac: better integration with Xcode. Post a fake mouse-up event after the odoc -event and the drag receive handler to work around a stall after Vim loads a -file. Fixed an off-by-one line number error. (Da Woon Jung) - -Added the t_SI and t_EI escape sequences for starting and ending Insert mode. To be used to set the cursor shape to a bar or a block. No default values, they are not supported by termcap/terminfo. @@ -707,6 +722,10 @@ the swap file to indicate it is in the s used path then doesn't matter and the check for editing the same file is much more reliable. +Unix: When editing a file through a symlink the swap file would use the name +of the symlink. Now use the name of the actual file, so that editing the same +file twice is detected. (suggestions by Stefano Zacchiroli and James Vega) + Client-server communication now supports 'encoding'. When setting 'encoding' in a Vim server to "utf-8", and using "vim --remote fname" in a console, "fname" is converted from the console encoding to utf-8. Also allows Vims @@ -869,6 +888,10 @@ file would be used for the current buffe actually different from the file content. Don't set the file name, unless the 'P' flag is present in 'cpoptions'. +When starting to edit a new file and the directory for the file doesn't exist +then Vim will report "[New DIRECTORY]" instead of "[New File] to give the user +a hint that something might be wrong. + ============================================================================== COMPILE TIME CHANGES *compile-changes-7* @@ -1438,4 +1461,8 @@ the buffer to use "fname", the modified When appending to to current file the "not edited" flag would be reset. ":w" would overwrite the file accidentally. +Unix: When filtering text with an external command Vim would still read input, +causing text typed for the command (e.g., a password) to be eaten and echoed. +Don't read input when the terminal is in cooked mode. + vim:tw=78:ts=8:ft=help:norl: diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -12836,10 +12836,9 @@ f_resolve(argvars, rettv) remain = vim_strsave(q - 1); else { - cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); + cpy = concat_str(q - 1, remain); if (cpy != NULL) { - STRCAT(cpy, remain); vim_free(remain); remain = cpy; } diff --git a/src/memline.c b/src/memline.c --- a/src/memline.c +++ b/src/memline.c @@ -3382,6 +3382,87 @@ ml_lineadd(buf, count) } } +#ifdef HAVE_READLINK +static int resolve_symlink __ARGS((char_u *fname, char_u *buf)); + +/* + * Resolve a symlink in the last component of a file name. + * Note that f_resolve() does it for every part of the path, we don't do that + * here. + * If it worked returns OK and the resolved link in "buf[MAXPATHL]". + * Otherwise returns FAIL. + */ + static int +resolve_symlink(fname, buf) + char_u *fname; + char_u *buf; +{ + char_u tmp[MAXPATHL]; + int ret; + int depth = 0; + + if (fname == NULL) + return FAIL; + + /* Put the result so far in tmp[], starting with the original name. */ + vim_strncpy(tmp, fname, MAXPATHL - 1); + + for (;;) + { + /* Limit symlink depth to 100, catch recursive loops. */ + if (++depth == 100) + { + EMSG2(_("E773: Symlink loop for \"%s\""), fname); + return FAIL; + } + + ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1); + if (ret <= 0) + { + if (errno == EINVAL) /* found non-symlink, stop here */ + { + /* When at the first level use the unmodifed name, skip the + * call to vim_FullName(). */ + if (depth == 1) + return FAIL; + + /* Use the resolved name in tmp[]. */ + break; + } + + /* There must be some error reading links, use original name. */ + return FAIL; + } + buf[ret] = NUL; + + /* + * Check whether the symlink is relative or absolute. + * If it's relative, build a new path based on the directory + * portion of the filename (if any) and the path the symlink + * points to. + */ + if (mch_isFullName(buf)) + STRCPY(tmp, buf); + else + { + char_u *tail; + + tail = gettail(tmp); + if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL) + return FAIL; + STRCPY(tail, buf); + } + } + + /* + * Try to resolve the full name of the file so that the swapfile name will + * be consistent even when opening a relative symlink from different + * working directories. + */ + return vim_FullName(tmp, buf, MAXPATHL, TRUE); +} +#endif + /* * Make swap file name out of the file name and a directory name. * Returns pointer to allocated memory or NULL. @@ -3395,6 +3476,10 @@ makeswapname(fname, ffname, buf, dir_nam char_u *dir_name; { char_u *r, *s; +#ifdef HAVE_READLINK + char_u fname_buf[MAXPATHL]; + char_u *fname_res; +#endif #if defined(UNIX) || defined(WIN3264) /* Need _very_ long file names */ s = dir_name + STRLEN(dir_name); @@ -3410,6 +3495,15 @@ makeswapname(fname, ffname, buf, dir_nam } #endif +#ifdef HAVE_READLINK + /* Expand symlink in the file name, so that we put the swap file with the + * actual file instead of with the symlink. */ + if (resolve_symlink(fname, fname_buf) == OK) + fname_res = fname_buf; + else + fname_res = fname; +#endif + r = buf_modname( #ifdef SHORT_FNAME TRUE, @@ -3420,7 +3514,11 @@ makeswapname(fname, ffname, buf, dir_nam /* Avoid problems if fname has special chars, eg */ ffname, #else +# ifdef HAVE_READLINK + fname_res, +# else fname, +# endif #endif (char_u *) #if defined(VMS) || defined(RISCOS) @@ -3848,7 +3946,17 @@ findswapname(buf, dirp, old_fname) if (fnamecmp(gettail(buf->b_ffname), gettail(b0.b0_fname)) != 0 || !same_directory(fname, buf->b_ffname)) - differ = TRUE; + { +#ifdef CHECK_INODE + /* Symlinks may point to the same file even + * when the name differs, need to check the + * inode too. */ + expand_env(b0.b0_fname, NameBuff, MAXPATHL); + if (fnamecmp_ino(buf->b_ffname, NameBuff, + char_to_long(b0.b0_ino))) +#endif + differ = TRUE; + } } else { @@ -3859,7 +3967,7 @@ findswapname(buf, dirp, old_fname) expand_env(b0.b0_fname, NameBuff, MAXPATHL); #ifdef CHECK_INODE if (fnamecmp_ino(buf->b_ffname, NameBuff, - char_to_long(b0.b0_ino))) + char_to_long(b0.b0_ino))) differ = TRUE; #else if (fnamecmp(NameBuff, buf->b_ffname) != 0) diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -4443,6 +4443,29 @@ vim_ispathlistsep(c) } #endif +/* + * Return TRUE if the directory of "fname" exists, FALSE otherwise. + * Also returns TRUE if there is no directory name. + * "fname" must be writable!. + */ + int +dir_of_file_exists(fname) + char_u *fname; +{ + char_u *p; + int c; + int retval; + + p = gettail_sep(fname); + if (p == fname) + return TRUE; + c = *p; + *p = NUL; + retval = mch_isdir(fname); + *p = c; + return retval; +} + #if (defined(CASE_INSENSITIVE_FILENAME) && defined(BACKSLASH_IN_FILENAME)) \ || defined(PROTO) /* diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro --- a/src/proto/misc1.pro +++ b/src/proto/misc1.pro @@ -1,93 +1,94 @@ /* misc1.c */ -int get_indent __ARGS((void)); -int get_indent_lnum __ARGS((linenr_T lnum)); -int get_indent_buf __ARGS((buf_T *buf, linenr_T lnum)); -int get_indent_str __ARGS((char_u *ptr, int ts)); -int set_indent __ARGS((int size, int flags)); -int get_number_indent __ARGS((linenr_T lnum)); -int open_line __ARGS((int dir, int flags, int old_indent)); -int get_leader_len __ARGS((char_u *line, char_u **flags, int backward)); -int plines __ARGS((linenr_T lnum)); -int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight)); -int plines_nofill __ARGS((linenr_T lnum)); -int plines_win_nofill __ARGS((win_T *wp, linenr_T lnum, int winheight)); -int plines_win_nofold __ARGS((win_T *wp, linenr_T lnum)); -int plines_win_col __ARGS((win_T *wp, linenr_T lnum, long column)); -int plines_m_win __ARGS((win_T *wp, linenr_T first, linenr_T last)); -void ins_bytes __ARGS((char_u *p)); -void ins_bytes_len __ARGS((char_u *p, int len)); -void ins_char __ARGS((int c)); -void ins_char_bytes __ARGS((char_u *buf, int charlen)); -void ins_str __ARGS((char_u *s)); -int del_char __ARGS((int fixpos)); -int del_chars __ARGS((long count, int fixpos)); -int del_bytes __ARGS((long count, int fixpos)); -int truncate_line __ARGS((int fixpos)); -void del_lines __ARGS((long nlines, int undo)); -int gchar_pos __ARGS((pos_T *pos)); -int gchar_cursor __ARGS((void)); -void pchar_cursor __ARGS((int c)); -int inindent __ARGS((int extra)); -char_u *skip_to_option_part __ARGS((char_u *p)); -void changed __ARGS((void)); -void changed_bytes __ARGS((linenr_T lnum, colnr_T col)); -void appended_lines __ARGS((linenr_T lnum, long count)); -void appended_lines_mark __ARGS((linenr_T lnum, long count)); -void deleted_lines __ARGS((linenr_T lnum, long count)); -void deleted_lines_mark __ARGS((linenr_T lnum, long count)); -void changed_lines __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume, long xtra)); -void unchanged __ARGS((buf_T *buf, int ff)); -void check_status __ARGS((buf_T *buf)); -void change_warning __ARGS((int col)); -int ask_yesno __ARGS((char_u *str, int direct)); -int get_keystroke __ARGS((void)); -int get_number __ARGS((int colon, int *mouse_used)); -int prompt_for_number __ARGS((int *mouse_used)); -void msgmore __ARGS((long n)); -void beep_flush __ARGS((void)); -void vim_beep __ARGS((void)); -void init_homedir __ARGS((void)); -void free_homedir __ARGS((void)); -void expand_env __ARGS((char_u *src, char_u *dst, int dstlen)); -void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr)); -char_u *vim_getenv __ARGS((char_u *name, int *mustfree)); -char_u *expand_env_save __ARGS((char_u *src)); -void vim_setenv __ARGS((char_u *name, char_u *val)); -char_u *get_env_name __ARGS((expand_T *xp, int idx)); -void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one)); -char_u *home_replace_save __ARGS((buf_T *buf, char_u *src)); -int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname)); -char_u *gettail __ARGS((char_u *fname)); -char_u *gettail_sep __ARGS((char_u *fname)); -char_u *getnextcomp __ARGS((char_u *fname)); -char_u *get_past_head __ARGS((char_u *path)); -int vim_ispathsep __ARGS((int c)); -int vim_ispathlistsep __ARGS((int c)); -int vim_fnamecmp __ARGS((char_u *x, char_u *y)); -int vim_fnamencmp __ARGS((char_u *x, char_u *y, size_t len)); -char_u *concat_fnames __ARGS((char_u *fname1, char_u *fname2, int sep)); -char_u *concat_str __ARGS((char_u *str1, char_u *str2)); -void add_pathsep __ARGS((char_u *p)); -char_u *FullName_save __ARGS((char_u *fname, int force)); -pos_T *find_start_comment __ARGS((int ind_maxcomment)); -void do_c_expr_indent __ARGS((void)); -int cin_islabel __ARGS((int ind_maxcomment)); -int cin_iscase __ARGS((char_u *s)); -int cin_isscopedecl __ARGS((char_u *s)); -int get_c_indent __ARGS((void)); -int get_expr_indent __ARGS((void)); -int get_lisp_indent __ARGS((void)); -void prepare_to_exit __ARGS((void)); -void preserve_exit __ARGS((void)); -int vim_fexists __ARGS((char_u *fname)); -void line_breakcheck __ARGS((void)); -void fast_breakcheck __ARGS((void)); -int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); -int match_suffix __ARGS((char_u *fname)); -int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags, int didstar)); -int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); -void addfile __ARGS((garray_T *gap, char_u *f, int flags)); -char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags)); -void FreeWild __ARGS((int count, char_u **files)); -int goto_im __ARGS((void)); +extern int get_indent __ARGS((void)); +extern int get_indent_lnum __ARGS((linenr_T lnum)); +extern int get_indent_buf __ARGS((buf_T *buf, linenr_T lnum)); +extern int get_indent_str __ARGS((char_u *ptr, int ts)); +extern int set_indent __ARGS((int size, int flags)); +extern int get_number_indent __ARGS((linenr_T lnum)); +extern int open_line __ARGS((int dir, int flags, int old_indent)); +extern int get_leader_len __ARGS((char_u *line, char_u **flags, int backward)); +extern int plines __ARGS((linenr_T lnum)); +extern int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight)); +extern int plines_nofill __ARGS((linenr_T lnum)); +extern int plines_win_nofill __ARGS((win_T *wp, linenr_T lnum, int winheight)); +extern int plines_win_nofold __ARGS((win_T *wp, linenr_T lnum)); +extern int plines_win_col __ARGS((win_T *wp, linenr_T lnum, long column)); +extern int plines_m_win __ARGS((win_T *wp, linenr_T first, linenr_T last)); +extern void ins_bytes __ARGS((char_u *p)); +extern void ins_bytes_len __ARGS((char_u *p, int len)); +extern void ins_char __ARGS((int c)); +extern void ins_char_bytes __ARGS((char_u *buf, int charlen)); +extern void ins_str __ARGS((char_u *s)); +extern int del_char __ARGS((int fixpos)); +extern int del_chars __ARGS((long count, int fixpos)); +extern int del_bytes __ARGS((long count, int fixpos)); +extern int truncate_line __ARGS((int fixpos)); +extern void del_lines __ARGS((long nlines, int undo)); +extern int gchar_pos __ARGS((pos_T *pos)); +extern int gchar_cursor __ARGS((void)); +extern void pchar_cursor __ARGS((int c)); +extern int inindent __ARGS((int extra)); +extern char_u *skip_to_option_part __ARGS((char_u *p)); +extern void changed __ARGS((void)); +extern void changed_bytes __ARGS((linenr_T lnum, colnr_T col)); +extern void appended_lines __ARGS((linenr_T lnum, long count)); +extern void appended_lines_mark __ARGS((linenr_T lnum, long count)); +extern void deleted_lines __ARGS((linenr_T lnum, long count)); +extern void deleted_lines_mark __ARGS((linenr_T lnum, long count)); +extern void changed_lines __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume, long xtra)); +extern void unchanged __ARGS((buf_T *buf, int ff)); +extern void check_status __ARGS((buf_T *buf)); +extern void change_warning __ARGS((int col)); +extern int ask_yesno __ARGS((char_u *str, int direct)); +extern int get_keystroke __ARGS((void)); +extern int get_number __ARGS((int colon, int *mouse_used)); +extern int prompt_for_number __ARGS((int *mouse_used)); +extern void msgmore __ARGS((long n)); +extern void beep_flush __ARGS((void)); +extern void vim_beep __ARGS((void)); +extern void init_homedir __ARGS((void)); +extern void free_homedir __ARGS((void)); +extern void expand_env __ARGS((char_u *src, char_u *dst, int dstlen)); +extern void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr)); +extern char_u *vim_getenv __ARGS((char_u *name, int *mustfree)); +extern char_u *expand_env_save __ARGS((char_u *src)); +extern void vim_setenv __ARGS((char_u *name, char_u *val)); +extern char_u *get_env_name __ARGS((expand_T *xp, int idx)); +extern void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one)); +extern char_u *home_replace_save __ARGS((buf_T *buf, char_u *src)); +extern int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname)); +extern char_u *gettail __ARGS((char_u *fname)); +extern char_u *gettail_sep __ARGS((char_u *fname)); +extern char_u *getnextcomp __ARGS((char_u *fname)); +extern char_u *get_past_head __ARGS((char_u *path)); +extern int vim_ispathsep __ARGS((int c)); +extern int vim_ispathlistsep __ARGS((int c)); +extern int dir_of_file_exists __ARGS((char_u *fname)); +extern int vim_fnamecmp __ARGS((char_u *x, char_u *y)); +extern int vim_fnamencmp __ARGS((char_u *x, char_u *y, size_t len)); +extern char_u *concat_fnames __ARGS((char_u *fname1, char_u *fname2, int sep)); +extern char_u *concat_str __ARGS((char_u *str1, char_u *str2)); +extern void add_pathsep __ARGS((char_u *p)); +extern char_u *FullName_save __ARGS((char_u *fname, int force)); +extern pos_T *find_start_comment __ARGS((int ind_maxcomment)); +extern void do_c_expr_indent __ARGS((void)); +extern int cin_islabel __ARGS((int ind_maxcomment)); +extern int cin_iscase __ARGS((char_u *s)); +extern int cin_isscopedecl __ARGS((char_u *s)); +extern int get_c_indent __ARGS((void)); +extern int get_expr_indent __ARGS((void)); +extern int get_lisp_indent __ARGS((void)); +extern void prepare_to_exit __ARGS((void)); +extern void preserve_exit __ARGS((void)); +extern int vim_fexists __ARGS((char_u *fname)); +extern void line_breakcheck __ARGS((void)); +extern void fast_breakcheck __ARGS((void)); +extern int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); +extern int match_suffix __ARGS((char_u *fname)); +extern int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags, int didstar)); +extern int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); +extern void addfile __ARGS((garray_T *gap, char_u *f, int flags)); +extern char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags)); +extern void FreeWild __ARGS((int count, char_u **files)); +extern int goto_im __ARGS((void)); /* vim: set ft=c : */