Loading ...
Sorry, an error occurred while loading the content.

Re: bufwinnr with regex pattern may fail in muliti-tabs layouts

Expand Messages
  • Vlad Irnov
    ... You probably meant bufwinnr() instead of bufname() in your first example. ... 1 ... -1 ... 1 When buffer test1 is not loaded but listed it still
    Message 1 of 4 , Feb 10, 2013
    • 0 Attachment
      On 2/8/13, Alexey Radkov <alexey.radkov@...> wrote:
      > Even an easier test:
      >
      > 1. Open a C file
      > 2. Open another C file in another tab
      > 3. :echo bufwinnr('*.c') -> -1. Wrong.
      >
      >
      > 2013/2/8 Alexey Radkov <alexey.radkov@...>
      >
      >> Hi,
      >>
      >> :help bufwinnr says:
      >>
      >> "Only deals with the current tab page."
      >>
      >> Recently i found that this behaviour is broken if the argument of
      >> bufwinnr() is regexp pattern and there are more than one tabs open. I
      >> found
      >> that in following experiment:
      >>
      >> 1. Open vim with some file.
      >> 2. Open NERD_tree plugin (its bufname will be 'NERD_tree_1')
      >> 3. :echo bufname('NERD_tree*') -> 1 (if it's open on the left), good
      >> 4. Open another file in a new tab.
      >> 5. Open another NERD_tree in this new tab (its name will be
      >> 'NERD_tree_2')
      >> 6. :echo bufname('NERD_tree*') -> -1 (bad, shoul be 1 because another
      >> NERD_tree is in another tab!)
      >> 7. Return to the first tab and do :echo.... again -> -1 (must be 1)
      >>
      >>
      >> The issue is due to f_bufwinnr() in eval.c calls get_buf_tv() which in
      >> turn calls buflist_findpat(). buflist_findpat() searches through buffers
      >> in
      >> all windows and when it finds more than one matches it returns -2!
      >> According to the idea of bufwinnr it should check only in buffers that
      >> bound to the current tab so buflist_findpat() must sort out buffers from
      >> other tabs. I implemented and attached a small patch that fixes this
      >> issue
      >> for me: this adds extra argument 'curtab_only' in get_buf_tv() and
      >> buflist_findpat(), the latter function adds a match only if matched
      >> buffer
      >> is bound to the current tab. Though I am not sure that it is clean enough
      >> (especially when i am adding curtab_only as the last argument to the
      >> buflist_findpat(), which previous argument marked with macro UNUSED).
      >>
      >> Cheers, Alexey.

      You probably meant bufwinnr() instead of bufname() in your first example.
      This can be reproduced without NERD_tree and without tabs:

      :edit test1
      :set buflisted bufhidden=unload
      :echo bufwinnr('test*')
      " 1
      :edit test2
      :echo bufwinnr('test*')
      " -1
      :bdelete test1
      :echo bufwinnr('test*')
      " 1

      When buffer 'test1' is not loaded but listed it still interferes with
      bufwinnr('test*').

      It's not clear if this is a bug and not an poorly documentd
      specification. Help for winbufnr() says: "For the use of {expr}, see
      |bufname()| above." bufname({expr}) returs empty string if more than one
      buffers match {expr}. bufnr() also returns -1 if there is more than one
      match, e.g. bufnr('test*') in the above example.

      This is why I always try to use buffer numbers to identify buffers.
      There are too many gotchas and special cases with bufname(), bufwinnr(),
      bufnr(), etc. when {expr} is a name.

      Regards,
      Vlad

      --
      --
      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+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    • Alexey Radkov
      1. Yes, i meant bufwinnr( NERD* ), sorry for this misleading mistake. 2. Yes, i understand that it could be just an undocumented restriction, but unfortunately
      Message 2 of 4 , Feb 10, 2013
      • 0 Attachment
        1. Yes, i meant bufwinnr('NERD*'), sorry for this misleading mistake.

        2. Yes, i understand that it could be just an undocumented restriction, but unfortunately in this case i cannot find if NERD_tree, which enumerates bufnames like NERD_tree_1, NERD_tree_2 and so on, is present in current tab. In this case i must use explicit loop through all windows, whereas at the first glance bufwinnr('NERD_tree*') was looking very promising.


        Cheers, Alexey.


        2013/2/11 Vlad Irnov <vlad.irnov@...>
        On 2/8/13, Alexey Radkov <alexey.radkov@...> wrote:
        > Even an easier test:
        >
        > 1. Open a C file
        > 2. Open another C file in another tab
        > 3. :echo bufwinnr('*.c') -> -1. Wrong.
        >
        >
        > 2013/2/8 Alexey Radkov <alexey.radkov@...>
        >
        >> Hi,
        >>
        >> :help bufwinnr says:
        >>
        >> "Only deals with the current tab page."
        >>
        >> Recently i found that this behaviour is broken if the argument of
        >> bufwinnr() is regexp pattern and there are more than one tabs open. I
        >> found
        >> that in following experiment:
        >>
        >> 1. Open vim with some file.
        >> 2. Open NERD_tree plugin (its bufname will be 'NERD_tree_1')
        >> 3. :echo bufname('NERD_tree*')  ->  1 (if it's open on the left), good
        >> 4. Open another file in a new tab.
        >> 5. Open another NERD_tree in this new tab (its name will be
        >> 'NERD_tree_2')
        >> 6. :echo bufname('NERD_tree*')  ->  -1 (bad, shoul be 1 because another
        >> NERD_tree is in another tab!)
        >> 7. Return to the first tab and do :echo.... again -> -1 (must be 1)
        >>
        >>
        >> The issue is due to f_bufwinnr() in eval.c calls get_buf_tv() which in
        >> turn calls buflist_findpat(). buflist_findpat() searches through buffers
        >> in
        >> all windows and when it finds more than one matches it returns -2!
        >> According to the idea of bufwinnr it should check only in buffers that
        >> bound to the current tab so buflist_findpat() must sort out buffers from
        >> other tabs. I implemented and attached a small patch that fixes this
        >> issue
        >> for me: this adds extra argument 'curtab_only' in get_buf_tv() and
        >> buflist_findpat(), the latter function adds a match only if matched
        >> buffer
        >> is bound to the current tab. Though I am not sure that it is clean enough
        >> (especially when i am adding curtab_only as the last argument to the
        >> buflist_findpat(), which previous argument marked with macro UNUSED).
        >>
        >> Cheers, Alexey.

        You probably meant bufwinnr() instead of bufname() in your first example.
        This can be reproduced without NERD_tree and without tabs:

        :edit test1
        :set buflisted bufhidden=unload
        :echo bufwinnr('test*')
        " 1
        :edit test2
        :echo bufwinnr('test*')
        " -1
        :bdelete test1
        :echo bufwinnr('test*')
        " 1

        When buffer 'test1' is not loaded but listed it still interferes with
        bufwinnr('test*').

        It's not clear if this is a bug and not an poorly documentd
        specification. Help for winbufnr() says: "For the use of {expr}, see
        |bufname()| above." bufname({expr}) returs empty string if more than one
        buffers match {expr}. bufnr() also returns -1 if there is more than one
        match, e.g. bufnr('test*') in the above example.

        This is why I always try to use buffer numbers to identify buffers.
        There are too many gotchas and special cases with bufname(), bufwinnr(),
        bufnr(), etc. when {expr} is a name.

        Regards,
        Vlad

        --
        --
        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+unsubscribe@....
        For more options, visit https://groups.google.com/groups/opt_out.



        --
        --
        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+unsubscribe@....
        For more options, visit https://groups.google.com/groups/opt_out.
         
         
      Your message has been successfully submitted and would be delivered to recipients shortly.