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

bufwinnr with regex pattern may fail in muliti-tabs layouts

Expand Messages
  • Alexey Radkov
    Hi, ... 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
    Message 1 of 4 , Feb 7, 2013
      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 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
      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
      Message 2 of 4 , Feb 8, 2013
        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 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.
         
         
      • 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 3 of 4 , Feb 10, 2013
          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 4 of 4 , Feb 10, 2013
            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.