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

Proposal for "v:cmdmodifiers" (and a patch)

Expand Messages
  • Hari Krishna Dara
    I would like to propose a new v: variable that makes any command modifiers specified to the current user-command available to the scripts as a string. This I
    Message 1 of 8 , Sep 28, 2009
      I would like to propose a new v: variable that makes any command
      modifiers specified to the current user-command available to the
      scripts as a string. This I think is very useful to create
      user-defined commands that are more "flush" with the built-in commands
      and in general work as a newbie would expect. Currently any modifiers
      specified before a user-defined command are ignored. From the source,
      I noticed that they are actually processed but there is no way to
      expose them to the scripts, so there is no way to take advantage of
      them.

      As one use case, let us say you create a replacement for a built-in
      command to enhance the functionality, but as a result, you loose the
      ability to recognize modifiers. I.e., you can say "vert diffsplit" or
      "confirm q" but you can't say "vert DiffSplit" or "confirm Q".

      As another use case, plugins have to create multiple variants of a
      user-defined command, to different modifiers, or global variables (as
      settings) that can't change for each command. While these are useful
      by themselves, in most cases they are trying to solve the inability to
      read modifiers from the script.

      As a first cut approach, I tried this below change and it seems to
      work nicely. One big drawback with this simplistic change is that the
      same string that user specified is exposed, so if required, the burden
      to parse falls on the script (especially that Vim allows typing
      partial command, as long as it is unambiguous). However, it is still
      useful for most cases when the modifiers will be literally passed down
      to one of the built-in commands that the script executes, something
      like this:

      command! UDC call UDC()
      func! UDC()
      .
      .
      exec v:cmdmodifiers 'split' s:windowName
      .
      .
      endfunc

      Ideally, the internal "cmdmod" is exposed such a way that the
      individual flags are accessible, or we can even try to expose each one
      of the flags as a separate v: variable (which should be easier
      compared to the former), but I will leave this discussion to the
      exerts (in which case the below change can still serve as a
      prototype). I am not too comfortable programming in c, so please
      excuse me if I missed any obvious things.

      After applying the patch, try commands like this to see it in action:

      -----------------
      :command! T echo v:cmdmodifiers
      :vert T
      vert
      :vert confirm T
      vert confirm
      :echo v:cmdmodifiers

      :T

      :let v:cmdmodifiers = 'vert'
      :T
      vert
      :echo v:cmdmodifiers
      vert
      :keepjumps T
      keepjumps
      :echo v:cmdmodifiers

      -----------------


      Index: C:/src/vim7mods/src/ex_docmd.c
      ===================================================================
      --- C:/src/vim7mods/src/ex_docmd.c (revision 1617)
      +++ C:/src/vim7mods/src/ex_docmd.c (working copy)
      @@ -530,6 +530,9 @@
      static int store_loop_line __ARGS((garray_T *gap, char_u *line));
      static void free_cmdlines __ARGS((garray_T *gap));

      +void set_cmd_modifiers(char *string, int len);
      +void clear_cmd_modifiers();
      +
      /* Struct to save a few things while debugging. Used in do_cmdline() only. */
      struct dbg_stuff
      {
      @@ -1685,6 +1688,8 @@
      #endif
      cmdmod_T save_cmdmod;
      int ni; /* set when Not Implemented */
      + char_u *modifiers_start = NULL;
      + char_u *modifiers_end = NULL;

      vim_memset(&ea, 0, sizeof(ea));
      ea.line1 = 1;
      @@ -1748,6 +1753,8 @@
      * 2. handle command modifiers.
      */
      p = ea.cmd;
      + if (modifiers_start == NULL)
      + modifiers_start = p;
      if (VIM_ISDIGIT(*ea.cmd))
      p = skipwhite(skipdigits(ea.cmd));
      switch (*p)
      @@ -1913,6 +1920,7 @@
      }
      break;
      }
      + modifiers_end = p;

      #ifdef FEAT_EVAL
      ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0
      @@ -2615,7 +2623,15 @@
      /*
      * Execute a user-defined command.
      */
      + if (modifiers_start != modifiers_end)
      + {
      + set_cmd_modifiers(modifiers_start, (modifiers_end - modifiers_start));
      + }
      do_ucmd(&ea);
      + if (modifiers_start != modifiers_end)
      + {
      + clear_cmd_modifiers();
      + }
      }
      else
      #endif
      Index: C:/src/vim7mods/src/eval.c
      ===================================================================
      --- C:/src/vim7mods/src/eval.c (revision 1617)
      +++ C:/src/vim7mods/src/eval.c (working copy)
      @@ -355,6 +355,7 @@
      {VV_NAME("operator", VAR_STRING), VV_RO},
      {VV_NAME("searchforward", VAR_NUMBER), 0},
      {VV_NAME("oldfiles", VAR_LIST), 0},
      + {VV_NAME("cmdmodifiers", VAR_STRING), 0},
      };

      /* shorthand */
      @@ -22748,4 +22749,19 @@
      return ret;
      }

      +void
      +set_cmd_modifiers(string, len)
      + char_u *string;
      + int len;
      +{
      + vimvars[VV_CMDMODIFIERS].vv_str = vim_strnsave(string, len);
      +}
      +
      +void
      +clear_cmd_modifiers()
      +{
      + clear_tv(&vimvars[VV_CMDMODIFIERS].vv_tv);
      +}
      +
      +
      #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
      Index: C:/src/vim7mods/src/vim.h
      ===================================================================
      --- C:/src/vim7mods/src/vim.h (revision 1617)
      +++ C:/src/vim7mods/src/vim.h (working copy)
      @@ -1746,7 +1746,8 @@
      #define VV_OP 52
      #define VV_SEARCHFORWARD 53
      #define VV_OLDFILES 54
      -#define VV_LEN 55 /* number of v: vars */
      +#define VV_CMDMODIFIERS 55
      +#define VV_LEN 56 /* number of v: vars */

      #ifdef FEAT_CLIPBOARD

      Bram, if you like the patch, could you please include it in Vim?

      --
      Thanks,
      Hari

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Ingo Karkat
      ... I like the idea, definitely useful, and have been wanting this occasionally when writing custom commands myself. Above quote probably covers most use
      Message 2 of 8 , Sep 30, 2009
        On 29-Sep-09 3:19, Hari Krishna Dara wrote:
        > exec v:cmdmodifiers 'split' s:windowName

        I like the idea, definitely useful, and have been wanting this occasionally when
        writing custom commands myself. Above quote probably covers most use cases; it
        seems unlikely that modifiers like 'confirm' and 'vertical' will be combined
        _and_ need to be handled separately. However, for such a use case it would
        simplify parsing of v:cmdmodifiers if the patch could expand (i.e. "vert" ->
        "vertical") any abbreviated modifiers. Using separate v: variables seems like
        overdoing it to me.

        -- cheers, ingo
        --
        -- Ingo Karkat -- /^-- /^-- /^-- /^-- /^-- /^-- http://ingo-karkat.de/ --
        -- http://vim.sourceforge.net/account/profile.php?user_id=9713 --

        --~--~---------~--~----~------------~-------~--~----~
        You received this message from the "vim_dev" maillist.
        For more information, visit http://www.vim.org/maillist.php
        -~----------~----~----~----~------~----~------~--~---
      • Hari Krishna Dara
        ... I wanted it do it, but my programming experience in C is limited and so didn t want to venture into that. As I said, most plugins won t normally care what
        Message 3 of 8 , Sep 30, 2009
          On Wed, Sep 30, 2009 at 3:24 AM, Ingo Karkat <swdev@...> wrote:
          >
          > On 29-Sep-09 3:19, Hari Krishna Dara wrote:
          >>   exec v:cmdmodifiers 'split' s:windowName
          >
          > I like the idea, definitely useful, and have been wanting this occasionally when
          > writing custom commands myself. Above quote probably covers most use cases; it
          > seems unlikely that modifiers like 'confirm' and 'vertical' will be combined
          > _and_ need to be handled separately. However, for such a use case it would
          > simplify parsing of v:cmdmodifiers if the patch could expand (i.e. "vert" ->
          > "vertical") any abbreviated modifiers.

          I wanted it do it, but my programming experience in C is limited and
          so didn't want to venture into that. As I said, most plugins won't
          normally care what is in it, so this solution will meet majority of
          the needs. When we do need to parse, Vim also has the "\%[]" regex
          atom that could be of use here.

          If expanding the modifiers is considered important, may be someone
          else can build on top of this patch, or give me some references on how
          to do this. I guess we need to first determine how long the string
          would be based on those flags that are enabled in cmdmod structure and
          then allocate memory and copy a string constant for each with a space
          as separator? I guess this code should take care of passing a number
          before the "tab" modifier. This is probably a child's play for a
          seasoned C programmer.

          --
          Hari

          > Using separate v: variables seems like
          > overdoing it to me.
          >
          > -- cheers, ingo
          > --
          >   -- Ingo Karkat -- /^-- /^-- /^-- /^-- /^-- /^-- http://ingo-karkat.de/ --
          >   --      http://vim.sourceforge.net/account/profile.php?user_id=9713    --
          >
          > >
          >

          --~--~---------~--~----~------------~-------~--~----~
          You received this message from the "vim_dev" maillist.
          For more information, visit http://www.vim.org/maillist.php
          -~----------~----~----~----~------~----~------~--~---
        • Bob Hiestand
          ... I d prefer to see a separate way to access each modifier, though maybe that could be something like v:cmdmodifier[ split ]. In any event, I would love
          Message 4 of 8 , Oct 1, 2009
            On Wed, Sep 30, 2009 at 10:57 AM, Hari Krishna Dara <hari.vim@...> wrote:
            >
            > On Wed, Sep 30, 2009 at 3:24 AM, Ingo Karkat <swdev@...> wrote:
            >>
            >> On 29-Sep-09 3:19, Hari Krishna Dara wrote:
            >>>   exec v:cmdmodifiers 'split' s:windowName
            >>
            >> I like the idea, definitely useful, and have been wanting this occasionally when
            >> writing custom commands myself. Above quote probably covers most use cases; it
            >> seems unlikely that modifiers like 'confirm' and 'vertical' will be combined
            >> _and_ need to be handled separately. However, for such a use case it would
            >> simplify parsing of v:cmdmodifiers if the patch could expand (i.e. "vert" ->
            >> "vertical") any abbreviated modifiers.
            >
            > I wanted it do it, but my programming experience in C is limited and
            > so didn't want to venture into that. As I said, most plugins won't
            > normally care what is in it, so this solution will meet majority of
            > the needs. When we do need to parse, Vim also has the "\%[]" regex
            > atom that could be of use here.

            I'd prefer to see a separate way to access each modifier, though maybe
            that could be something like v:cmdmodifier["split"]. In any event, I
            would love this feature.

            --~--~---------~--~----~------------~-------~--~----~
            You received this message from the "vim_dev" maillist.
            For more information, visit http://www.vim.org/maillist.php
            -~----------~----~----~----~------~----~------~--~---
          • Hari Krishna Dara
            ... That is not convenient for most of the use cases. E.g., to modify the window split behavior, the user could have specified any of top , vertical ,
            Message 5 of 8 , Oct 1, 2009
              On Thu, Oct 1, 2009 at 7:41 AM, Bob Hiestand <bob.hiestand@...> wrote:
              >
              > On Wed, Sep 30, 2009 at 10:57 AM, Hari Krishna Dara <hari.vim@...> wrote:
              >>
              >> On Wed, Sep 30, 2009 at 3:24 AM, Ingo Karkat <swdev@...> wrote:
              >>>
              >>> On 29-Sep-09 3:19, Hari Krishna Dara wrote:
              >>>>   exec v:cmdmodifiers 'split' s:windowName
              >>>
              >>> I like the idea, definitely useful, and have been wanting this occasionally when
              >>> writing custom commands myself. Above quote probably covers most use cases; it
              >>> seems unlikely that modifiers like 'confirm' and 'vertical' will be combined
              >>> _and_ need to be handled separately. However, for such a use case it would
              >>> simplify parsing of v:cmdmodifiers if the patch could expand (i.e. "vert" ->
              >>> "vertical") any abbreviated modifiers.
              >>
              >> I wanted it do it, but my programming experience in C is limited and
              >> so didn't want to venture into that. As I said, most plugins won't
              >> normally care what is in it, so this solution will meet majority of
              >> the needs. When we do need to parse, Vim also has the "\%[]" regex
              >> atom that could be of use here.
              >
              > I'd prefer to see a separate way to access each modifier, though maybe
              > that could be something like v:cmdmodifier["split"].  In any event, I
              > would love this feature.

              That is not convenient for most of the use cases. E.g., to modify the
              window split behavior, the user could have specified any of "top",
              "vertical", "leftabove", "rightbelow", "topleft" etc., so would you
              search for each of the flags to compose the modifiers to pass down to
              the final split your plugin is going to perform, instead of a simple
              pass through like this?

              exec v:cmdmodifiers 'split' s:windowName

              I think the sweet spot is a single string, but with any modifiers
              expanded to their full name, as it serves all the needs.

              --
              Hari

              >
              > >
              >

              --~--~---------~--~----~------------~-------~--~----~
              You received this message from the "vim_dev" maillist.
              For more information, visit http://www.vim.org/maillist.php
              -~----------~----~----~----~------~----~------~--~---
            • Bob Hiestand
              ... If you change that to: exec v:cmdmodifiers[ split ] split s:windowName ... then you have what I requested. The split entry of v:cmdmodifiers would
              Message 6 of 8 , Oct 2, 2009
                On Thu, Oct 1, 2009 at 5:20 PM, Hari Krishna Dara <hari.vim@...> wrote:
                >
                > On Thu, Oct 1, 2009 at 7:41 AM, Bob Hiestand <bob.hiestand@...> wrote:
                >> I'd prefer to see a separate way to access each modifier, though maybe
                >> that could be something like v:cmdmodifier["split"].  In any event, I
                >> would love this feature.
                >
                > That is not convenient for most of the use cases. E.g., to modify the
                > window split behavior, the user could have specified any of "top",
                > "vertical", "leftabove", "rightbelow", "topleft" etc., so would you
                > search for each of the flags to compose the modifiers to pass down to
                > the final split your plugin is going to perform, instead of a simple
                > pass through like this?
                >
                >  exec v:cmdmodifiers 'split' s:windowName
                >
                > I think the sweet spot is a single string, but with any modifiers
                > expanded to their full name, as it serves all the needs.

                If you change that to:

                exec v:cmdmodifiers['split'] 'split' s:windowName

                ... then you have what I requested. The 'split' entry of
                v:cmdmodifiers would contain all the split-specific modifiers. I
                can't think of other command-modifying commands off-hand; :silent and
                :verbose already are available in variable form.

                --~--~---------~--~----~------------~-------~--~----~
                You received this message from the "vim_dev" maillist.
                For more information, visit http://www.vim.org/maillist.php
                -~----------~----~----~----~------~----~------~--~---
              • Hari Krishna Dara
                ... There would also be v:cmdmodifiers[ tab ] that is of use here. And also :keepalt and may be others in the future. I think a string that has all expanded
                Message 7 of 8 , Oct 2, 2009
                  On Fri, Oct 2, 2009 at 1:26 PM, Bob Hiestand <bob.hiestand@...> wrote:
                  >
                  > On Thu, Oct 1, 2009 at 5:20 PM, Hari Krishna Dara <hari.vim@...> wrote:
                  >>
                  >> On Thu, Oct 1, 2009 at 7:41 AM, Bob Hiestand <bob.hiestand@...> wrote:
                  >>> I'd prefer to see a separate way to access each modifier, though maybe
                  >>> that could be something like v:cmdmodifier["split"].  In any event, I
                  >>> would love this feature.
                  >>
                  >> That is not convenient for most of the use cases. E.g., to modify the
                  >> window split behavior, the user could have specified any of "top",
                  >> "vertical", "leftabove", "rightbelow", "topleft" etc., so would you
                  >> search for each of the flags to compose the modifiers to pass down to
                  >> the final split your plugin is going to perform, instead of a simple
                  >> pass through like this?
                  >>
                  >>  exec v:cmdmodifiers 'split' s:windowName
                  >>
                  >> I think the sweet spot is a single string, but with any modifiers
                  >> expanded to their full name, as it serves all the needs.
                  >
                  > If you change that to:
                  >
                  > exec v:cmdmodifiers['split'] 'split' s:windowName
                  >

                  There would also be v:cmdmodifiers['tab'] that is of use here. And
                  also :keepalt and may be others in the future. I think a string that
                  has all expanded modifiers is simpler to use than a dictionary for
                  most plugins.

                  Would v:cmdmodifiers['split'] return a string of all modifiers or just
                  the internal flag cmdmod_T.split? What about others that are just
                  boolean flags? Would v:cmdmodifiers['keepjumps'] either return a blank
                  string or the string 'keepjumps' depending on whether the flag is set
                  or not? What about tab? Would it return the tab number, or the
                  "[count]tab" string?

                  --
                  Thanks,
                  Hari


                  > ... then you have what I requested.  The 'split' entry of
                  > v:cmdmodifiers would contain all the split-specific modifiers.  I
                  > can't think of other command-modifying commands off-hand; :silent and
                  > :verbose already are available in variable form.
                  >
                  > >
                  >

                  --~--~---------~--~----~------------~-------~--~----~
                  You received this message from the "vim_dev" maillist.
                  For more information, visit http://www.vim.org/maillist.php
                  -~----------~----~----~----~------~----~------~--~---
                • Bram Moolenaar
                  ... To avoid overhead for each executed command, the information about which modifiers are active should only be handled when needed. It s hardly ever used,
                  Message 8 of 8 , Oct 4, 2009
                    Hari Krishna Dara wrote:

                    > I would like to propose a new v: variable that makes any command
                    > modifiers specified to the current user-command available to the
                    > scripts as a string. This I think is very useful to create
                    > user-defined commands that are more "flush" with the built-in commands
                    > and in general work as a newbie would expect. Currently any modifiers
                    > specified before a user-defined command are ignored. From the source,
                    > I noticed that they are actually processed but there is no way to
                    > expose them to the scripts, so there is no way to take advantage of
                    > them.
                    >
                    > As one use case, let us say you create a replacement for a built-in
                    > command to enhance the functionality, but as a result, you loose the
                    > ability to recognize modifiers. I.e., you can say "vert diffsplit" or
                    > "confirm q" but you can't say "vert DiffSplit" or "confirm Q".
                    >
                    > As another use case, plugins have to create multiple variants of a
                    > user-defined command, to different modifiers, or global variables (as
                    > settings) that can't change for each command. While these are useful
                    > by themselves, in most cases they are trying to solve the inability to
                    > read modifiers from the script.
                    >
                    > As a first cut approach, I tried this below change and it seems to
                    > work nicely. One big drawback with this simplistic change is that the
                    > same string that user specified is exposed, so if required, the burden
                    > to parse falls on the script (especially that Vim allows typing
                    > partial command, as long as it is unambiguous). However, it is still
                    > useful for most cases when the modifiers will be literally passed down
                    > to one of the built-in commands that the script executes, something
                    > like this:
                    >
                    > command! UDC call UDC()
                    > func! UDC()
                    > .
                    > .
                    > exec v:cmdmodifiers 'split' s:windowName
                    > .
                    > .
                    > endfunc
                    >
                    > Ideally, the internal "cmdmod" is exposed such a way that the
                    > individual flags are accessible, or we can even try to expose each one
                    > of the flags as a separate v: variable (which should be easier
                    > compared to the former), but I will leave this discussion to the
                    > exerts (in which case the below change can still serve as a
                    > prototype). I am not too comfortable programming in c, so please
                    > excuse me if I missed any obvious things.

                    To avoid overhead for each executed command, the information about which
                    modifiers are active should only be handled when needed. It's hardly
                    ever used, thus setting v:cmdmodifiers on each command is not a good
                    idea.

                    A function could be used, which can then also handle the "silent" flag,
                    which doesn't appear in cmdmod and handle other border cases.

                    getmodifier("silent")
                    getmodifier("vertical")

                    It's easy to extend when more modifiers might be added.

                    How about that?

                    --
                    E M A C S
                    s e l o h
                    c t t n i
                    a a t f
                    p r t
                    e o
                    l

                    /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                    /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                    \\\ download, build and distribute -- http://www.A-A-P.org ///
                    \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

                    --~--~---------~--~----~------------~-------~--~----~
                    You received this message from the "vim_dev" maillist.
                    For more information, visit http://www.vim.org/maillist.php
                    -~----------~----~----~----~------~----~------~--~---
                  Your message has been successfully submitted and would be delivered to recipients shortly.