Re: [PATCH] Ignore comments when jumping to a declaration

2016-10-08 Fir de Conversatie Anton Lindqvist
Updated patch attach which adds support for skipping strings and
characters that include the identifier. With the patch applied, pressing
gd in the example below would end up on line 4 as opposed of line 3:

int func(void)
{
  char *s = "x"; // line #3
  int x = 1; // line #4

  return x;
 ^
 |
   cursor
}

While at it, I added a few more tests to cover this new behavior.

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/normal.c b/src/normal.c
index 8302ffb..9a27d3c 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4240,6 +4240,52 @@ nv_gd(
 }
 
 /*
+ * Return TRUE if line[offset] is not inside a C-style comment or string, FALSE
+ * otherwise.
+ */
+static int
+is_ident(char_u *line, int offset)
+{
+inti;
+intincomment = FALSE;
+intinstring = FALSE;
+intprev;
+intstrdel; /* string delimiter character */
+
+for (i = prev = 0; i < offset && line[i] != NUL; i++)
+{
+   if (incomment)
+   {
+   if (prev == '*' && line[i] == '/')
+   incomment = FALSE;
+   }
+   else if (prev == '/' && line[i] == '*')
+   {
+   incomment = TRUE;
+   }
+   else if (prev == '/' && line[i] == '/')
+   {
+   return FALSE;
+   }
+
+   if (instring)
+   {
+   if (prev != '\\' && line[i] == strdel)
+   instring = FALSE;
+   }
+   else if (prev != '\\' && (line[i] == '"' || line[i] == '\''))
+   {
+   instring = TRUE;
+   strdel = line[i];
+   }
+
+   prev = line[i];
+}
+
+return incomment == FALSE && instring == FALSE;
+}
+
+/*
  * Search for variable declaration of "ptr[len]".
  * When "locally" is TRUE in the current function ("gd"), otherwise in the
  * current file ("gD").
@@ -4264,6 +4310,7 @@ find_decl(
 intretval = OK;
 intincll;
 intsearchflags = flags_arg;
+intvalid;
 
 if ((pat = alloc(len + 7)) == NULL)
return FAIL;
@@ -4301,6 +4348,7 @@ find_decl(
 clearpos(_pos);
 for (;;)
 {
+   valid = FALSE;
t = searchit(curwin, curbuf, >w_cursor, FORWARD,
pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum)
@@ -4337,9 +4385,20 @@ find_decl(
continue;
}
 #endif
-   if (!locally)   /* global search: use first match found */
+
+   /* If the current position is not a valid identifier and a previous
+* match is present, favor that one instead. */
+   if ((valid = is_ident(ml_get_curline(), curwin->w_cursor.col)) == FALSE
+   && found_pos.lnum != 0)
+   {
+   curwin->w_cursor = found_pos;
break;
-   if (curwin->w_cursor.lnum >= par_pos.lnum)
+   }
+
+   /* Global search: use first valid match found */
+   if (valid && !locally)
+   break;
+   if (valid && curwin->w_cursor.lnum >= par_pos.lnum)
{
/* If we previously found a valid position, use it. */
if (found_pos.lnum != 0)
@@ -4347,11 +4406,20 @@ find_decl(
break;
}
 
-   /* For finding a local variable and the match is before the "{" search
-* to find a later match.  For K style function declarations this
-* skips the function header without types.  Remove SEARCH_START from
-* flags to avoid getting stuck at one position. */
-   found_pos = curwin->w_cursor;
+   /* For finding a local variable and the match is before the "{" or
+* inside a comment, continue searching.  For K style function
+* declarations this skips the function header without types. */
+   if (!valid)
+   {
+   /* Braces needed due to macro expansion of clearpos. */
+   clearpos(_pos);
+   }
+   else
+   {
+   found_pos = curwin->w_cursor;
+   }
+   /* Remove SEARCH_START from flags to avoid getting stuck at one
+* position. */
searchflags &= ~SEARCH_START;
 }
 
diff --git a/src/testdir/test_goto.vim b/src/testdir/test_goto.vim
index 2afd96b..7ea5169 100644
--- a/src/testdir/test_goto.vim
+++ b/src/testdir/test_goto.vim
@@ -1,20 +1,237 @@
 " Test commands that jump somewhere.
 
-func Test_geeDEE()
+" Create a new buffer using lines and place the cursor on the word after the
+" first occurrence of return and invoke key. The cursor should now be 
positioned
+" at the given line and col.
+func 

[PATCH] Ignore comments when jumping to a declaration

2016-08-29 Fir de Conversatie Anton Lindqvist
Hi,

The goto declaration commands (gd and gD) only discards completely
commented out lines. In the following scenario pressing 'gd' would place
the cursor on the occurrence of x inside the trailing comment:

int func(int x) /* x is an int */
{
  return x;
 ^
 |
  cursor
}

This is by design, the search is not terminated at the first occurrence
of the identifier in order to handle K function declarations
correctly.

The attached patch add support for discarding any type of C-style
comment. Thus, it does not respect the commentstring option. I think
this is reasonable since the behavior of gd and gD is tailored for C
code but occasionally works well with other similar languages. Another
limitation of the attached patch is that it does not recognize nested
multi-line comments (/* /* nested */ */) but should one care?

While at it, improve the test coverage for both gd and gD.

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/normal.c b/src/normal.c
index bbcd618..ce75e90 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4238,6 +4238,46 @@ nv_gd(
 }
 
 /*
+ * Find the first inline C-style comment in line starting from offset. The
+ * comment boundaries (inclusive) will be written to start and end.  Return 
TRUE
+ * if a comment is found, FALSE otherwise.
+ */
+static int
+find_comment(char_u *line, int offset, int *start, int *end)
+{
+inti;
+intincomment = FALSE;
+intprev = 0;
+
+for (i = offset; line[i] != NUL; i++)
+{
+   if (incomment)
+   {
+   if (prev == '*' && line[i] == '/')
+   {
+   *end = i;
+   return TRUE;
+   }
+   }
+   else if (prev == '/' && line[i] == '*')
+   {
+   incomment = TRUE;
+   *start = i > 0 ? i - 1 : 0;
+   }
+   else if (prev == '/' && line[i] == '/')
+   {
+   *start = i > 0 ? i - 1 : 0;
+   *end = *start + STRLEN([i]);
+   return TRUE;
+   }
+
+   prev = line[i];
+}
+
+return FALSE;
+}
+
+/*
  * Search for variable declaration of "ptr[len]".
  * When "locally" is TRUE in the current function ("gd"), otherwise in the
  * current file ("gD").
@@ -4262,6 +4302,9 @@ find_decl(
 intretval = OK;
 intincll;
 intsearchflags = flags_arg;
+intcstart; /* comment start offset */
+intcend;   /* comment end offset */
+intincomment;
 
 if ((pat = alloc(len + 7)) == NULL)
return FAIL;
@@ -4299,6 +4342,7 @@ find_decl(
 clearpos(_pos);
 for (;;)
 {
+   incomment = FALSE;
t = searchit(curwin, curbuf, >w_cursor, FORWARD,
pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum)
@@ -4335,9 +4379,33 @@ find_decl(
continue;
}
 #endif
-   if (!locally)   /* global search: use first match found */
+
+   /* If the identifier is present inside a comment and a previous match is
+* present, favor that one instead. */
+   for (cstart = 0;
+   find_comment(ml_get_curline(), cstart, , ) == TRUE;
+   cstart++)
+   {
+   if (curwin->w_cursor.col > cstart
+   && curwin->w_cursor.col + len < cend)
+   {
+   if (found_pos.lnum != 0)
+   {
+   curwin->w_cursor = found_pos;
+   goto done;
+   }
+   else
+   {
+   incomment = TRUE;
+   break;
+   }
+   }
+   }
+
+   /* Global search: use first match found unless inside comment */
+   if (!incomment && !locally)
break;
-   if (curwin->w_cursor.lnum >= par_pos.lnum)
+   if (!incomment && curwin->w_cursor.lnum >= par_pos.lnum)
{
/* If we previously found a valid position, use it. */
if (found_pos.lnum != 0)
@@ -4345,14 +4413,24 @@ find_decl(
break;
}
 
-   /* For finding a local variable and the match is before the "{" search
-* to find a later match.  For K style function declarations this
-* skips the function header without types.  Remove SEARCH_START from
-* flags to avoid getting stuck at one position. */
-   found_pos = curwin->w_cursor;
+   /* For finding a local variable and the match is before the "{" or
+* inside a comment, continue 

[patch] Fix compiler warning in quickfix.c

2016-07-16 Fir de Conversatie Anton Lindqvist
Hi,
Compiling commit e0d3797 with GCC and -pedantic gives the following
warning:

quickfix.c: In function 'qf_init_ext':
quickfix.c:795: warning: initializer element is not computable at load time
quickfix.c:795: warning: initializer element is not computable at load time

Attached is a patch that gets rid of this warning.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/quickfix.c b/src/quickfix.c
index 4be1d91..fa76e5d 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -792,7 +792,7 @@ qf_init_ext(
 interrmsglen;
 char_u *pattern;
 qfstate_T  state = {NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
-NULL, lnumfirst, lnumlast};
+NULL, 0, 0};
 intcol = 0;
 char_u use_viscol = FALSE;
 inttype = 0;
@@ -816,6 +816,8 @@ qf_init_ext(
 char_u *tail = NULL;
 regmatch_T regmatch;
 
+state.buflnum = lnumfirst;
+state.lnumlast = lnumlast;
 namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf);
 errmsglen = CMDBUFFSIZE + 1;
 errmsg = alloc_id(errmsglen, aid_qf_errmsg);


Re: [patch] Fix quickfix handling of long lines

2016-04-30 Fir de Conversatie Anton Lindqvist
On Sat, Apr 30, 2016 at 01:17:22PM +0200, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > I managed to crash Vim yesterday due to a off-by-one allocation bug
> > related to the quickfix changes. Fixed in the attached patch.
> 
> Well, if I run test_quickfix after including this patch, Vim crashes.
> I found that a statement was missing, setting linelen to len.
> I did some minor cleanups.

Nice catch!

> I'll include it now.  However, the code to increase the size of the
> buffer is repeated three times, would be nice to put it in one place.

Here's a proposal:

  static char_u *
  buffer_alloc(char_u *buf, int *bufsiz, int *newsiz)
  {
  if (*newsiz > LINE_MAXLEN)
  *newsiz = LINE_MAXLEN - 1;

  if (buf == NULL)
  {
  if ((buf = alloc(*newsiz)) == NULL)
  return NULL;
  }
  else
  {
  if (*newsiz < *bufsiz)
  return buf;
  if ((buf = vim_realloc(buf, *newsiz)) == NULL)
  return NULL;
  }

  /* allocation succeed */
  *bufsiz = *newsiz;
  return buf;
  }

Then the following logic:

  linelen = len > LINE_MAXLEN ? LINE_MAXLEN - 1 : len;
  if (growbuf == NULL)
  {
  growbuf = alloc(linelen);
  growbufsiz = linelen;
  }
  else if (linelen > growbufsiz)
  {
  growbuf = vim_realloc(growbuf, linelen);
  if (growbuf == NULL)
  goto qf_init_end;
  growbufsiz = linelen;
  }
  linebuf = growbuf;


... could be replaced with:

  linelen = len;
  if ((growbuf = buffer_alloc(growbuf, , )) == NULL)
  goto qf_init_end;

Would you like me to submit such a patch?

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [patch] Fix quickfix handling of long lines

2016-04-26 Fir de Conversatie Anton Lindqvist
The patch did no longer apply without a conflict, updated patch
attached.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/quickfix.c b/src/quickfix.c
index 510d8dd..cad2877 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -175,6 +175,11 @@ qf_init(
 }
 
 /*
+ * Maximum number of bytes allowed per line while reading a errorfile.
+ */
+#define LINE_MAXLEN 4096
+
+/*
  * Read the errorfile "efile" into memory, line by line, building the error
  * list.
  * Alternative: when "efile" is null read errors from buffer "buf".
@@ -197,8 +202,15 @@ qf_init_ext(
 {
 char_u *namebuf;
 char_u *errmsg;
+interrmsglen;
 char_u *pattern;
 char_u *fmtstr = NULL;
+char_u *growbuf = NULL;
+intgrowbuflen;
+intgrowbufsiz;
+char_u *linebuf;
+intlinelen;
+intdiscard;
 intcol = 0;
 char_u use_viscol = FALSE;
 inttype = 0;
@@ -227,6 +239,7 @@ qf_init_ext(
 char_u *directory = NULL;
 char_u *currfile = NULL;
 char_u *tail = NULL;
+char_u *p_buf = NULL;
 char_u *p_str = NULL;
 listitem_T *p_li = NULL;
 struct dir_stack_T  *file_stack = NULL;
@@ -250,7 +263,8 @@ qf_init_ext(
};
 
 namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf);
-errmsg = alloc_id(CMDBUFFSIZE + 1, aid_qf_errmsg);
+errmsglen = CMDBUFFSIZE + 1;
+errmsg = alloc_id(errmsglen, aid_qf_errmsg);
 pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern);
 if (namebuf == NULL || errmsg == NULL || pattern == NULL)
goto qf_init_end;
@@ -523,10 +537,37 @@ qf_init_ext(
len = (int)STRLEN(p_str);
 
if (len > CMDBUFFSIZE - 2)
-   vim_strncpy(IObuff, p_str, CMDBUFFSIZE - 2);
+   {
+   /*
+* If the line exceeds LINE_MAXLEN exclude the last byte
+* since it's not a NL character.
+*/
+   linelen = len > LINE_MAXLEN ? LINE_MAXLEN - 1 : len;
+   if (growbuf == NULL)
+   {
+   growbuf = alloc(linelen);
+   growbufsiz = linelen;
+   }
+   else if (linelen > growbufsiz)
+   {
+   if ((growbuf = vim_realloc(growbuf,
+   linelen)) == NULL)
+   goto qf_init_end;
+   growbufsiz = linelen;
+   }
+   linebuf = growbuf;
+   }
else
-   vim_strncpy(IObuff, p_str, len);
+   {
+   linebuf = IObuff;
+   linelen = len;
+   }
+   vim_strncpy(linebuf, p_str, linelen);
 
+   /*
+* Increment using len in order to discard the rest of the
+* line if it exceeds LINE_MAXLEN.
+*/
p_str += len;
}
else if (tv->v_type == VAR_LIST)
@@ -541,9 +582,30 @@ qf_init_ext(
 
len = (int)STRLEN(p_li->li_tv.vval.v_string);
if (len > CMDBUFFSIZE - 2)
-   len = CMDBUFFSIZE - 2;
+   {
+   if (linelen > LINE_MAXLEN)
+   linelen = LINE_MAXLEN - 1;
+   if (growbuf == NULL)
+   {
+   growbuf = alloc(linelen);
+   growbufsiz = linelen;
+   }
+   else if (linelen > growbufsiz)
+   {
+   if ((growbuf = vim_realloc(growbuf,
+   linelen)) == NULL)
+   goto qf_init_end;
+   growbufsiz = linelen;
+   }
+   linebuf = growbuf;
+   }
+   else
+   {
+   linebuf = IObuff;
+   linelen = len;
+   }
 
-   vim_strncpy(IObuff, p_li->li_tv.vval.v_string, 

Re: [patch] Add optiontype function

2016-04-13 Fir de Conversatie Anton Lindqvist
On Sun, Mar 27, 2016 at 06:11:10PM +0200, Anton Lindqvist wrote:
> On Sat, Mar 26, 2016 at 04:52:47PM +0100, Bram Moolenaar wrote:
> > 
> > Anton Lindqvist wrote:
> > 
> > > > > Hi,
> > > > > This patch adds a function with the declaration optiontype({option})
> > > > > which returns the type of the given option. I'm currently using it to
> > > > > achieve the following option toggle mapping:
> > > > > 
> > > > >   " :NMapChangeOption[!] {letter} {option} [enable]
> > > > >   "
> > > > >   " Create a normal mode option toggle mapping for {option}. The 
> > > > > mapping key
> > > > >   " sequence will be prefixed with 'co' followed by {letter}.
> > > > >   "
> > > > >   " By default the option will only be changed in the current buffer. 
> > > > > Using [!]
> > > > >   " will change the option globally.
> > > > >   "
> > > > >   " Boolean option example:
> > > > >   "
> > > > >   "   :NMapChangeOption s spell
> > > > >   "
> > > > >   " Pressing 'cos' will toggle the spell option on and off.
> > > > >   "
> > > > >   " Non boolean option example:
> > > > >   "
> > > > >   "   :NMapChangeOption y syntax ON
> > > > >   "
> > > > >   " The optional [enable] argument can be used for string and comma 
> > > > > separated
> > > > >   " list options. Pressing 'coy' will add/remove 'ON' from the syntax 
> > > > > option.
> > > > >   "
> > > > >   " This functionality is borrowed from Tim Pope's unimpaired.vim 
> > > > > plugin.
> > > > >   command! -bang -complete=option -nargs=+ NMapChangeOption
> > > > > \ call s:NMapChangeOption(0, )
> > > > >   func! s:NMapChangeOption(global, letter, option, ...) abort
> > > > > let set = a:global ? 'set' : 'setlocal'
> > > > > let type = optiontype(a:option)
> > > > > if type == 0 " boolean
> > > > >   let rhs = printf(':%s =&%s ? "no" : ""%s',
> > > > > \ set, a:option, a:option)
> > > > > elseif type == 2 " comma separated list
> > > > >   let rhs = printf(':%s %s=&%s !~# "%s" ? "+=" : 
> > > > > "-="%s',
> > > > > \ set, a:option, a:option, a:1, a:1)
> > > > > elseif type == 4 " string
> > > > >   let rhs = printf(':%s %s=&%s == "%s" ? "&" : 
> > > > > "=%s"',
> > > > > \ set, a:option, a:option, a:1, a:1)
> > > > > endif
> > > > > exe 'nnoremap co' . a:letter rhs
> > > > >   endfunc
> > > > > 
> > > > >   NMapChangeOption  c colorcolumn +1
> > > > >   NMapChangeOption! h hlsearch
> > > > >   NMapChangeOption  l list
> > > > >   NMapChangeOption! p paste
> > > > >   NMapChangeOption  s spell
> > > > >   NMapChangeOption  w wrap
> > > > >   NMapChangeOption  y syntax ON
> > > > > 
> > > > > The patch includes tests and docs.
> > > > 
> > > > I can see how this would be useful.  But returning just a number is
> > > > limited.  There are many more properties of an option, such as whether
> > > > it is window-local, was set or not, can be set from a modeline, etc.
> > > > Not that we need to add all those properties now, but I'm sure someone
> > > > will want to add them later.  Perhaps using "optionproperties()" and
> > > > returning a Dictionary?
> > > 
> > > Great feedback. Attached is a revised patch with you ideas applied.
> > > For now the 'optionproperties()' function returns a Dictionary with only
> > > one entry called 'type'.
> > 
> > Thanks.  I wonder if "type" would just return bool/number/string.  Then
> > for a string type there would be a subtype for comma/flaglist.
> > I suppose it depends on what you want to do if you want to know what
> > kind of string option it is.  Also, if we later add another kind (colon
> > separate?) that is also a string, it would still be possible to
>

Re: [patch] Fix quickfix handling of long lines

2016-04-13 Fir de Conversatie Anton Lindqvist
On Sat, Apr 09, 2016 at 04:45:23PM +0200, Anton Lindqvist wrote:
> On Tue, Apr 05, 2016 at 09:56:26PM +0200, Bram Moolenaar wrote:
> > 
> > Anton Lindqvist wrote:
> > 
> > > > > If a file passed to the 'qf_init_ext' function contains lines longer
> > > > > than 1021 bytes (might be platform specific) the rest of the line is
> > > > > recognized as a separate error without a valid filename and lnum. If a
> > > > > string or list is passed to 'qf_init_ext' the rest of a long line is
> > > > > discarded. This patch adds the same behavior while reading errors 
> > > > > from a
> > > > > file. This is done by continue reading from the file in to a temporary
> > > > > buffer until end-of-line is encountered. Could any existing general
> > > > > purpose buffer with a known size be used instead of allocation a new
> > > > > one?
> > > > 
> > > > This code comes from when memory was scarce and error messages were
> > > > short.  Using a fixed size buffer isn't so nice these days.
> > > > 
> > > > A good strategy could be to use IObuff as it is, and when an error
> > > > message is longer then allocate a larger buffer and append to it.
> > > > It does require growing (doubling?) the buffer further until a NL is
> > > > found.  That can be slow, e.g. if the error file has no NL at all
> > > > (that's a mistake, but you don't want Vim to hang then).  So some upper
> > > > limit would still be useful.
> > > 
> > > I would prefer allocating a buffer using BUFSIZ defined in stdio.h and
> > > then make it grow exponentially. Instead of using a upper limit I would
> > > prefer to continue reading until NL/EOF occurs or realloc fails.
> > 
> > Well, if arbitrary long lines are supported, where would they be useful?
> > Certainly not for displaying, it would scroll through many pages.
> > Perhaps for a script that analizes the error further.  But I find that a
> > bit far fetched.  I think a 100 Kbyte limit is very resonable.
> > Especially since currently it's chopped up after 1 Kbyte.
> > 
> > > > I have seen error messages from a test that say "expected
> > > >  but got ".  Not sure what a useful
> > > > upper limit would be.  100 Kbyte perhaps?
> > > 
> > > Reading and displaying the whole line despite its length is a reasonable
> > > behavior nowadays, however like marius@ pointed out I would not mind if
> > > the lines where truncated since they seldom adds value. 
> > > 
> > > > Are you interested in implementing this?
> > > 
> > > Sure! But what's your take on the concerns above?
> > 
> > I think reading into IObuff at first, and using a growing buffer after
> > that would be a good solution.  Probably keep the buffer until all
> > errors are done, if one line is long there is a bigger change of another
> > one.
> 
> Here's a first attempt on implementing the proposed changes. Some notes
> regarding the patch in no particular order:
> 
> - The maximum number of bytes per line is defined at compile-time using
>   LINE_MAXLEN. It's currently set a lower value than the proposed 100Kb
>   for the sake of testing but can easily be adjusted. If changed, the
>   tests needs to adjusted as well.
> 
> - The behavior for long lines is consistent for all types of
>   invocations, reading from a file, list, string or buffer
> 
> - The file `src/testdir/samples/quickfix.txt' is used for the tests.
>   Should it be placed somewhere else?
> 
> - The following logic is removed:
> 
> if ((efmp = vim_strrchr(IObuff, '\n')) != NULL)
>   *efmp = NUL;
> 
>   As far as I can tell this should never be true since any trailing
>   new-line character is removed from the buffer and reading always halts
>   on new-line which implies that only one new-line character can be
>   present in buffer at once.
> 
> Feedback and testing would be much appreciated.

I compiled the changes with a stricter set of flags and discovered two
mixed signedness warnings. Fixed the attached patch.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.

Re: [patch] Fix quickfix handling of long lines

2016-04-09 Fir de Conversatie Anton Lindqvist
On Tue, Apr 05, 2016 at 09:56:26PM +0200, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > > > If a file passed to the 'qf_init_ext' function contains lines longer
> > > > than 1021 bytes (might be platform specific) the rest of the line is
> > > > recognized as a separate error without a valid filename and lnum. If a
> > > > string or list is passed to 'qf_init_ext' the rest of a long line is
> > > > discarded. This patch adds the same behavior while reading errors from a
> > > > file. This is done by continue reading from the file in to a temporary
> > > > buffer until end-of-line is encountered. Could any existing general
> > > > purpose buffer with a known size be used instead of allocation a new
> > > > one?
> > > 
> > > This code comes from when memory was scarce and error messages were
> > > short.  Using a fixed size buffer isn't so nice these days.
> > > 
> > > A good strategy could be to use IObuff as it is, and when an error
> > > message is longer then allocate a larger buffer and append to it.
> > > It does require growing (doubling?) the buffer further until a NL is
> > > found.  That can be slow, e.g. if the error file has no NL at all
> > > (that's a mistake, but you don't want Vim to hang then).  So some upper
> > > limit would still be useful.
> > 
> > I would prefer allocating a buffer using BUFSIZ defined in stdio.h and
> > then make it grow exponentially. Instead of using a upper limit I would
> > prefer to continue reading until NL/EOF occurs or realloc fails.
> 
> Well, if arbitrary long lines are supported, where would they be useful?
> Certainly not for displaying, it would scroll through many pages.
> Perhaps for a script that analizes the error further.  But I find that a
> bit far fetched.  I think a 100 Kbyte limit is very resonable.
> Especially since currently it's chopped up after 1 Kbyte.
> 
> > > I have seen error messages from a test that say "expected
> > >  but got ".  Not sure what a useful
> > > upper limit would be.  100 Kbyte perhaps?
> > 
> > Reading and displaying the whole line despite its length is a reasonable
> > behavior nowadays, however like marius@ pointed out I would not mind if
> > the lines where truncated since they seldom adds value. 
> > 
> > > Are you interested in implementing this?
> > 
> > Sure! But what's your take on the concerns above?
> 
> I think reading into IObuff at first, and using a growing buffer after
> that would be a good solution.  Probably keep the buffer until all
> errors are done, if one line is long there is a bigger change of another
> one.

Here's a first attempt on implementing the proposed changes. Some notes
regarding the patch in no particular order:

- The maximum number of bytes per line is defined at compile-time using
  LINE_MAXLEN. It's currently set a lower value than the proposed 100Kb
  for the sake of testing but can easily be adjusted. If changed, the
  tests needs to adjusted as well.

- The behavior for long lines is consistent for all types of
  invocations, reading from a file, list, string or buffer

- The file `src/testdir/samples/quickfix.txt' is used for the tests.
  Should it be placed somewhere else?

- The following logic is removed:

if ((efmp = vim_strrchr(IObuff, '\n')) != NULL)
  *efmp = NUL;

  As far as I can tell this should never be true since any trailing
  new-line character is removed from the buffer and reading always halts
  on new-line which implies that only one new-line character can be
  present in buffer at once.

Feedback and testing would be much appreciated.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/quickfix.c b/src/quickfix.c
index 00762bd..e5be238 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -175,6 +175,11 @@ qf_init(
 }
 
 /*
+ * Maximum number of bytes allowed per line while reading a errorfile.
+ */
+#define LINE_MAXLEN 4096
+
+/*
  * Read the errorfile "efile" into memory, line by line, building the error
  * list.
  * Alternative: when "efile" is null read errors from buffer "buf".
@@ -197,8 +202,15 @@ qf_init_ext(
 {
 char_u *namebuf;
 char_u *errmsg;
+i

Re: [patch] Add optional argument to bufwinnr to return all windows

2016-04-05 Fir de Conversatie Anton Lindqvist
On Sun, Feb 21, 2016 at 03:15:17PM +0100, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > Hi,
> > This patch adds an optional second argument to the bufwinnr function
> > which if present returns all windows associated with the given buffer
> > across all tabs. This is useful in order to determine if a buffer is
> > present in several windows. I'm currently using this patch in order to
> > get backspace to behave accordingly: if the current buffer is present in
> > other windows than the current one, close the window, otherwise wipe the
> > current buffer.
> > 
> >   nnoremap  :call BufferClose()
> >   func BufferClose()
> > if len(bufwinnr('%', 1)) > 1
> >   wincmd c
> > else
> >   bwipe
> > endif
> >   endfunc
> > 
> > I didn't end up using the FOR_ALL_TAB_WINDOWS macro since I needed to
> > reset winnr and increment tabnr in the outer loop.
> 
> Thanks.  Seems useful.
> 
> I have been thinking of adding a unique window number.  Some plugins
> have problems finding the right window after splitting and closing
> windows.  The current window number changes then, thus it requires
> looping over windows to find the right window.  Netrw had a bug related
> to this.
> 
>   getwinid()   ID of current winow
>   getwinnr({id})   window nr of {id} or -1 if not open
>   gettabnr({id})   tab page nr of {id} or -1 if not open
>   gotowin({id})
> 
> I wonder how this bufwinnr() change fits in.

With the addition of the unique window IDs the returned tabnr and winnr
from bufwinnr() can be used to retrieve the window ID using the new
win_getid() function. Once the window ID is obtain all the new functions
can be utilized.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [patch] Fix quickfix handling of long lines

2016-04-05 Fir de Conversatie Anton Lindqvist
Bram,

On Mon, Apr 04, 2016 at 10:03:22PM +0200, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > If a file passed to the 'qf_init_ext' function contains lines longer
> > than 1021 bytes (might be platform specific) the rest of the line is
> > recognized as a separate error without a valid filename and lnum. If a
> > string or list is passed to 'qf_init_ext' the rest of a long line is
> > discarded. This patch adds the same behavior while reading errors from a
> > file. This is done by continue reading from the file in to a temporary
> > buffer until end-of-line is encountered. Could any existing general
> > purpose buffer with a known size be used instead of allocation a new
> > one?
> 
> This code comes from when memory was scarce and error messages were
> short.  Using a fixed size buffer isn't so nice these days.
> 
> A good strategy could be to use IObuff as it is, and when an error
> message is longer then allocate a larger buffer and append to it.
> It does require growing (doubling?) the buffer further until a NL is
> found.  That can be slow, e.g. if the error file has no NL at all
> (that's a mistake, but you don't want Vim to hang then).  So some upper
> limit would still be useful.

I would prefer allocating a buffer using BUFSIZ defined in stdio.h and
then make it grow exponentially. Instead of using a upper limit I would
prefer to continue reading until NL/EOF occurs or realloc fails.

> I have seen error messages from a test that say "expected
>  but got ".  Not sure what a useful
> upper limit would be.  100 Kbyte perhaps?

Reading and displaying the whole line despite its length is a reasonable
behavior nowadays, however like marius@ pointed out I would not mind if
the lines where truncated since they seldom adds value. 

> Are you interested in implementing this?

Sure! But what's your take on the concerns above?

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[patch] Fix quickfix handling of long lines

2016-04-04 Fir de Conversatie Anton Lindqvist
Hi,
If a file passed to the 'qf_init_ext' function contains lines longer
than 1021 bytes (might be platform specific) the rest of the line is
recognized as a separate error without a valid filename and lnum. If a
string or list is passed to 'qf_init_ext' the rest of a long line is
discarded. This patch adds the same behavior while reading errors from a
file. This is done by continue reading from the file in to a temporary
buffer until end-of-line is encountered. Could any existing general
purpose buffer with a known size be used instead of allocation a new
one?

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/alloc.h b/src/alloc.h
index 90a9878..f1a9bd2 100644
--- a/src/alloc.h
+++ b/src/alloc.h
@@ -17,5 +17,6 @@ typedef enum {
aid_qf_namebuf,
aid_qf_errmsg,
aid_qf_pattern,
+   aid_qf_discard,
aid_last
 } alloc_id_T;
diff --git a/src/quickfix.c b/src/quickfix.c
index 00762bd..739fc89 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -198,6 +198,7 @@ qf_init_ext(
 char_u *namebuf;
 char_u *errmsg;
 char_u *pattern;
+char_u *discard;
 char_u *fmtstr = NULL;
 intcol = 0;
 char_u use_viscol = FALSE;
@@ -216,6 +217,7 @@ qf_init_ext(
 char_u *efm;
 char_u *ptr;
 char_u *srcptr;
+intbuflen;
 intlen;
 inti;
 intround;
@@ -252,7 +254,8 @@ qf_init_ext(
 namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf);
 errmsg = alloc_id(CMDBUFFSIZE + 1, aid_qf_errmsg);
 pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern);
-if (namebuf == NULL || errmsg == NULL || pattern == NULL)
+discard = alloc_id(CMDBUFFSIZE + 1, aid_qf_discard);
+if (namebuf == NULL || errmsg == NULL || pattern == NULL || discard == 
NULL)
goto qf_init_end;
 
 if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL)
@@ -557,8 +560,31 @@ qf_init_ext(
CMDBUFFSIZE - 2);
}
}
-   else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
-   break;
+   else
+   {
+   if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
+   break;
+
+   buflen = (int)STRLEN(IObuff);
+   while (buflen == CMDBUFFSIZE - 2 - 1)
+   {
+   /*
+* End-of-line not yet reached since the number of read bytes is
+* equal to the size of the buffer, excluding null-terminator.
+* Continue reading and discard the rest of the line.
+*/
+   if (fgets((char *)discard, CMDBUFFSIZE - 2, fd) == NULL)
+   break;
+
+   buflen = (int)STRLEN(discard);
+   if (discard[buflen - 1] == '\n'
+#ifdef USE_CRNL
+   || discard[buflen - 1] == '\r'
+#endif
+  )
+   break;
+   }
+   }
 
IObuff[CMDBUFFSIZE - 2] = NUL;  /* for very long lines */
 #ifdef FEAT_MBYTE
@@ -878,6 +904,7 @@ qf_init_end:
 vim_free(errmsg);
 vim_free(pattern);
 vim_free(fmtstr);
+vim_free(discard);
 
 #ifdef FEAT_WINDOWS
 qf_update_buffer(qi);
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 8da1b6f..df2c0a0 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -697,3 +697,14 @@ func Test_cgetexpr_works()
   " this must not crash Vim
   cgetexpr [$x]
 endfunc
+
+func Test_cgetfile_long_lines()
+  let tmp = tempname()
+  exe 'new' tmp
+  normal ifile:1:
+  normal $2000aa
+  w | bw
+  exe 'cgetfile' fnameescape(tmp)
+  call assert_equal(1, len(getqflist()))
+  call assert_true(len(getqflist()[0].text) < 2000)
+endfunc


[patch] Add missing errorformat to GCC compiler

2016-03-31 Fir de Conversatie Anton Lindqvist
Hi,
I contacted the maintainer of the gcc.vim compiler without any response.

I'm currently using the gcc.vim compiler with
g:compiler_gcc_ignore_unmatched_lines enabled. A linker error did not
get recognized as an error on my machine using GCC 4.2.1 on OpenBSD.
Output from GCC:

  cc -O2 -pipe  -pedantic -std=c99 -Wall -Werror -Wextra   -o bug bug.c 
  /tmp//cck5iAWg.o: In function `main':
  bug.c:(.text+0x5): undefined reference to `foo'
  collect2: ld returned 1 exit status
  *** Error 1 in /home/a (:85 'bug')

Attached is a patch including an attempt to resolve this issue.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/compiler/gcc.vim b/runtime/compiler/gcc.vim
index aee31d9..b3150e8 100644
--- a/runtime/compiler/gcc.vim
+++ b/runtime/compiler/gcc.vim
@@ -24,6 +24,7 @@ CompilerSet errorformat=
   \%f:%l:\ %trror:\ %m,
   \%f:%l:\ %tarning:\ %m,
   \%f:%l:\ %m,
+  \%f:\\(%*[^\\)]\\):\ %m,
   \\"%f\"\\,\ line\ %l%*\\D%c%*[^\ ]\ %m,
   \%D%*\\a[%*\\d]:\ Entering\ directory\ [`']%f',
   \%X%*\\a[%*\\d]:\ Leaving\ directory\ [`']%f',


Re: [patch] Add optiontype function

2016-03-27 Fir de Conversatie Anton Lindqvist
On Sat, Mar 26, 2016 at 04:52:47PM +0100, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > > > Hi,
> > > > This patch adds a function with the declaration optiontype({option})
> > > > which returns the type of the given option. I'm currently using it to
> > > > achieve the following option toggle mapping:
> > > > 
> > > >   " :NMapChangeOption[!] {letter} {option} [enable]
> > > >   "
> > > >   " Create a normal mode option toggle mapping for {option}. The 
> > > > mapping key
> > > >   " sequence will be prefixed with 'co' followed by {letter}.
> > > >   "
> > > >   " By default the option will only be changed in the current buffer. 
> > > > Using [!]
> > > >   " will change the option globally.
> > > >   "
> > > >   " Boolean option example:
> > > >   "
> > > >   "   :NMapChangeOption s spell
> > > >   "
> > > >   " Pressing 'cos' will toggle the spell option on and off.
> > > >   "
> > > >   " Non boolean option example:
> > > >   "
> > > >   "   :NMapChangeOption y syntax ON
> > > >   "
> > > >   " The optional [enable] argument can be used for string and comma 
> > > > separated
> > > >   " list options. Pressing 'coy' will add/remove 'ON' from the syntax 
> > > > option.
> > > >   "
> > > >   " This functionality is borrowed from Tim Pope's unimpaired.vim 
> > > > plugin.
> > > >   command! -bang -complete=option -nargs=+ NMapChangeOption
> > > > \ call s:NMapChangeOption(0, )
> > > >   func! s:NMapChangeOption(global, letter, option, ...) abort
> > > > let set = a:global ? 'set' : 'setlocal'
> > > > let type = optiontype(a:option)
> > > > if type == 0 " boolean
> > > >   let rhs = printf(':%s =&%s ? "no" : ""%s',
> > > > \ set, a:option, a:option)
> > > > elseif type == 2 " comma separated list
> > > >   let rhs = printf(':%s %s=&%s !~# "%s" ? "+=" : 
> > > > "-="%s',
> > > > \ set, a:option, a:option, a:1, a:1)
> > > > elseif type == 4 " string
> > > >   let rhs = printf(':%s %s=&%s == "%s" ? "&" : "=%s"',
> > > > \ set, a:option, a:option, a:1, a:1)
> > > > endif
> > > > exe 'nnoremap co' . a:letter rhs
> > > >   endfunc
> > > > 
> > > >   NMapChangeOption  c colorcolumn +1
> > > >   NMapChangeOption! h hlsearch
> > > >   NMapChangeOption  l list
> > > >   NMapChangeOption! p paste
> > > >   NMapChangeOption  s spell
> > > >   NMapChangeOption  w wrap
> > > >   NMapChangeOption  y syntax ON
> > > > 
> > > > The patch includes tests and docs.
> > > 
> > > I can see how this would be useful.  But returning just a number is
> > > limited.  There are many more properties of an option, such as whether
> > > it is window-local, was set or not, can be set from a modeline, etc.
> > > Not that we need to add all those properties now, but I'm sure someone
> > > will want to add them later.  Perhaps using "optionproperties()" and
> > > returning a Dictionary?
> > 
> > Great feedback. Attached is a revised patch with you ideas applied.
> > For now the 'optionproperties()' function returns a Dictionary with only
> > one entry called 'type'.
> 
> Thanks.  I wonder if "type" would just return bool/number/string.  Then
> for a string type there would be a subtype for comma/flaglist.
> I suppose it depends on what you want to do if you want to know what
> kind of string option it is.  Also, if we later add another kind (colon
> separate?) that is also a string, it would still be possible to
> recognize the string if you don't care about the subtype.

It guess it makes sense to assume that in the general use-case one is
only interested of the primitive type of a option, therefore
bool/number/string is sufficient. The attached patch adds two new
entries to the returned dictionary: 'comma' and 'flaglist'.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, 

Re: [patch] Add optiontype function

2016-03-26 Fir de Conversatie Anton Lindqvist
Bram,

On Thu, Mar 24, 2016 at 06:44:39PM +0100, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > Hi,
> > This patch adds a function with the declaration optiontype({option})
> > which returns the type of the given option. I'm currently using it to
> > achieve the following option toggle mapping:
> > 
> >   " :NMapChangeOption[!] {letter} {option} [enable]
> >   "
> >   " Create a normal mode option toggle mapping for {option}. The mapping key
> >   " sequence will be prefixed with 'co' followed by {letter}.
> >   "
> >   " By default the option will only be changed in the current buffer. Using 
> > [!]
> >   " will change the option globally.
> >   "
> >   " Boolean option example:
> >   "
> >   "   :NMapChangeOption s spell
> >   "
> >   " Pressing 'cos' will toggle the spell option on and off.
> >   "
> >   " Non boolean option example:
> >   "
> >   "   :NMapChangeOption y syntax ON
> >   "
> >   " The optional [enable] argument can be used for string and comma 
> > separated
> >   " list options. Pressing 'coy' will add/remove 'ON' from the syntax 
> > option.
> >   "
> >   " This functionality is borrowed from Tim Pope's unimpaired.vim plugin.
> >   command! -bang -complete=option -nargs=+ NMapChangeOption
> > \ call s:NMapChangeOption(0, )
> >   func! s:NMapChangeOption(global, letter, option, ...) abort
> > let set = a:global ? 'set' : 'setlocal'
> > let type = optiontype(a:option)
> > if type == 0 " boolean
> >   let rhs = printf(':%s =&%s ? "no" : ""%s',
> > \ set, a:option, a:option)
> > elseif type == 2 " comma separated list
> >   let rhs = printf(':%s %s=&%s !~# "%s" ? "+=" : "-="%s',
> > \ set, a:option, a:option, a:1, a:1)
> > elseif type == 4 " string
> >   let rhs = printf(':%s %s=&%s == "%s" ? "&" : "=%s"',
> > \ set, a:option, a:option, a:1, a:1)
> > endif
> > exe 'nnoremap co' . a:letter rhs
> >   endfunc
> > 
> >   NMapChangeOption  c colorcolumn +1
> >   NMapChangeOption! h hlsearch
> >   NMapChangeOption  l list
> >   NMapChangeOption! p paste
> >   NMapChangeOption  s spell
> >   NMapChangeOption  w wrap
> >   NMapChangeOption  y syntax ON
> > 
> > The patch includes tests and docs.
> 
> I can see how this would be useful.  But returning just a number is
> limited.  There are many more properties of an option, such as whether
> it is window-local, was set or not, can be set from a modeline, etc.
> Not that we need to add all those properties now, but I'm sure someone
> will want to add them later.  Perhaps using "optionproperties()" and
> returning a Dictionary?

Great feedback. Attached is a revised patch with you ideas applied.
For now the 'optionproperties()' function returns a Dictionary with only
one entry called 'type'.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 642f0ad..3087938 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2023,6 +2023,7 @@ mode( [expr]) String  current editing 
mode
 mzeval( {expr})any evaluate |MzScheme| expression
 nextnonblank( {lnum})  Number  line nr of non-blank line >= {lnum}
 nr2char( {expr}[, {utf8}]) String  single char with ASCII/UTF8 value {expr}
+optionproperties( {option})Dictproperties of option {option}
 or( {expr}, {expr})Number  bitwise OR
 pathshorten( {expr})   String  shorten directory names in a path
 perleval( {expr})  any evaluate |Perl| expression
@@ -5316,6 +5317,20 @@ nr2char({expr}[, {utf8}])
*nr2char()*
characters.  nr2char(0) is a real NUL and terminates the
string, thus results in an empty string.
 
+   *E518*
+optionproperties({option}) *optionproperties()*
+   Ret

[patch] Add optiontype function

2016-03-24 Fir de Conversatie Anton Lindqvist
Hi,
This patch adds a function with the declaration optiontype({option})
which returns the type of the given option. I'm currently using it to
achieve the following option toggle mapping:

  " :NMapChangeOption[!] {letter} {option} [enable]
  "
  " Create a normal mode option toggle mapping for {option}. The mapping key
  " sequence will be prefixed with 'co' followed by {letter}.
  "
  " By default the option will only be changed in the current buffer. Using [!]
  " will change the option globally.
  "
  " Boolean option example:
  "
  "   :NMapChangeOption s spell
  "
  " Pressing 'cos' will toggle the spell option on and off.
  "
  " Non boolean option example:
  "
  "   :NMapChangeOption y syntax ON
  "
  " The optional [enable] argument can be used for string and comma separated
  " list options. Pressing 'coy' will add/remove 'ON' from the syntax option.
  "
  " This functionality is borrowed from Tim Pope's unimpaired.vim plugin.
  command! -bang -complete=option -nargs=+ NMapChangeOption
\ call s:NMapChangeOption(0, )
  func! s:NMapChangeOption(global, letter, option, ...) abort
let set = a:global ? 'set' : 'setlocal'
let type = optiontype(a:option)
if type == 0 " boolean
  let rhs = printf(':%s =&%s ? "no" : ""%s',
\ set, a:option, a:option)
elseif type == 2 " comma separated list
  let rhs = printf(':%s %s=&%s !~# "%s" ? "+=" : "-="%s',
\ set, a:option, a:option, a:1, a:1)
elseif type == 4 " string
  let rhs = printf(':%s %s=&%s == "%s" ? "&" : "=%s"',
\ set, a:option, a:option, a:1, a:1)
endif
exe 'nnoremap co' . a:letter rhs
  endfunc

  NMapChangeOption  c colorcolumn +1
  NMapChangeOption! h hlsearch
  NMapChangeOption  l list
  NMapChangeOption! p paste
  NMapChangeOption  s spell
  NMapChangeOption  w wrap
  NMapChangeOption  y syntax ON

The patch includes tests and docs.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 642f0ad..f411beb 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2023,6 +2023,7 @@ mode( [expr]) String  current editing 
mode
 mzeval( {expr})any evaluate |MzScheme| expression
 nextnonblank( {lnum})  Number  line nr of non-blank line >= {lnum}
 nr2char( {expr}[, {utf8}]) String  single char with ASCII/UTF8 value {expr}
+optiontype( {option})  Number  type of option {option}
 or( {expr}, {expr})Number  bitwise OR
 pathshorten( {expr})   String  shorten directory names in a path
 perleval( {expr})  any evaluate |Perl| expression
@@ -5316,6 +5317,15 @@ nr2char({expr}[, {utf8}])
*nr2char()*
characters.  nr2char(0) is a real NUL and terminates the
string, thus results in an empty string.
 
+optiontype({option})   *optiontype()* *E518*
+   Return the type of {option} as a Number:
+Boolean: 0
+ Number: 1
+   Comma separated list: 2
+ Char flag list: 3
+ String: 4
+   If {option} does not exist, -1 is returned.
+
 or({expr}, {expr}) *or()*
Bitwise OR on the two arguments.  The arguments are converted
to a number.  A List, Dict or Float argument causes an error.
diff --git a/src/eval.c b/src/eval.c
index b233833..38533d8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -682,6 +682,7 @@ static void f_mzeval(typval_T *argvars, typval_T *rettv);
 static void f_nextnonblank(typval_T *argvars, typval_T *rettv);
 static void f_nr2char(typval_T *argvars, typval_T *rettv);
 static void f_or(typval_T *argvars, typval_T *rettv);
+static void f_optiontype(typval_T *argvars, typval_T *rettv);
 static void f_pathshorten(typval_T *argvars, typval_T *rettv);
 #ifdef FEAT_PERL
 static void f_perleval(typval_T *argvars, typval_T *rettv);
@@ -8327,6 +8328,7 @@ static struct fst
 {"nextnonblank",   1, 1, f_nextnonblank},
 {"nr2char",1, 2, f_nr2char},
 {"or", 2, 2, f_or},
+{"optiontype", 1, 1, f_optiontype},
 {"pathshorten",1, 1, f_pathshorten},
 #ifdef FEAT_PERL
 {"perleval",   1, 1, f_perleval},
@@ -15901,6 +15903,22 @@ f_or(typval_T *argvars, typval_T *rettv)
 }
 
 /*
+ * "optiontype(option)" function
+ */
+static void

Re: [patch] Add Error autocmd event

2016-02-27 Fir de Conversatie Anton Lindqvist
On Thu, Feb 25, 2016 at 10:17:34PM +0100, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > Bram,
> > I noticed your comment in todo.txt about the fact that the current
> > solution only remembers the code of last error that occurred. Here's a
> > first attempt address this issue by using an growarray. Caution: I don't
> > know if it's wise to clear the array in the main loop.
> 
> Thanks.  However, I still have doubts about how useful this is.
> Autocommands are tricky as they are, and this one is more tricky then
> others.
> 
> It's not that I don't like your work, I just don't want to make a
> promise to users, which means once this is in we'll have to keep it
> around forever.  Even when we find a better solution eventually.

Sounds reasonable and I respect your judgment.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [patch] Add Error autocmd event

2016-02-25 Fir de Conversatie Anton Lindqvist
Bram,
I noticed your comment in todo.txt about the fact that the current
solution only remembers the code of last error that occurred. Here's a
first attempt address this issue by using an growarray. Caution: I don't
know if it's wise to clear the array in the main loop.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/fileio.c b/src/fileio.c
index ecec757..aaed5cb 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7666,6 +7666,7 @@ static struct event_name
 {"CursorMoved",	EVENT_CURSORMOVED},
 {"CursorMovedI",	EVENT_CURSORMOVEDI},
 {"EncodingChanged",	EVENT_ENCODINGCHANGED},
+{"Error",		EVENT_ERROR},
 {"FileEncoding",	EVENT_ENCODINGCHANGED},
 {"FileAppendPost",	EVENT_FILEAPPENDPOST},
 {"FileAppendPre",	EVENT_FILEAPPENDPRE},
@@ -7725,6 +7726,21 @@ static struct event_name
 {NULL,		(event_T)0}
 };
 
+
+/*
+ * Mapping of error code to pattern used for  when triggering the Error
+ * event.
+ */
+static struct error_pat
+{
+const char	*code;
+const char	*pat;
+} error_pats[] =
+{
+{"E426",	"tagnotfound"},
+{NULL,	NULL}
+};
+
 static AutoPat *first_autopat[NUM_EVENTS] =
 {
 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -9351,7 +9367,7 @@ apply_autocmds_group(
 {
 	sfname = vim_strsave(fname);
 	/* Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
-	 * ColorScheme or QuickFixCmd* */
+	 * ColorScheme, Error or QuickFixCmd* */
 	if (event == EVENT_FILETYPE
 		|| event == EVENT_SYNTAX
 		|| event == EVENT_FUNCUNDEFINED
@@ -9359,6 +9375,7 @@ apply_autocmds_group(
 		|| event == EVENT_SPELLFILEMISSING
 		|| event == EVENT_QUICKFIXCMDPRE
 		|| event == EVENT_COLORSCHEME
+		|| event == EVENT_ERROR
 		|| event == EVENT_OPTIONSET
 		|| event == EVENT_QUICKFIXCMDPOST)
 	fname = vim_strsave(fname);
@@ -9750,20 +9767,26 @@ has_autocmd(event_T event, char_u *sfname, buf_T *buf)
 char_u	*tail = gettail(sfname);
 int		retval = FALSE;
 
-fname = FullName_save(sfname, FALSE);
-if (fname == NULL)
-	return FALSE;
-
+/* don't try expanding Error */
+if (event == EVENT_ERROR) {
+	fname = vim_strsave(sfname);
+	if (fname == NULL)
+	return FALSE;
+} else {
+	fname = FullName_save(sfname, FALSE);
+	if (fname == NULL)
+	return FALSE;
 #ifdef BACKSLASH_IN_FILENAME
-/*
- * Replace all backslashes with forward slashes.  This makes the
- * autocommand patterns portable between Unix and MS-DOS.
- */
-sfname = vim_strsave(sfname);
-if (sfname != NULL)
-	forward_slash(sfname);
-forward_slash(fname);
+	/*
+	 * Replace all backslashes with forward slashes.  This makes the
+	 * autocommand patterns portable between Unix and MS-DOS.
+	 */
+	sfname = vim_strsave(sfname);
+	if (sfname != NULL)
+	forward_slash(sfname);
+	forward_slash(fname);
 #endif
+}
 
 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
 	if (ap->pat != NULL && ap->cmds != NULL
@@ -10358,3 +10381,23 @@ write_eintr(int fd, void *buf, size_t bufsize)
 return ret;
 }
 #endif
+
+#ifdef FEAT_AUTOCMD
+/*
+ * Get the corresponding pattern for the given error message code. The returned
+ * value is used for  when triggering the Error autocmd event.
+ */
+char_u *
+get_error_pat(char_u *code)
+{
+size_t	len;
+int		i;
+
+len = STRLEN(code);
+for (i = 0; error_pats[i].code; i++)
+	if (STRNCMP(error_pats[i].code, code, len) == 0)
+	return (char_u *)error_pats[i].pat;
+
+return NULL;
+}
+#endif
diff --git a/src/globals.h b/src/globals.h
index 4c1b41f..cb46510 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -184,6 +184,11 @@ EXTERN int	did_emsg;		/* set by emsg() when the message
 EXTERN int	did_emsg_syntax;	/* did_emsg set because of a
 	   syntax error */
 EXTERN int	called_emsg;		/* always set by emsg() */
+#ifdef FEAT_AUTOCMD
+EXTERN garray_T	emsg_codes;		/* grow array containing the latest
+	   error message codes set by
+	   emsg(). */
+#endif
 EXTERN int	ex_exitval INIT(= 0);	/* exit value for ex mode */
 EXTERN int	emsg_on_display INIT(= FALSE);	/* there is an error message */
 EXTERN int	rc_did_emsg INIT(= FALSE);  /* vim_regcomp() called emsg() */
diff --git a/src/main.c b/src/main.c
index e412641..6edc369 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1278,6 +1278,22 @@ main_loop(
 		fileinfo(FALSE, TRUE, FALSE);
 		need_fileinfo = FALSE;
 	}
+#ifdef FEAT_AUTOCMD
+	if (emsg_codes.ga_len) {
+		for (int i = 0; i < emsg_codes.ga_len; ++i)
+		{
+		char_u *code = ((char_u 

Re: [patch] Add Error autocmd event

2016-02-22 Fir de Conversatie Anton Lindqvist
Realized I was using my personal preference for cinoptions. Here's a
revised patch with correct indentation.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/fileio.c b/src/fileio.c
index ecec757..aaed5cb 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7666,6 +7666,7 @@ static struct event_name
 {"CursorMoved",	EVENT_CURSORMOVED},
 {"CursorMovedI",	EVENT_CURSORMOVEDI},
 {"EncodingChanged",	EVENT_ENCODINGCHANGED},
+{"Error",		EVENT_ERROR},
 {"FileEncoding",	EVENT_ENCODINGCHANGED},
 {"FileAppendPost",	EVENT_FILEAPPENDPOST},
 {"FileAppendPre",	EVENT_FILEAPPENDPRE},
@@ -7725,6 +7726,21 @@ static struct event_name
 {NULL,		(event_T)0}
 };
 
+
+/*
+ * Mapping of error code to pattern used for  when triggering the Error
+ * event.
+ */
+static struct error_pat
+{
+const char	*code;
+const char	*pat;
+} error_pats[] =
+{
+{"E426",	"tagnotfound"},
+{NULL,	NULL}
+};
+
 static AutoPat *first_autopat[NUM_EVENTS] =
 {
 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -9351,7 +9367,7 @@ apply_autocmds_group(
 {
 	sfname = vim_strsave(fname);
 	/* Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
-	 * ColorScheme or QuickFixCmd* */
+	 * ColorScheme, Error or QuickFixCmd* */
 	if (event == EVENT_FILETYPE
 		|| event == EVENT_SYNTAX
 		|| event == EVENT_FUNCUNDEFINED
@@ -9359,6 +9375,7 @@ apply_autocmds_group(
 		|| event == EVENT_SPELLFILEMISSING
 		|| event == EVENT_QUICKFIXCMDPRE
 		|| event == EVENT_COLORSCHEME
+		|| event == EVENT_ERROR
 		|| event == EVENT_OPTIONSET
 		|| event == EVENT_QUICKFIXCMDPOST)
 	fname = vim_strsave(fname);
@@ -9750,20 +9767,26 @@ has_autocmd(event_T event, char_u *sfname, buf_T *buf)
 char_u	*tail = gettail(sfname);
 int		retval = FALSE;
 
-fname = FullName_save(sfname, FALSE);
-if (fname == NULL)
-	return FALSE;
-
+/* don't try expanding Error */
+if (event == EVENT_ERROR) {
+	fname = vim_strsave(sfname);
+	if (fname == NULL)
+	return FALSE;
+} else {
+	fname = FullName_save(sfname, FALSE);
+	if (fname == NULL)
+	return FALSE;
 #ifdef BACKSLASH_IN_FILENAME
-/*
- * Replace all backslashes with forward slashes.  This makes the
- * autocommand patterns portable between Unix and MS-DOS.
- */
-sfname = vim_strsave(sfname);
-if (sfname != NULL)
-	forward_slash(sfname);
-forward_slash(fname);
+	/*
+	 * Replace all backslashes with forward slashes.  This makes the
+	 * autocommand patterns portable between Unix and MS-DOS.
+	 */
+	sfname = vim_strsave(sfname);
+	if (sfname != NULL)
+	forward_slash(sfname);
+	forward_slash(fname);
 #endif
+}
 
 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
 	if (ap->pat != NULL && ap->cmds != NULL
@@ -10358,3 +10381,23 @@ write_eintr(int fd, void *buf, size_t bufsize)
 return ret;
 }
 #endif
+
+#ifdef FEAT_AUTOCMD
+/*
+ * Get the corresponding pattern for the given error message code. The returned
+ * value is used for  when triggering the Error autocmd event.
+ */
+char_u *
+get_error_pat(char_u *code)
+{
+size_t	len;
+int		i;
+
+len = STRLEN(code);
+for (i = 0; error_pats[i].code; i++)
+	if (STRNCMP(error_pats[i].code, code, len) == 0)
+	return (char_u *)error_pats[i].pat;
+
+return NULL;
+}
+#endif
diff --git a/src/globals.h b/src/globals.h
index 4c1b41f..4342b71 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -184,6 +184,10 @@ EXTERN int	did_emsg;		/* set by emsg() when the message
 EXTERN int	did_emsg_syntax;	/* did_emsg set because of a
 	   syntax error */
 EXTERN int	called_emsg;		/* always set by emsg() */
+#ifdef FEAT_AUTOCMD
+EXTERN char_u	*emsg_code INIT(= NULL);/* last error message code set by
+	   emsg() */
+#endif
 EXTERN int	ex_exitval INIT(= 0);	/* exit value for ex mode */
 EXTERN int	emsg_on_display INIT(= FALSE);	/* there is an error message */
 EXTERN int	rc_did_emsg INIT(= FALSE);  /* vim_regcomp() called emsg() */
diff --git a/src/main.c b/src/main.c
index e412641..43671e9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1278,6 +1278,20 @@ main_loop(
 		fileinfo(FALSE, TRUE, FALSE);
 		need_fileinfo = FALSE;
 	}
+#ifdef FEAT_AUTOCMD
+	if (did_emsg && emsg_code) {
+		char_u *pat = get_error_pat(emsg_code);
+		if (pat && has_autocmd(EVENT_ERROR, pat, curbuf))
+		apply_autocmds(EVENT_ERROR, pat, curbuf->b_fname, FALSE,
+			curbuf);
+		else if (has_autocmd(EVENT_ERROR, emsg_code, curbuf))
+		apply_autocmds(EVENT_ERROR, emsg_code, 

Re: [patch] Add optional argument to bufwinnr to return all windows

2016-02-21 Fir de Conversatie Anton Lindqvist
On Sun, Feb 21, 2016 at 03:15:17PM +0100, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > Hi,
> > This patch adds an optional second argument to the bufwinnr function
> > which if present returns all windows associated with the given buffer
> > across all tabs. This is useful in order to determine if a buffer is
> > present in several windows. I'm currently using this patch in order to
> > get backspace to behave accordingly: if the current buffer is present in
> > other windows than the current one, close the window, otherwise wipe the
> > current buffer.
> > 
> >   nnoremap  :call BufferClose()
> >   func BufferClose()
> > if len(bufwinnr('%', 1)) > 1
> >   wincmd c
> > else
> >   bwipe
> > endif
> >   endfunc
> > 
> > I didn't end up using the FOR_ALL_TAB_WINDOWS macro since I needed to
> > reset winnr and increment tabnr in the outer loop.
> 
> Thanks.  Seems useful.
> 
> I have been thinking of adding a unique window number.  Some plugins
> have problems finding the right window after splitting and closing
> windows.  The current window number changes then, thus it requires
> looping over windows to find the right window.  Netrw had a bug related
> to this.
> 
>   getwinid()   ID of current winow
>   getwinnr({id})   window nr of {id} or -1 if not open
>   gettabnr({id})   tab page nr of {id} or -1 if not open
>   gotowin({id})
> 
> I wonder how this bufwinnr() change fits in.

Unique window numbers sounds like a great addition. The bufwinnr()
function could then return a list unique window numbers instead of a
list of dictionaries. If the window number is unique it should be all
the data needed in order to interact/manipulate the window using the
functions mentioned.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[patch] Add optional argument to bufwinnr to return all windows

2016-02-21 Fir de Conversatie Anton Lindqvist
Hi,
This patch adds an optional second argument to the bufwinnr function
which if present returns all windows associated with the given buffer
across all tabs. This is useful in order to determine if a buffer is
present in several windows. I'm currently using this patch in order to
get backspace to behave accordingly: if the current buffer is present in
other windows than the current one, close the window, otherwise wipe the
current buffer.

  nnoremap  :call BufferClose()
  func BufferClose()
if len(bufwinnr('%', 1)) > 1
  wincmd c
else
  bwipe
endif
  endfunc

I didn't end up using the FOR_ALL_TAB_WINDOWS macro since I needed to
reset winnr and increment tabnr in the outer loop.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 9ec893f..3bcac94 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2436,7 +2436,7 @@ bufnr({expr} [, {create}])
 			*last_buffer_nr()*
 		Obsolete name for bufnr("$"): last_buffer_nr().
 
-bufwinnr({expr})	*bufwinnr()*
+bufwinnr({expr} [, {all}])	*bufwinnr()*
 		The result is a Number, which is the number of the first
 		window associated with buffer {expr}.  For the use of {expr},
 		see |bufname()| above.	If buffer {expr} doesn't exist or
@@ -2446,7 +2446,16 @@ bufwinnr({expr})	*bufwinnr()*
 
 <		The number can be used with |CTRL-W_w| and ":wincmd w"
 		|:wincmd|.
-		Only deals with the current tab page.
+		If the {all} argument is present and not zero a list including
+		all windows associated with buffer {expr} across all tabs is
+		returned. Each list item is a dictionary with these entries:
+			tabnr	number of the tab the window is associated
+with
+			winnr	number of the window associated with buffer
+{expr}
+
+		If buffer {expr} doesn't exist or there is no such window, a
+		empty list is returned.
 
 byte2line({byte})	*byte2line()*
 		Return the line number that contains the character at byte
diff --git a/src/eval.c b/src/eval.c
index 781cd3d..3e330aa 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -8115,7 +8115,7 @@ static struct fst
 {"bufloaded",	1, 1, f_bufloaded},
 {"bufname",		1, 1, f_bufname},
 {"bufnr",		1, 2, f_bufnr},
-{"bufwinnr",	1, 1, f_bufwinnr},
+{"bufwinnr",	1, 2, f_bufwinnr},
 {"byte2line",	1, 1, f_byte2line},
 {"byteidx",		2, 2, f_byteidx},
 {"byteidxcomp",	2, 2, f_byteidxcomp},
@@ -9666,7 +9666,11 @@ f_bufnr(typval_T *argvars, typval_T *rettv)
 f_bufwinnr(typval_T *argvars, typval_T *rettv)
 {
 #ifdef FEAT_WINDOWS
+tabpage_T	*tp;
 win_T	*wp;
+dict_T	*dict;
+int		error = FALSE;
+int		tabnr = 0;
 int		winnr = 0;
 #endif
 buf_T	*buf;
@@ -9675,13 +9679,40 @@ f_bufwinnr(typval_T *argvars, typval_T *rettv)
 ++emsg_off;
 buf = get_buf_tv([0], TRUE);
 #ifdef FEAT_WINDOWS
-for (wp = firstwin; wp; wp = wp->w_next)
+if (argvars[1].v_type != VAR_UNKNOWN
+	&& get_tv_number_chk([1], ) != 0
+	&& !error)
 {
-	++winnr;
-	if (wp->w_buffer == buf)
-	break;
+	if (rettv_list_alloc(rettv) == FAIL)
+	return;
+	for (tp = first_tabpage; tp; tp = tp->tp_next) {
+	++tabnr;
+	winnr = 0;
+	for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
+		wp;
+		wp = wp->w_next)
+	{
+		++winnr;
+		if (wp->w_buffer == buf)
+		if ((dict = dict_alloc()) == NULL
+			|| list_append_dict(rettv->vval.v_list,
+dict) == FAIL
+			|| dict_add_nr_str(dict, "tabnr", (long)tabnr,
+NULL) == FAIL
+			|| dict_add_nr_str(dict, "winnr", (long)winnr,
+NULL) == FAIL)
+			return;
+	}
+	}
+} else {
+	for (wp = firstwin; wp; wp = wp->w_next)
+	{
+	++winnr;
+	if (wp->w_buffer == buf)
+		break;
+	}
+	rettv->vval.v_number = (wp != NULL ? winnr : -1);
 }
-rettv->vval.v_number = (wp != NULL ? winnr : -1);
 #else
 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1);
 #endif


Re: [patch] Add Error autocmd event

2016-02-17 Fir de Conversatie Anton Lindqvist
Updated patch attached which adds a missing autocmd feature check.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/fileio.c b/src/fileio.c
index ecec757..aaed5cb 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7666,6 +7666,7 @@ static struct event_name
 {"CursorMoved",	EVENT_CURSORMOVED},
 {"CursorMovedI",	EVENT_CURSORMOVEDI},
 {"EncodingChanged",	EVENT_ENCODINGCHANGED},
+{"Error",		EVENT_ERROR},
 {"FileEncoding",	EVENT_ENCODINGCHANGED},
 {"FileAppendPost",	EVENT_FILEAPPENDPOST},
 {"FileAppendPre",	EVENT_FILEAPPENDPRE},
@@ -7725,6 +7726,21 @@ static struct event_name
 {NULL,		(event_T)0}
 };
 
+
+/*
+ * Mapping of error code to pattern used for  when triggering the Error
+ * event.
+ */
+static struct error_pat
+{
+const char	*code;
+const char	*pat;
+} error_pats[] =
+{
+{"E426",	"tagnotfound"},
+{NULL,	NULL}
+};
+
 static AutoPat *first_autopat[NUM_EVENTS] =
 {
 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -9351,7 +9367,7 @@ apply_autocmds_group(
 {
 	sfname = vim_strsave(fname);
 	/* Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
-	 * ColorScheme or QuickFixCmd* */
+	 * ColorScheme, Error or QuickFixCmd* */
 	if (event == EVENT_FILETYPE
 		|| event == EVENT_SYNTAX
 		|| event == EVENT_FUNCUNDEFINED
@@ -9359,6 +9375,7 @@ apply_autocmds_group(
 		|| event == EVENT_SPELLFILEMISSING
 		|| event == EVENT_QUICKFIXCMDPRE
 		|| event == EVENT_COLORSCHEME
+		|| event == EVENT_ERROR
 		|| event == EVENT_OPTIONSET
 		|| event == EVENT_QUICKFIXCMDPOST)
 	fname = vim_strsave(fname);
@@ -9750,20 +9767,26 @@ has_autocmd(event_T event, char_u *sfname, buf_T *buf)
 char_u	*tail = gettail(sfname);
 int		retval = FALSE;
 
-fname = FullName_save(sfname, FALSE);
-if (fname == NULL)
-	return FALSE;
-
+/* don't try expanding Error */
+if (event == EVENT_ERROR) {
+	fname = vim_strsave(sfname);
+	if (fname == NULL)
+	return FALSE;
+} else {
+	fname = FullName_save(sfname, FALSE);
+	if (fname == NULL)
+	return FALSE;
 #ifdef BACKSLASH_IN_FILENAME
-/*
- * Replace all backslashes with forward slashes.  This makes the
- * autocommand patterns portable between Unix and MS-DOS.
- */
-sfname = vim_strsave(sfname);
-if (sfname != NULL)
-	forward_slash(sfname);
-forward_slash(fname);
+	/*
+	 * Replace all backslashes with forward slashes.  This makes the
+	 * autocommand patterns portable between Unix and MS-DOS.
+	 */
+	sfname = vim_strsave(sfname);
+	if (sfname != NULL)
+	forward_slash(sfname);
+	forward_slash(fname);
 #endif
+}
 
 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
 	if (ap->pat != NULL && ap->cmds != NULL
@@ -10358,3 +10381,23 @@ write_eintr(int fd, void *buf, size_t bufsize)
 return ret;
 }
 #endif
+
+#ifdef FEAT_AUTOCMD
+/*
+ * Get the corresponding pattern for the given error message code. The returned
+ * value is used for  when triggering the Error autocmd event.
+ */
+char_u *
+get_error_pat(char_u *code)
+{
+size_t	len;
+int		i;
+
+len = STRLEN(code);
+for (i = 0; error_pats[i].code; i++)
+	if (STRNCMP(error_pats[i].code, code, len) == 0)
+	return (char_u *)error_pats[i].pat;
+
+return NULL;
+}
+#endif
diff --git a/src/globals.h b/src/globals.h
index 4c1b41f..4342b71 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -184,6 +184,10 @@ EXTERN int	did_emsg;		/* set by emsg() when the message
 EXTERN int	did_emsg_syntax;	/* did_emsg set because of a
 	   syntax error */
 EXTERN int	called_emsg;		/* always set by emsg() */
+#ifdef FEAT_AUTOCMD
+EXTERN char_u	*emsg_code INIT(= NULL);/* last error message code set by
+	   emsg() */
+#endif
 EXTERN int	ex_exitval INIT(= 0);	/* exit value for ex mode */
 EXTERN int	emsg_on_display INIT(= FALSE);	/* there is an error message */
 EXTERN int	rc_did_emsg INIT(= FALSE);  /* vim_regcomp() called emsg() */
diff --git a/src/main.c b/src/main.c
index e412641..aad656a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1278,6 +1278,20 @@ main_loop(
 		fileinfo(FALSE, TRUE, FALSE);
 		need_fileinfo = FALSE;
 	}
+#ifdef FEAT_AUTOCMD
+	if (did_emsg && emsg_code) {
+		char_u *pat = get_error_pat(emsg_code);
+		if (pat && has_autocmd(EVENT_ERROR, pat, curbuf))
+		apply_autocmds(EVENT_ERROR, pat, curbuf->b_fname, FALSE,
+   curbuf);
+		else if (has_autocmd(EVENT_ERROR, emsg_code, curbuf))
+		apply_autocmds(EVENT_ERROR, emsg_code, curbuf->b_fname,
+   FALSE, curbuf);
+
+		

Re: [patch] Add Error autocmd event

2016-02-14 Fir de Conversatie Anton Lindqvist
Here's a revised patch including a more rigorous way of parsing the error code
from a error message.

Another use-case I've been trying recently: if wrapscan is initially disabled,
enable it when the search hits top/bottom. This way one is notified that the
search reached the end but pressing n/N again will temporary enable wrapscan in
order to redo the search from the opposite end.

  set nowrapscan
  let s:wrapscan = 0

  func! s:ToggleWrapScan(rhs) abort
if s:wrapscan
  set wrapscan
  let s:wrapscan = 0
else
  set nowrapscan
endif
return a:rhs
  endfunc
  nnoremap  n ToggleWrapScan('n')
  nnoremap  N ToggleWrapScan('N')

  augroup error
au! Error E38[45] let s:wrapscan = 1
  augroup END

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/fileio.c b/src/fileio.c
index ecec757..9a1e294 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7666,6 +7666,7 @@ static struct event_name
 {"CursorMoved",	EVENT_CURSORMOVED},
 {"CursorMovedI",	EVENT_CURSORMOVEDI},
 {"EncodingChanged",	EVENT_ENCODINGCHANGED},
+{"Error",		EVENT_ERROR},
 {"FileEncoding",	EVENT_ENCODINGCHANGED},
 {"FileAppendPost",	EVENT_FILEAPPENDPOST},
 {"FileAppendPre",	EVENT_FILEAPPENDPRE},
@@ -7725,6 +7726,21 @@ static struct event_name
 {NULL,		(event_T)0}
 };
 
+
+/*
+ * Mapping of error code to pattern used for  when triggering the Error
+ * event.
+ */
+static struct error_pat
+{
+const char	*code;
+const char	*pat;
+} error_pats[] =
+{
+{"E426",	"tagnotfound"},
+{NULL,	NULL}
+};
+
 static AutoPat *first_autopat[NUM_EVENTS] =
 {
 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -9351,7 +9367,7 @@ apply_autocmds_group(
 {
 	sfname = vim_strsave(fname);
 	/* Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
-	 * ColorScheme or QuickFixCmd* */
+	 * ColorScheme, Error or QuickFixCmd* */
 	if (event == EVENT_FILETYPE
 		|| event == EVENT_SYNTAX
 		|| event == EVENT_FUNCUNDEFINED
@@ -9359,6 +9375,7 @@ apply_autocmds_group(
 		|| event == EVENT_SPELLFILEMISSING
 		|| event == EVENT_QUICKFIXCMDPRE
 		|| event == EVENT_COLORSCHEME
+		|| event == EVENT_ERROR
 		|| event == EVENT_OPTIONSET
 		|| event == EVENT_QUICKFIXCMDPOST)
 	fname = vim_strsave(fname);
@@ -9750,20 +9767,26 @@ has_autocmd(event_T event, char_u *sfname, buf_T *buf)
 char_u	*tail = gettail(sfname);
 int		retval = FALSE;
 
-fname = FullName_save(sfname, FALSE);
-if (fname == NULL)
-	return FALSE;
-
+/* don't try expanding Error */
+if (event == EVENT_ERROR) {
+	fname = vim_strsave(sfname);
+	if (fname == NULL)
+	return FALSE;
+} else {
+	fname = FullName_save(sfname, FALSE);
+	if (fname == NULL)
+	return FALSE;
 #ifdef BACKSLASH_IN_FILENAME
-/*
- * Replace all backslashes with forward slashes.  This makes the
- * autocommand patterns portable between Unix and MS-DOS.
- */
-sfname = vim_strsave(sfname);
-if (sfname != NULL)
-	forward_slash(sfname);
-forward_slash(fname);
+	/*
+	 * Replace all backslashes with forward slashes.  This makes the
+	 * autocommand patterns portable between Unix and MS-DOS.
+	 */
+	sfname = vim_strsave(sfname);
+	if (sfname != NULL)
+	forward_slash(sfname);
+	forward_slash(fname);
 #endif
+}
 
 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
 	if (ap->pat != NULL && ap->cmds != NULL
@@ -10358,3 +10381,22 @@ write_eintr(int fd, void *buf, size_t bufsize)
 return ret;
 }
 #endif
+
+
+/*
+ * Get the corresponding pattern for the given error message code. The returned
+ * value is used for  when triggering the Error autocmd event.
+ */
+char_u *
+get_error_pat(char_u *code)
+{
+size_t	len;
+int		i;
+
+len = STRLEN(code);
+for (i = 0; error_pats[i].code; i++)
+	if (STRNCMP(error_pats[i].code, code, len) == 0)
+	return (char_u *)error_pats[i].pat;
+
+return NULL;
+}
diff --git a/src/globals.h b/src/globals.h
index 4c1b41f..4342b71 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -184,6 +184,10 @@ EXTERN int	did_emsg;		/* set by emsg() when the message
 EXTERN int	did_emsg_syntax;	/* did_emsg set because of a
 	   syntax error */
 EXTERN int	called_emsg;		/* always set by emsg() */
+#ifdef FEAT_AUTOCMD
+EXTERN char_u	*emsg_code INIT(= NULL);/* last error message code set by
+	   emsg() */
+#endif
 EXTERN int	ex_exitval INIT(= 0);	/* exit value for ex mode */
 EXTERN int	emsg_on_display INIT(= FALSE);	/* there is an error message */
 EXTERN int	rc_did_emsg 

Re: [patch] Add Error autocmd event

2016-02-09 Fir de Conversatie Anton Lindqvist
Bram,

On Mon, Feb 08, 2016 at 10:57:37PM +0100, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > This is a result of a previous discussion[1] which concluded that a
> > more general Error autocmd event would be a better addition than the
> > proposed TagNotFound event.
> > 
> > Questions and comments regarding the patch in no particular order:
> > 
> > - Is the addition to the main_loop function at a suitable location?
> > 
> > - The error code (emsg_code) is the actual code including the 'E' prefix.
> >   Another solution is to use the numerical representation of the error code.
> > 
> > - The get_error_pat function is used to translate error codes into something
> >   more descriptive. As of writing this only one such mapping is
> >   present. We could either ensure that all possible error codes has a
> >   mapping or add them on demand. The function is doing a linear search
> >   of error_pats. If the error code is represented as an int this could
> >   be replaced with a constant lookup if the array index is equal to
> >   the error code:
> > 
> > static const char *error_pat[] = {
> >   [426] = "tagnotfound",
> > }
> > 
> >   If mappings of all possible error codes is present the array won't end up
> >   being that sparse.
> > 
> >   The existing solution (representing error codes as string) could also be
> >   improved by replacing the linear search with a binary search.
> > 
> > - If no mapping of the error code to pattern is found the actual error
> >   code is used as the amatch argument when triggering the Error event.
> > 
> > [1] https://groups.google.com/d/msg/vim_dev/XzhNNjbtfow/u6BWsne4CwAJ
> 
> I am wondering if this is really a useful solution.
> 
> At least in scripts one can already use try/catch to deal with errors.
> Thus this patch is mainly for when typing commands.
> 
> The original reason was to handle an error for a tag lookup.  With the
> solution the tag lookup will still fail.  It can trigger rebuilding the
> tags file, but for most users it will be quite unexpected that trying to
> jump to the same tag suddenly works a bit later.

The creation of the tags file when missing was just an example of a use-case of
my own and is of course a opt-in usage of the new event.

> Can you think of a command or situation where this patch provides a
> nice, useful solution?

Other than the examples already provided, here's a couple of ideas:

- Opening a new file in a non existing directory and then write triggers a E212
  which could be caught and then before writing again try to create the
  directory (%:h) of the file.

- The SpellFileMissing autocmd event could probably be implemented using the
  Error event instead. However this might not a suitable idea since it would
  require keeping the old event for backwards compability.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [patch] Add TagNotFound autocmd event

2016-02-08 Fir de Conversatie Anton Lindqvist
Hi,
See the new patch[1].

[1] https://groups.google.com/d/msg/vim_dev/3_Mn38Jk3N0/W3TQ0g1WDQAJ

On Sat, Feb 06, 2016 at 03:28:37PM +0100, Bram Moolenaar wrote:
> 
> Anton Lindqvist wrote:
> 
> > On Thu, Feb 04, 2016 at 09:36:21PM +0100, Christian Brabandt wrote:
> > > While I agree that this is useful, I have been thinking, if a more 
> > > general approach would not be more useful. Something like an Error 
> > > autocommand, that triggers on the EXXX numbers?
> > 
> > I really like this idea, especially if  would be the actual
> > error message since it would allow people to get creative. Having
> > limited experience with the Vim codebase: would it be feasible to
> > trigger the autocmd event somewhere along the call stack for the emsg
> > functions? At first glance it looks like that solution would require
> > less changes. Compared to adding a explicit call to apply_autocmds
> > prior calling any of the emsg functions.
> 
> Although this sounds like a nice general solution, it will require the
> code that gives the error message to be prepared for an autocommand
> kicking in.  Otherwise, whatever the autocommand does may completely
> mess up what the code was doing.  We have had many autocommands cause
> trouble and still fixing more.
> 
> So the code would explicitly check for an autocommand that handles the
> error.  And since we need to do that, we might as well use a nicer name
> than the error number.  That also helps for when there can be multiple
> errors.  E.g. "tagnotfound" is much nicer than matching a list of error
> codes.  And more error codes could be added later.
> 
> An alternative would be to match the error code, but not trigger the
> autocommand yet.  In the main loop we can then check for  the matches
> and execute the autocommand.  That is a lot safer and simpler.
> 
> Nevertheless, you probably want to do something more clever, since after
> rebuilding the tags file you would want to search for a match again.
> 
> -- 
> hundred-and-one symptoms of being an internet addict:
> 151. You find yourself engaged to someone you've never actually met,
>  except through e-mail.
> 
>  /// Bram Moolenaar -- b...@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///

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [patch] Add TagNotFound autocmd event

2016-02-06 Fir de Conversatie Anton Lindqvist
On Thu, Feb 04, 2016 at 10:04:44PM +0100, Christian Brabandt wrote:
> On Do, 04 Feb 2016, Anton Lindqvist wrote:
> 
> > On Thu, Feb 04, 2016 at 09:36:21PM +0100, Christian Brabandt wrote:
> > > While I agree that this is useful, I have been thinking, if a more
> > > general approach would not be more useful. Something like an Error
> > > autocommand, that triggers on the EXXX numbers?
> > 
> > I really like this idea, especially if  would be the actual
> > error message since it would allow people to get creative. Having
> > limited experience with the Vim codebase: would it be feasible to
> > trigger the autocmd event somewhere along the call stack for the emsg
> > functions? At first glance it looks like that solution would require
> > less changes. Compared to adding a explicit call to apply_autocmds
> > prior calling any of the emsg functions.
> 
> That's what my half working patch did. It is here:
> https://github.com/chrisbra/vim-mq-patches/blob/master/error_aucmd
> you might want to look into it. Never got around finishing it. 

Christian,
I am able to apply your patch and it works fine. Here's an example of a
potential use-case of mine:

  " Run ctags if the tag file is missing (E433) or the tag was not found (E426)
  augroup ctags
au! Error E4\(26\|33\)* silent exe '!ctags'
  augroup END

Are you aware of any bugs with your patch or other potential gotchas that needs
to be resolved?

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [patch] Add TagNotFound autocmd event

2016-02-05 Fir de Conversatie Anton Lindqvist
On Thu, Feb 04, 2016 at 10:04:44PM +0100, Christian Brabandt wrote:
> That's what my half working patch did. It is here:
> https://github.com/chrisbra/vim-mq-patches/blob/master/error_aucmd
> you might want to look into it. Never got around finishing it. 

Thanks, I will try to finish your patch.

-- 
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [patch] Add TagNotFound autocmd event

2016-02-04 Fir de Conversatie Anton Lindqvist
Christian,

On Thu, Feb 04, 2016 at 09:36:21PM +0100, Christian Brabandt wrote:
> While I agree that this is useful, I have been thinking, if a more 
> general approach would not be more useful. Something like an Error 
> autocommand, that triggers on the EXXX numbers?

I really like this idea, especially if  would be the actual error
message since it would allow people to get creative. Having limited experience
with the Vim codebase: would it be feasible to trigger the autocmd event
somewhere along the call stack for the emsg functions? At first glance it looks
like that solution would require less changes. Compared to adding a explicit
call to apply_autocmds prior calling any of the emsg functions.

--
:wq

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[patch] Add TagNotFound autocmd event

2016-02-03 Fir de Conversatie Anton Lindqvist
Hi,
This patch add a autocmd event called TagNotFound triggered when the requested
tag was not found. The motivation for this event is as follows: I usually add
the following to my vimrc in order to ensure my tags file is up-to-date:

  au BufWritePost * if filereadable('tags') | silent exe '!ctags -a %' | endif

However this seems wasteful since the majority of my writes don't include new
identifiers to be indexed. With this patch the command above could be replaced
with:

  au TagNotFound * if filereadable('tags') | silent exe '!ctags' | endif

Thus indexing would only be performed when a missing tag is requested. 

Another use-case for this new event would be to trigger a psearch when the tag
was not found:

  au TagNotFound * exe 'psearch /' . expand('') . '/'

BTW: what's the recommended cinoptions for the Vim codebase?

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 4de5b16..06f1578 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -284,6 +284,7 @@ Name			triggered by ~
 |SpellFileMissing|	a spell file is used but it can't be found
 |SourcePre|		before sourcing a Vim script
 |SourceCmd|		before sourcing a Vim script |Cmd-event|
+|TagNotFound|		the tag was not found in the tag file(s)
 
 |VimResized|		after the Vim window size changed
 |FocusGained|		Vim got input focus
@@ -879,6 +880,10 @@ TabEnter			Just after entering a tab page. |tab-page|
 TabLeave			Just before leaving a tab page. |tab-page|
 A WinLeave event will have been triggered
 first.
+			*TagNotFound*
+TagNotFound			When the requested tag was not found in the
+tag file(s). The pattern is matched against
+the tag name.  is the tag name.
 			*TermChanged*
 TermChanged			After the value of 'term' has changed.  Useful
 for re-loading the syntax file to update the
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index 8186678..55d8d97 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -820,7 +820,8 @@ Note: these are typed literally, they are not special keys!
 	   When executing autocommands, is replaced with the match for
 		   which this autocommand was executed.  It differs from
 		only when the file name isn't used to match with
-		   (for FileType, Syntax and SpellFileMissing events).
+		   (for FileType, Syntax, SpellFileMissing and TagNotFound
+		   events).
 	When executing a ":source" command, is replaced with the
 		   file name of the sourced file.  *E498*
 		   When executing a function, is replaced with:
diff --git a/src/Makefile b/src/Makefile
index 8fd59fb..1a65333 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -565,7 +565,7 @@ CClink = $(CC)
 # When using -g with some older versions of Linux you might get a
 # statically linked executable.
 # When not defined, configure will try to use -O2 -g for gcc and -O for cc.
-#CFLAGS = -g
+CFLAGS = -g -O0
 #CFLAGS = -O
 
 # Optimization limits - depends on the compiler.  Automatic check in configure
@@ -1108,7 +1108,7 @@ INSTALL_DATA_R	= cp -r
 
 ### Program to run on installed binary.  Use the second one to disable strip.
 #STRIP = strip
-#STRIP = /bin/true
+STRIP = /bin/true
 
 ### Permissions for binaries  {{{1
 BINMOD = 755
diff --git a/src/fileio.c b/src/fileio.c
index ecec757..fa2ec72 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7711,6 +7711,7 @@ static struct event_name
 {"Syntax",		EVENT_SYNTAX},
 {"TabEnter",	EVENT_TABENTER},
 {"TabLeave",	EVENT_TABLEAVE},
+{"TagNotFound",	EVENT_TAGNOTFOUND},
 {"TermChanged",	EVENT_TERMCHANGED},
 {"TermResponse",	EVENT_TERMRESPONSE},
 {"TextChanged",	EVENT_TEXTCHANGED},
@@ -9357,6 +9358,7 @@ apply_autocmds_group(
 		|| event == EVENT_FUNCUNDEFINED
 		|| event == EVENT_REMOTEREPLY
 		|| event == EVENT_SPELLFILEMISSING
+		|| event == EVENT_TAGNOTFOUND
 		|| event == EVENT_QUICKFIXCMDPRE
 		|| event == EVENT_COLORSCHEME
 		|| event == EVENT_OPTIONSET
diff --git a/src/tag.c b/src/tag.c
index d2fdee6..b24212e 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -569,6 +569,10 @@ do_tag(
 
 	if (num_matches <= 0)
 	{
+#ifdef FEAT_AUTOCMD
+	apply_autocmds(EVENT_TAGNOTFOUND, name, curbuf->b_fname,
+			   FALSE, curbuf);
+#endif
 	if (verbose)
 		EMSG2(_("E426: tag not found: %s"), name);
 #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
diff --git a/src/vim.h b/src/vim.h
index 18610f5..80491d0 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1314,6 +1314,7 @@ enum auto_event
 EVENT_TEXTCHANGEDI,		/* text was modified in Insert 

Re: [patch] Add TagNotFound autocmd event

2016-02-03 Fir de Conversatie Anton Lindqvist
Den onsdag 3 februari 2016 kl. 14:04:46 UTC+1 skrev Anton Lindqvist:
> Hi,
> This patch add a autocmd event called TagNotFound triggered when the requested
> tag was not found. The motivation for this event is as follows: I usually add
> the following to my vimrc in order to ensure my tags file is up-to-date:
> 
>   au BufWritePost * if filereadable('tags') | silent exe '!ctags -a %' | endif
> 
> However this seems wasteful since the majority of my writes don't include new
> identifiers to be indexed. With this patch the command above could be replaced
> with:
> 
>   au TagNotFound * if filereadable('tags') | silent exe '!ctags' | endif
> 
> Thus indexing would only be performed when a missing tag is requested. 
> 
> Another use-case for this new event would be to trigger a psearch when the tag
> was not found:
> 
>   au TagNotFound * exe 'psearch /' . expand('') . '/'
> 
> BTW: what's the recommended cinoptions for the Vim codebase?

A unintentional change to one of the Makefile was present in the patch. See the 
attached revised patch.

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 4de5b16..06f1578 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -284,6 +284,7 @@ Name			triggered by ~
 |SpellFileMissing|	a spell file is used but it can't be found
 |SourcePre|		before sourcing a Vim script
 |SourceCmd|		before sourcing a Vim script |Cmd-event|
+|TagNotFound|		the tag was not found in the tag file(s)
 
 |VimResized|		after the Vim window size changed
 |FocusGained|		Vim got input focus
@@ -879,6 +880,10 @@ TabEnter			Just after entering a tab page. |tab-page|
 TabLeave			Just before leaving a tab page. |tab-page|
 A WinLeave event will have been triggered
 first.
+			*TagNotFound*
+TagNotFound			When the requested tag was not found in the
+tag file(s). The pattern is matched against
+the tag name.  is the tag name.
 			*TermChanged*
 TermChanged			After the value of 'term' has changed.  Useful
 for re-loading the syntax file to update the
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index 8186678..55d8d97 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -820,7 +820,8 @@ Note: these are typed literally, they are not special keys!
 	   When executing autocommands, is replaced with the match for
 		   which this autocommand was executed.  It differs from
 		only when the file name isn't used to match with
-		   (for FileType, Syntax and SpellFileMissing events).
+		   (for FileType, Syntax, SpellFileMissing and TagNotFound
+		   events).
 	When executing a ":source" command, is replaced with the
 		   file name of the sourced file.  *E498*
 		   When executing a function, is replaced with:
diff --git a/src/fileio.c b/src/fileio.c
index ecec757..fa2ec72 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7711,6 +7711,7 @@ static struct event_name
 {"Syntax",		EVENT_SYNTAX},
 {"TabEnter",	EVENT_TABENTER},
 {"TabLeave",	EVENT_TABLEAVE},
+{"TagNotFound",	EVENT_TAGNOTFOUND},
 {"TermChanged",	EVENT_TERMCHANGED},
 {"TermResponse",	EVENT_TERMRESPONSE},
 {"TextChanged",	EVENT_TEXTCHANGED},
@@ -9357,6 +9358,7 @@ apply_autocmds_group(
 		|| event == EVENT_FUNCUNDEFINED
 		|| event == EVENT_REMOTEREPLY
 		|| event == EVENT_SPELLFILEMISSING
+		|| event == EVENT_TAGNOTFOUND
 		|| event == EVENT_QUICKFIXCMDPRE
 		|| event == EVENT_COLORSCHEME
 		|| event == EVENT_OPTIONSET
diff --git a/src/tag.c b/src/tag.c
index d2fdee6..b24212e 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -569,6 +569,10 @@ do_tag(
 
 	if (num_matches <= 0)
 	{
+#ifdef FEAT_AUTOCMD
+	apply_autocmds(EVENT_TAGNOTFOUND, name, curbuf->b_fname,
+			   FALSE, curbuf);
+#endif
 	if (verbose)
 		EMSG2(_("E426: tag not found: %s"), name);
 #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
diff --git a/src/vim.h b/src/vim.h
index 18610f5..80491d0 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1314,6 +1314,7 @@ enum auto_event
 EVENT_TEXTCHANGEDI,		/* text was modified in Insert mode*/
 EVENT_CMDUNDEFINED,		/* command undefined */
 EVENT_OPTIONSET,		/* option was set */
+EVENT_TAGNOTFOUND,		/* tag not found */
 NUM_EVENTS			/* MUST be the last one */
 };
 


[patch] syntax manual bug

2016-02-01 Fir de Conversatie Anton Lindqvist
Hi,
I'm using manual syntax highlighting and discovered a bug when moving between
buffers. How to reproduce:

  1. Create files:

 $ cat >vimrc <1.vim <2.vim