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

[PATCH] Allow negative indices for strings

Expand Messages
  • LCD 47
    There is an asymmetry in handling indices for lists and strings. Lists accept things like lst[n], lst[n1:n2], lst[n1:-n2], and lst[-n]. Strings accept str[n],
    Message 1 of 7 , Feb 12, 2014
    • 0 Attachment
      There is an asymmetry in handling indices for lists and strings.
      Lists accept things like lst[n], lst[n1:n2], lst[n1:-n2], and lst[-n].
      Strings accept str[n], str[n1:n2], str[n1:-n2] (all with the same
      meanings as the corresponding operations for lists), but not str[-n].
      Negative indices in strings always return '', which is frustrating. :)

      The patch below makes negative indices behave the same way for
      string as they do for lists (but they don't rise exceptions when out of
      range):

      :let a = '12345'
      :echo a[-1]
      5
      :echo string(a[-6])
      ''

      Negative indices for strings never did anything useful (at least as
      far as I can tell), so this is unlikely to break existing code.

      Best regards,

      /lcd


      diff -r 277885c9c344 src/eval.c
      --- a/src/eval.c Wed Feb 12 22:08:49 2014 +0100
      +++ b/src/eval.c Thu Feb 13 09:20:29 2014 +0200
      @@ -5414,8 +5414,10 @@
      else
      {
      /* The resulting variable is a string of a single
      - * character. If the index is too big or negative the
      + * character. If the index is out of range the
      * result is empty. */
      + if (n1 < 0)
      + n1 = len + n1;
      if (n1 >= len || n1 < 0)
      s = NULL;
      else

      --
      --
      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.
    • Bram Moolenaar
      ... I suppose that would be OK, and useful, to add. Can you also add a test? -- Not too long ago, compress was something you did to garbage... /// Bram
      Message 2 of 7 , Feb 13, 2014
      • 0 Attachment
        lcd wrote:

        > There is an asymmetry in handling indices for lists and strings.
        > Lists accept things like lst[n], lst[n1:n2], lst[n1:-n2], and lst[-n].
        > Strings accept str[n], str[n1:n2], str[n1:-n2] (all with the same
        > meanings as the corresponding operations for lists), but not str[-n].
        > Negative indices in strings always return '', which is frustrating. :)
        >
        > The patch below makes negative indices behave the same way for
        > string as they do for lists (but they don't rise exceptions when out of
        > range):
        >
        > :let a = '12345'
        > :echo a[-1]
        > 5
        > :echo string(a[-6])
        > ''
        >
        > Negative indices for strings never did anything useful (at least as
        > far as I can tell), so this is unlikely to break existing code.

        I suppose that would be OK, and useful, to add.

        Can you also add a test?

        --
        Not too long ago, compress was something you did to garbage...

        /// Bram Moolenaar -- Bram@... -- 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 ///

        --
        --
        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.
      • Liang Li
        ... Not to derail this, but regarding asymetries -- is there any reason why strings aren t treated like arrays of characters, ie, why I can t say let
        Message 3 of 7 , Feb 13, 2014
        • 0 Attachment
          On Thursday, February 13, 2014 4:06:49 PM UTC-5, Bram Moolenaar wrote:
          > lcd wrote:
          >
          >
          >
          > > There is an asymmetry in handling indices for lists and strings.
          >
          > > Lists accept things like lst[n], lst[n1:n2], lst[n1:-n2], and lst[-n].
          >
          > > Strings accept str[n], str[n1:n2], str[n1:-n2] (all with the same
          >
          > > meanings as the corresponding operations for lists), but not str[-n].
          >
          > > Negative indices in strings always return '', which is frustrating. :)
          >
          > >
          >
          > > The patch below makes negative indices behave the same way for
          >
          > > string as they do for lists (but they don't rise exceptions when out of
          >
          > > range):
          >
          > >
          >
          > > :let a = '12345'
          >
          > > :echo a[-1]
          >
          > > 5
          >
          > > :echo string(a[-6])
          >
          > > ''
          >
          > >
          >
          > > Negative indices for strings never did anything useful (at least as
          >
          > > far as I can tell), so this is unlikely to break existing code.
          >
          >
          >
          > I suppose that would be OK, and useful, to add.
          >
          >
          >
          > Can you also add a test?
          >
          >
          >
          > --
          >
          > Not too long ago, compress was something you did to garbage...
          >
          >
          >
          > /// Bram Moolenaar -- Bram@... -- 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 ///

          Not to derail this, but regarding asymetries -- is there any reason why strings aren't treated like arrays of characters, ie, why I can't say let str[7]='p' or let str[7:9]='pqr'?

          --
          --
          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.
        • LCD 47
          ... Sure, attached below. /lcd diff -r 277885c9c344 src/eval.c ... +++ b/src/eval.c Fri Feb 14 09:38:11 2014 +0200 @@ -5414,8 +5414,10 @@ else { /* The
          Message 4 of 7 , Feb 13, 2014
          • 0 Attachment
            On 13 February 2014, Bram Moolenaar <Bram@...> wrote:
            >
            > lcd wrote:
            >
            > > There is an asymmetry in handling indices for lists and strings.
            > > Lists accept things like lst[n], lst[n1:n2], lst[n1:-n2], and lst[-n].
            > > Strings accept str[n], str[n1:n2], str[n1:-n2] (all with the same
            > > meanings as the corresponding operations for lists), but not str[-n].
            > > Negative indices in strings always return '', which is frustrating. :)
            > >
            > > The patch below makes negative indices behave the same way for
            > > string as they do for lists (but they don't rise exceptions when out of
            > > range):
            > >
            > > :let a = '12345'
            > > :echo a[-1]
            > > 5
            > > :echo string(a[-6])
            > > ''
            > >
            > > Negative indices for strings never did anything useful (at least as
            > > far as I can tell), so this is unlikely to break existing code.
            >
            > I suppose that would be OK, and useful, to add.
            >
            > Can you also add a test?

            Sure, attached below.

            /lcd


            diff -r 277885c9c344 src/eval.c
            --- a/src/eval.c Wed Feb 12 22:08:49 2014 +0100
            +++ b/src/eval.c Fri Feb 14 09:38:11 2014 +0200
            @@ -5414,8 +5414,10 @@
            else
            {
            /* The resulting variable is a string of a single
            - * character. If the index is too big or negative the
            + * character. If the index is out of range the
            * result is empty. */
            + if (n1 < 0)
            + n1 = len + n1;
            if (n1 >= len || n1 < 0)
            s = NULL;
            else
            diff -r 277885c9c344 src/testdir/Makefile
            --- a/src/testdir/Makefile Wed Feb 12 22:08:49 2014 +0100
            +++ b/src/testdir/Makefile Fri Feb 14 09:38:11 2014 +0200
            @@ -31,7 +31,7 @@
            test89.out test90.out test91.out test92.out test93.out \
            test94.out test95.out test96.out test97.out test98.out \
            test99.out test100.out test101.out test102.out test103.out \
            - test104.out
            + test104.out test105.out

            SCRIPTS_GUI = test16.out

            diff -r 277885c9c344 src/testdir/test105.in
            --- /dev/null Thu Jan 01 00:00:00 1970 +0000
            +++ b/src/testdir/test105.in Fri Feb 14 09:38:11 2014 +0200
            @@ -0,0 +1,12 @@
            +Tests negative indices in strings
            +
            +STARTTEST
            +:let a='12345'
            +:for i in range(1, 6)
            +: $put =string(a[-i])
            +:endfor
            +:/^Results/,$wq! test.out
            +:qa!
            +ENDTEST
            +
            +Results:
            diff -r 277885c9c344 src/testdir/test105.ok
            --- /dev/null Thu Jan 01 00:00:00 1970 +0000
            +++ b/src/testdir/test105.ok Fri Feb 14 09:38:11 2014 +0200
            @@ -0,0 +1,7 @@
            +Results:
            +'5'
            +'4'
            +'3'
            +'2'
            +'1'
            +''

            --
            --
            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.
          • LCD 47
            ... Hmm, I just found this note in the manual (:help expr-[]): A negative index always results in an empty string (reason: backwards compatibility). Use [-1:]
            Message 5 of 7 , Feb 14, 2014
            • 0 Attachment
              On 14 February 2014, LCD 47 <lcd047@...> wrote:
              > On 13 February 2014, Bram Moolenaar <Bram@...> wrote:
              > >
              > > lcd wrote:
              > >
              > > > There is an asymmetry in handling indices for lists and strings.
              > > > Lists accept things like lst[n], lst[n1:n2], lst[n1:-n2], and lst[-n].
              > > > Strings accept str[n], str[n1:n2], str[n1:-n2] (all with the same
              > > > meanings as the corresponding operations for lists), but not str[-n].
              > > > Negative indices in strings always return '', which is frustrating. :)
              > > >
              > > > The patch below makes negative indices behave the same way for
              > > > string as they do for lists (but they don't rise exceptions when out of
              > > > range):
              > > >
              > > > :let a = '12345'
              > > > :echo a[-1]
              > > > 5
              > > > :echo string(a[-6])
              > > > ''
              > > >
              > > > Negative indices for strings never did anything useful (at least as
              > > > far as I can tell), so this is unlikely to break existing code.
              > >
              > > I suppose that would be OK, and useful, to add.
              > >
              > > Can you also add a test?
              >
              > Sure, attached below.

              Hmm, I just found this note in the manual (:help expr-[]):

              A negative index always results in an empty string (reason: backwards
              compatibility). Use [-1:] to get the last byte.

              I suppose something like a[-3:-3] can be used instead of a[-3],
              but...

              /lcd

              --
              --
              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.
            • LCD 47
              ... I believe the reason is that you can t do that in Python. :) Although, the semantics is already slightly different, since str[7:9] in Vim is actually
              Message 6 of 7 , Feb 14, 2014
              • 0 Attachment
                On 13 February 2014, Liang Li <q335r49@...> wrote:
                > On Thursday, February 13, 2014 4:06:49 PM UTC-5, Bram Moolenaar wrote:
                > > lcd wrote:
                > >
                > > > There is an asymmetry in handling indices for lists
                > > > and strings. Lists accept things like lst[n], lst[n1:n2],
                > > > lst[n1:-n2], and lst[-n]. Strings accept str[n], str[n1:n2],
                > > > str[n1:-n2] (all with the same meanings as the corresponding
                > > > operations for lists), but not str[-n]. Negative indices in
                > > > strings always return '', which is frustrating. :)
                > > >
                > > > The patch below makes negative indices behave the same way for
                > > > string as they do for lists (but they don't rise exceptions when
                > > > out of range):
                > > >
                > > > :let a = '12345'
                > > > :echo a[-1]
                > > > 5
                > > > :echo string(a[-6])
                > > > ''
                > > >
                > > > Negative indices for strings never did anything useful (at
                > > > least as far as I can tell), so this is unlikely to break existing
                > > > code.
                > >
                > > I suppose that would be OK, and useful, to add.
                > >
                > > Can you also add a test?
                >
                > Not to derail this, but regarding asymetries -- is there any reason
                > why strings aren't treated like arrays of characters, ie, why I can't
                > say let str[7]='p' or let str[7:9]='pqr'?

                I believe the reason is that you can't do that in Python. :)
                Although, the semantics is already slightly different, since str[7:9] in
                Vim is actually str[7:10] in Python.

                I suppose an argument can be made for implementing full splices for
                both lists and strings. E.g. something like list[3:5] = [] would delete
                the corresponding elements etc.

                /lcd

                --
                --
                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.
              • Bram Moolenaar
                ... I forgot the backwards compatibility problem. Probably it s about calculating the index and it going negative unintentionally. -- Apologies for taking up
                Message 7 of 7 , Feb 14, 2014
                • 0 Attachment
                  lcd wrote:

                  > On 14 February 2014, LCD 47 <lcd047@...> wrote:
                  > > On 13 February 2014, Bram Moolenaar <Bram@...> wrote:
                  > > >
                  > > > lcd wrote:
                  > > >
                  > > > > There is an asymmetry in handling indices for lists and strings.
                  > > > > Lists accept things like lst[n], lst[n1:n2], lst[n1:-n2], and lst[-n].
                  > > > > Strings accept str[n], str[n1:n2], str[n1:-n2] (all with the same
                  > > > > meanings as the corresponding operations for lists), but not str[-n].
                  > > > > Negative indices in strings always return '', which is frustrating. :)
                  > > > >
                  > > > > The patch below makes negative indices behave the same way for
                  > > > > string as they do for lists (but they don't rise exceptions when out of
                  > > > > range):
                  > > > >
                  > > > > :let a = '12345'
                  > > > > :echo a[-1]
                  > > > > 5
                  > > > > :echo string(a[-6])
                  > > > > ''
                  > > > >
                  > > > > Negative indices for strings never did anything useful (at least as
                  > > > > far as I can tell), so this is unlikely to break existing code.
                  > > >
                  > > > I suppose that would be OK, and useful, to add.
                  > > >
                  > > > Can you also add a test?
                  > >
                  > > Sure, attached below.
                  >
                  > Hmm, I just found this note in the manual (:help expr-[]):
                  >
                  > A negative index always results in an empty string (reason: backwards
                  > compatibility). Use [-1:] to get the last byte.
                  >
                  > I suppose something like a[-3:-3] can be used instead of a[-3],
                  > but...

                  I forgot the backwards compatibility problem. Probably it's about
                  calculating the index and it going negative unintentionally.

                  --
                  Apologies for taking up the bandwidth with the apology. Anything else I
                  can apologise for ...... er no can't think of anything, sorry about that.
                  Andy Hunt (Member of British Olympic Apology Squad)

                  /// Bram Moolenaar -- Bram@... -- 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 ///

                  --
                  --
                  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.