summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/todo.txt20
-rw-r--r--runtime/doc/version7.txt41
-rw-r--r--src/eval.c3
-rw-r--r--src/memline.c112
-rw-r--r--src/misc1.c23
-rw-r--r--src/proto/misc1.pro183
6 files changed, 261 insertions, 121 deletions
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 8535d5c4f..821c47e4b 100644
--- 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 Vim development. See |sponsor|.
*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 <F4> to be used as <F4>{motion}: Add operator that
-executes a user defined function. '[ and '] marks are at start and end of
-text. ":map <F4> :set opfunc=MyOp<CR>gy".
-
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
index a8acddaa8..ead361823 100644
--- 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-back|
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 methods used for making suggestions
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)
-GUI font selector for Motif. (Marcin Dalecki)
-
-Nicer toolbar buttons for Motif. (Marcin Dalecki)
-
-Mnemonics for the Motif find/replace dialog. (Marcin Dalecki)
+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)
+
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 same directory as the edited file. The
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 buffer. But the buffer contents is
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 flag was reset.
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
index a3bf58d35..fe3c5a7ad 100644
--- 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
index a6ab42c4e..a8e4025be 100644
--- 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_name)
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_name)
}
#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_name)
/* Avoid problems if fname has special chars, eg <Wimp$Scrap> */
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
index bef297cf2..cd8acceaa 100644
--- 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
index 584207289..20c7b513f 100644
--- 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 : */