Each buffer in own tab/function lookup seem to clash

63 views
Skip to first unread message

Henry Combrinck

unread,
Sep 30, 2013, 10:01:17 AM9/30/13
to v...@vim.org
Greets,

I've tried this on vim 7.3 and 7.4.

The problem:  if I enable "au BufAdd,BufNewFile...", then C-] often jumps to the incorrect position in the file containing a function/subroutine declaration.  This happens whether I use the call to MatchCaseTag() or not.

If I disable "au BufAdd,BufNewFile...", then it always jumps to the correct position - without fail.  But having vim remember my cursor position per file is indispensable.

My .vimrc contains:

set ai
set tabstop=4
set shiftwidth=4
syntax on
set expandtab
set smarttab
set smartindent
set backspace=indent,eol,start
set tags+=tags;~

" don't format/autoindent pasted text
nnoremap <F2> :set invpaste paste?<CR>
set pastetoggle=<F2>
set showmode

" remember last cursor position
if has("autocmd")
  au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif

" toggle last search term highlighting
"map  <F12> :set hls!<CR>
"imap <F12> <ESC>:set hls!<CR>a
"vmap <F12> <ESC>:set hls!<CR>gv
map  <C-h> :set hls!<CR>
imap <C-h> <ESC>:set hls!<CR>a
vmap <C-h> <ESC>:set hls!<CR>gv

" uppercase current word
map <C-u> gUiw
" lowercase current word
map <C-l> guiw

" switch off last found highlight
map ; /adfadf<CR><C-g>

map <C-]> :call MatchCaseTag()<CR>
" following is so g] works on class::method
set iskeyword+=:
nmap <C-Enter> <C-w><C-]><C-w>T


set hlsearch
highlight MatchParen ctermbg=yellow guibg=yellow

set showtabline=2               " File tabs allways visible
" c-pageup/down switches tabs
" :tabnew etc

" each buffer in it's own tab.
au BufAdd,BufNewFile * nested tab sball

"set nocompatible
map OA k
map <Down> j
map <Left> h
map <Right> l

fun! MatchCaseTag()
    let ic = &ic
    set noic
    try
        exe 'tjump ' . expand('<cword>')
    finally
       let &ic = ic
    endtry
endfun

" auto-add comments
set formatoptions+=r

" check with :make
autocmd FileType perl set makeprg=perl\ -c\ %\ $*
autocmd FileType perl set errorformat=%f:%l:%m
autocmd FileType perl set autowrite

" Tidy selected lines (or entire file) with _t:
" (perltidy does not exist on eros)
nnoremap <silent> _t :%!perltidy -q<Enter>
vnoremap <silent> _t :!perltidy -q<Enter>

" my perl includes pod
let perl_include_pod = 1
" syntax color complex things like @{${"foo"}}
let perl_extended_vars = 1

---

I'd appreciate any pointers on what I'm doing incorrectly.

Thanks
Henry

Ben Fritz

unread,
Sep 30, 2013, 11:01:54 AM9/30/13
to vim...@googlegroups.com, v...@vim.org
On Monday, September 30, 2013 9:01:17 AM UTC-5, Henry Combrinck wrote:
>
>
> The problem:  if I enable "au BufAdd,BufNewFile...", then C-] often
> jumps to the incorrect position in the file containing a
> function/subroutine declaration.  This happens whether I use the call
> to MatchCaseTag() or not.
>
>
> If I disable "au BufAdd,BufNewFile...", then it always jumps to the
> correct position - without fail.  But having vim remember my cursor
> position per file is indispensable.
>

OK, but why are you mentioning the remembered cursor position? If I
understand your .vimrc (below) correctly, that's a completely separate
autocmd that (so far) hasn't entered into your description.

But maybe it's one culprit.

> My .vimrc contains:
>
> [snip]
>
> " remember last cursor position
> if has("autocmd")
>   au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
> endif
>
> [snip]
>
> map <C-]> :call MatchCaseTag()<CR>
> " following is so g] works on class::method
> set iskeyword+=:
>
> nmap <C-Enter> <C-w><C-]><C-w>T

Side note: Is this last mapping necessary? You have an autocmd to
already force a new buffer into a new tab. What's this one for? Opening
a new tab for existing buffers?

> [snip]
>
> " each buffer in it's own tab.
> au BufAdd,BufNewFile * nested tab sball
>
> "set nocompatible
> map OA k
> map <Down> j
> map <Left> h
> map <Right> l
>

Side note: By default Vim already moves around in every mode when you
use the arrow keys, I don't think these mappings are needed.

>
> fun! MatchCaseTag()
>     let ic = &ic
>     set noic
>     try
>         exe 'tjump ' . expand('<cword>')
>     finally
>        let &ic = ic
>     endtry
> endfun
>
> " auto-add comments
>
>
> I'd appreciate any pointers on what I'm doing incorrectly.
>

Your first problem is trying to force one-buffer-per-tab in all
situations. That's always a recipe for headaches. But with that "maybe
you should reconsider" note, I'll try to work with you here.

It seems like the BuffAdd event fires before the file is actually read
into the buffer. For after the file gets read, there is the BufRead
event. So, your autocmd to force new buffers into tabs is messing with
window layout and all sorts of things before Vim has any text to jump to
to find the tag. Without any more details, I'd suggest trying a few
other buffer related events, trying to get one which happens as late as
possible in the process of opening the buffer so it has less chance of
interfering with commands in progress.

If that doesn't work, you could try modifying your MatchCaseTag function
to issue a second tjump command in case the first doesn't work. It's a
hack, but maybe it will fix your problem.

Other than that, I think we need more info. Is there a pattern to the
location in the new file where the bad tag jump takes you? Is it the
last edited position, restored by your BufReadPost autocmd? Is it the
same line number as the file you're jumping from, but in the new file?
Somewhere else? No discernible pattern at all? This may give some clues.

You can also try removing that BufReadPost autocmd temporarily to see
whether it plays into this problem. I know you want to keep that one,
but perhaps it needs tweaking to not fire while doing a tag jump via
your function.

Henry Combrinck

unread,
Oct 1, 2013, 1:24:02 AM10/1/13
to vim...@googlegroups.com, v...@vim.org
Thanks for the detailed response Ben -

On Monday, September 30, 2013 5:01:54 PM UTC+2, Ben Fritz wrote:
> > nmap <C-Enter> <C-w><C-]><C-w>T
>
>
>
> Side note: Is this last mapping necessary? You have an autocmd to
>
> already force a new buffer into a new tab. What's this one for? Opening
>
> a new tab for existing buffers?

You can ignore this one - it was an experiment which I forgot to remove before posting my query.


> > map OA k
>
> > map <Down> j
>
> > map <Left> h
>
> > map <Right> l
>
>
>
> Side note: By default Vim already moves around in every mode when you
>
> use the arrow keys, I don't think these mappings are needed.

This was me trying to get terminals to work correctly on an older Solaris machine which had old crappy terminfos - I eventually got it to work, so left this as-is.


> Your first problem is trying to force one-buffer-per-tab in all
>
> situations. That's always a recipe for headaches. But with that "maybe
>
> you should reconsider" note, I'll try to work with you here.

I hear you - It would be nice to perhaps get a new buffer only when I hit C-].


> It seems like the BuffAdd event fires before the file is actually read
>
> into the buffer. For after the file gets read, there is the BufRead
>
> event. So, your autocmd to force new buffers into tabs is messing with
>
> window layout and all sorts of things before Vim has any text to jump to
>
> to find the tag. Without any more details, I'd suggest trying a few
>
> other buffer related events, trying to get one which happens as late as
>
> possible in the process of opening the buffer so it has less chance of
>
> interfering with commands in progress.
>
>
>
> If that doesn't work, you could try modifying your MatchCaseTag function
>
> to issue a second tjump command in case the first doesn't work. It's a
>
> hack, but maybe it will fix your problem.
>
>
>
> Other than that, I think we need more info. Is there a pattern to the
>
> location in the new file where the bad tag jump takes you? Is it the
>
> last edited position, restored by your BufReadPost autocmd? Is it the
>
> same line number as the file you're jumping from, but in the new file?
>
> Somewhere else? No discernible pattern at all? This may give some clues.
>
>
>
> You can also try removing that BufReadPost autocmd temporarily to see
>
> whether it plays into this problem. I know you want to keep that one,
>
> but perhaps it needs tweaking to not fire while doing a tag jump via
>
> your function.

If I disable BufReadPost, then this is what happens:

C-] on a function call (A) in file (1) opens a new tab, but positions the cursor at the top of file (2), not on the function declaration itself.

If I then close the tab (returning to the original file (1)), and hit C-] again (on the same function call (A)), it then jumps to file (2) correctly positioning the cursor on the function declaration, but interestingly, does not open file (2) in a new tab, but instead re-uses the existing one (as it would if the function declaration was in the same file).

If enable BufReadPost, but disable au BufAdd,BufNewFile..., then all works perfectly, but without tabs obviously.

I'll continue scratching around, but any suggestions are welcome.

Regards
Henry

Ben Fritz

unread,
Oct 1, 2013, 11:18:59 AM10/1/13
to vim...@googlegroups.com, v...@vim.org
On Tuesday, October 1, 2013 12:24:02 AM UTC-5, Henry Combrinck wrote:
> > It seems like the BuffAdd event fires before the file is actually read
> > into the buffer. For after the file gets read, there is the BufRead
> > event. So, your autocmd to force new buffers into tabs is messing with
> > window layout and all sorts of things before Vim has any text to jump to
> > to find the tag. Without any more details, I'd suggest trying a few
> > other buffer related events, trying to get one which happens as late as
> > possible in the process of opening the buffer so it has less chance of
> > interfering with commands in progress.
> >
> > If that doesn't work, you could try modifying your MatchCaseTag function
> > to issue a second tjump command in case the first doesn't work. It's a
> > hack, but maybe it will fix your problem.
> >
> > Other than that, I think we need more info. Is there a pattern to the
> > location in the new file where the bad tag jump takes you? Is it the
> > last edited position, restored by your BufReadPost autocmd? Is it the
> > same line number as the file you're jumping from, but in the new file?
> > Somewhere else? No discernible pattern at all? This may give some clues.
> > You can also try removing that BufReadPost autocmd temporarily to see
> > whether it plays into this problem. I know you want to keep that one,
> > but perhaps it needs tweaking to not fire while doing a tag jump via
> > your function.
>
> If I disable BufReadPost, then this is what happens:
>
> C-] on a function call (A) in file (1) opens a new tab, but positions the
> cursor at the top of file (2), not on the function declaration itself.
>

Ok, so if you're not setting position on a BufRead, then your BufAdd autocmd
causes the file to open in a new tab. But Vim loses track of the fact that
it is in the middle of jumping somewhere. Probably this is because you're
messing with windows and such before Vim even reads in the buffer contents.

> If I then close the tab (returning to the original file (1)), and hit C-]
> again (on the same function call (A)), it then jumps to file (2) correctly
> positioning the cursor on the function declaration, but interestingly,
> does not open file (2) in a new tab, but instead re-uses the existing one
> (as it would if the function declaration was in the same file).

I bet this is because the buffer is already in your buffer list, so BufAdd
doesn't fire. How did you close the tab? You can try using :bdelete or
:bwipe instead of :tabclose or :close or :quit to see if that makes a
difference. But I think BufAdd is just the wrong event to use for this
autocmd, because it causes this problem and also potentially the problem
with interrupting a tag jump.

>
> If enable BufReadPost, but disable au BufAdd,BufNewFile..., then all works
> perfectly, but without tabs obviously.
>

I think instead of BuffAdd, I'd first try BufWinEnter. If that doesn't work,
then maybe BufReadPost would work.

Henry Combrinck

unread,
Oct 2, 2013, 2:08:02 AM10/2/13
to vim...@googlegroups.com, v...@vim.org

I normally close the tab with :q, but :bdelete and :bwipe do the same.

> >
> > If enable BufReadPost, but disable au BufAdd,BufNewFile..., then all works
> > perfectly, but without tabs obviously.
> >
>
> I think instead of BuffAdd, I'd first try BufWinEnter. If that doesn't work,
> then maybe BufReadPost would work.

Spent some time brushing up on events at
http://vimdoc.sourceforge.net/htmldoc/autocmd.html#{event}

Sadly, "au BufWinEnter * nested tab sball" results in the error
"E435: Couldn't find tag, just guessing"

And so does "au BufReadPost * nested tab sball"

At times like this I wish I could slip into an alternate universe for a few weeks or months and study the problem to the exclusion of all else in as much depth as required until a solution is found, then return to "now" where my eyelids have yet to complete their last lubricating blink and be hailed an all-knowing demi god.

oh well.

zvav...@gmail.com

unread,
Oct 2, 2013, 3:06:06 AM10/2/13
to vim...@googlegroups.com
--
--
You received this message from the "vim_use" 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_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Ben Fritz

unread,
Oct 2, 2013, 8:06:30 AM10/2/13
to vim...@googlegroups.com, v...@vim.org
On Wednesday, October 2, 2013 1:08:02 AM UTC-5, Henry wrote:
> On Tuesday, October 1, 2013 5:18:59 PM UTC+2, Ben Fritz wrote:
> > > > If that doesn't work, you could try modifying your MatchCaseTag function
> > > > to issue a second tjump command in case the first doesn't work. It's a
> > > > hack, but maybe it will fix your problem.
> > > >
> >
> > I think instead of BuffAdd, I'd first try BufWinEnter. If that doesn't work,
> > then maybe BufReadPost would work.
>
> Spent some time brushing up on events at
> http://vimdoc.sourceforge.net/htmldoc/autocmd.html#{event}
>
> Sadly, "au BufWinEnter * nested tab sball" results in the error
> "E435: Couldn't find tag, just guessing"
>
> And so does "au BufReadPost * nested tab sball"
>
> At times like this I wish I could slip into an alternate universe for a few weeks or months and study the problem to the exclusion of all else in as much depth as required until a solution is found, then return to "now" where my eyelids have yet to complete their last lubricating blink and be hailed an all-knowing demi god.
>
> oh well.

Does the suggested workaround of issuing a second tag jump command get you the desired behavior? I'm kind of out of ideas after that since different autocmd events don't seem to avoid the problem.

Henry Combrinck

unread,
Oct 2, 2013, 8:37:35 AM10/2/13
to vim...@googlegroups.com
> > If that doesn't work, you could try modifying your MatchCaseTag function
> > to issue a second tjump command in case the first doesn't work. It's a
> > hack, but maybe it will fix your problem.

By "in case the first doesn't work" I presume you mean an exception?


    try
        exe 'tjump ' . expand('<cword>')
    catch

        exe 'tjump ' . expand('<cword>')
    finally
       let &ic = ic
    endtry


But this doesn't do much because the first exe/tjump doesn't actually "fail" per se:  it always opens the file successfully...

Unless I'm not understanding your suggestion correctly?



--
--
You received this message from the "vim_use" 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 a topic in the Google Groups "vim_use" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vim_use/juMNxDig_O4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vim_use+u...@googlegroups.com.

Ben Fritz

unread,
Oct 2, 2013, 9:36:35 AM10/2/13
to vim...@googlegroups.com
On Wednesday, October 2, 2013 7:37:35 AM UTC-5, Henry wrote:
> > > If that doesn't work, you could try modifying your MatchCaseTag function
>
> > > to issue a second tjump command in case the first doesn't work. It's a
>
> > > hack, but maybe it will fix your problem.
>
> By "in case the first doesn't work" I presume you mean an exception?
>
>     try
>         exe 'tjump ' . expand('<cword>')
>
>     catch
>         exe 'tjump ' . expand('<cword>')
>     finally
>        let &ic = ic
>     endtry
>
>
> But this doesn't do much because the first exe/tjump doesn't actually "fail" per se:  it always opens the file successfully...
>
>
> Unless I'm not understanding your suggestion correctly?
>

Nope, I just meant something stupid and hacky like:

    try
        exe 'tjump ' . expand('<cword>')
        exe 'tjump ' . expand('<cword>')
    finally
       let &ic = ic
    endtry

Now I realize you could probably do better using the tag stack, taking a hint from the examples given just under ":help :tags":

    try
        exe 'tjump ' . expand('<cword>')
        0tag

Henry Combrinck

unread,
Oct 3, 2013, 5:29:11 AM10/3/13
to vim...@googlegroups.com
Thanks Ben,

I actually did try

         exe 'tjump ' . expand('<cword>')
         exe 'tjump ' . expand('<cword>')

initially, but all hell breaks lose with that :)

Looks like

   try
         exe 'tjump ' . expand('<cword>')
         0tag

Does the trick - at least in the sense that it *always* finds the relevant tag.  There's some weirdness with tab behaviour if you drill down, back out, then drill down again.  The second drill down results in new tabs never being opened again in the current session...  but screw it.  At least now it reliably finds the tag.

Thanks for your input!

Cheers
Henry
  


Ben Fritz

unread,
Oct 3, 2013, 1:42:38 PM10/3/13
to vim...@googlegroups.com
On Thursday, October 3, 2013 4:29:11 AM UTC-5, Henry wrote:
> Thanks Ben,
>
> I actually did try
>
>          exe 'tjump ' . expand('<cword>')
>
>          exe 'tjump ' . expand('<cword>')
>
> initially, but all hell breaks lose with that :)
>
> Looks like
>
>    try
>
>          exe 'tjump ' . expand('<cword>')
>
>          0tag
>
> Does the trick - at least in the sense that it *always* finds the relevant tag. 

Heh, I'm actually realizing the first approach should not re-read the <cword> after the first tjump command, it should store off the expand('<cword>') result and use it twice instead of grabbing the word under the new cursor position.

But the second approach is nicer anyway, so I wouldn't bother trying to get the first to wok.
Reply all
Reply to author
Forward
0 new messages