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

Two minor requests for the TODO list

Expand Messages
  • Eggum, DavidX S
    Hello All, I ve found two tasks that are done in vim scripts routinely and it would be nice to streamline them: Here s the first one: If some variable isn t
    Message 1 of 5 , Dec 6, 2006
      Hello All,

      I've found two tasks that are done in vim scripts routinely and it would be nice to streamline them:

      Here's the first one: "If some variable isn't set yet, then set it to a default value". The code always looks something like this:

      if !exists("g:MyScriptSetting")
         let g:MyScriptSetting = "default_value"
      endif

      To make this easier, I would love to see is the vim 7.0 "get()" function expanded to handle regular variables. The get() function is currently defined this way:
      get({list}, {idx} [, {default}])
                                      Get item {idx} from List {list}.  When this item is not
                                      available return {default}.  Return zero when {default} is
                                      omitted.
      get({dict}, {key} [, {default}])
                                      Get item with key {key} from Dictionary {dict}.  When this
                                      item is not available return {default}.  Return zero when
                                      {default} is omitted.

      How about adding this:
      get({string} [, {default}])
                                      Get value from variable {string}.  When this variable does not
                                      exist, return {default}.  Return zero when {default} is
                                      omitted.

      The second one is: "Make these vim settings during this function call only, so save the current values first, set them to what I want, then restore them before leaving". There is an item on the TODO list to make this easier:

      ":with option=value | command": temporarily set an option value and restore it after the command has executed.

      The problem is that this could get ugly if many options need to be changed, and those settings have to be made *every time* the routine is called. Typically, the function only works correctly when those settings are set. It would be nice to see something like the current setlocal command instead:

      :sett[emp] ...                    
      Like ":set" but set only the value local to the current function.  The value is restored to the value set before the current function was called when the function ends. Not valid outside of a
      function.

      What do you think?

      David
    • Luc Hermitte
      Hello, ... Well, I ve started to refactor my plugins to isolate a similar similar function in an autoload plugin. My function also takes another argument: a
      Message 2 of 5 , Dec 6, 2006
        Hello,

        * On Wed, Dec 06, 2006 at 04:11:24PM -0800, Eggum, DavidX S <davidx.s.eggum@...> wrote:
        > I've found two tasks that are done in vim scripts routinely and it
        > would be nice to streamline them:
        >
        > Here's the first one: "If some variable isn't set yet, then set it to
        > a default value". The code always looks something like this:
        >
        > if !exists("g:MyScriptSetting")
        >    let g:MyScriptSetting = "default_value"
        > endif
        >
        > How about adding this:
        > [...]
        > get({string} [, {default}])
        >            value from variable {string}.  When this variable does not
        >            exist, return {default}.  Return zero when {default} is
        > omitted.

        Well, I've started to refactor my plugins to isolate a similar similar
        function in an autoload plugin. My function also takes another argument:
        a list of scopes in which the variable can be defined.

        " Function: lh#option#Get({name}, {default} [, {scope}])
        " @return b:{name} if it exists, of g:{name} if it exists, or {default}
        " otherwise
        " The order of the variables checked can be specified through the optional
        " argument {scope}

        Then, in my script, I systematically call this function, and never
        directly use a variable. Indeed, I have no way of knowing if the
        variable is b:goo, g:foo, w:foo or even s:foo.

        The support of non global options is very important to me as I mainly
        maintain ftplugins, and work on the files from various projects that
        don't share the same configuration (like different targets used in the
        makefiles).

        A typical use is:
        let l:foo = lh#option#Get('foo', s:foo_default, 'wbg')
        Which will return the value of the first variable found among w:foo,
        b:foo and g:foo. Or s:foo_default otherwise.

        So far, {default} is not optional as I have both integer and string
        variables, and I can't easily tell the exact type of the variable.

        Having such function as builtin would be nice. I can easily cope without
        it. But still, it would be nice.

        --
        Luc Hermitte
        http://hermitte.free.fr/vim/
      • Eggum, DavidX S
        ... it only has an effect if the variable is not yet defined. This statement: let foo ?= bar is exactly equivalent to this: if !exists( foo ) let foo = bar
        Message 3 of 5 , Dec 7, 2006
          > How about adding this:
          > get({string} [, {default}])
          >                                 Get value from variable {string}.  When this variable does not
          >                                 exist, return {default}.  Return zero when {default} is
          >                                 omitted.


          Hmmm.... we could follow the more succinct gmake way of doing things and add a new operator instead (I like this solution better):

          :let {var} ?= {expr} This is a conditional variable assignment operator,
          it only has an effect if the variable is not yet
          defined. This statement:

          let foo ?= "bar"

          is exactly equivalent to this:

          if !exists("foo")
          let foo = "bar"
          endif

          Regards,
          David

          ---
          "Love is what's in the room with you at Christmas if you stop opening presents and listen."

          Bobby - age 7
        • Halim, Salman
          I have a relatively simple function I use: function! GetVar( ... ) let varName=a:1 let retVal = exists( a:2 ) ? a:2 : -1 if ( exists ( w: . varName ) ) let
          Message 4 of 5 , Dec 7, 2006
            I have a relatively simple function I use:

            function! GetVar( ... )
            let varName=a:1

            let retVal = exists( "a:2" ) ? a:2 : -1

            if ( exists ( "w:" . varName ) )
            let retVal=w:{varName}
            elseif ( exists ( "b:" . varName ) )
            let retVal=b:{varName}
            elseif ( exists ( "t:" . varName ) )
            let retVal=t:{varName}
            elseif ( exists ( "g:" . varName ) )
            let retVal=g:{varName}
            endif
            return retVal
            endfunction

            Calling it with something like:

            :let test = GetVar( 'expandWindow', 'never' )

            First checks to see if w:expandWindow exists (and returns that), then b:expandWindow, t:expandWindow and finally g:expandWindow; if none of them exist, it returns 'never' (or -1, if there was no second parameter). I use it in plugins to allow both global default values as well as window-, buffer- or tab-specific overrides.

            This could be easily rewritten as:

            :return exists( a:1 ) ? {a:1} : exists( a:2 ) ? a:2 : 0

            To do what you're asking.

            Of course, an internal version would be much faster, which might be why you asked :)

            Salman.

            > -----Original Message-----
            > From: Eggum, DavidX S [mailto:davidx.s.eggum@...]
            > Sent: Thursday, December 07, 2006 1:22 PM
            > To: vim developers list
            > Subject: RE: Two minor requests for the TODO list
            >
            >
            > > How about adding this:
            > > get({string} [, {default}])
            > >                                 Get value from variable {string}. 
            > > When this variable does not
            > >                                 exist, return {default}. 
            > Return zero
            > > when {default} is
            > >                                 omitted.
            >
            >
            > Hmmm.... we could follow the more succinct gmake way of doing
            > things and add a new operator instead (I like this solution better):
            >
            > :let {var} ?= {expr} This is a conditional
            > variable assignment operator,
            > it only has an effect
            > if the variable is not yet
            > defined. This statement:
            >
            > let foo ?= "bar"
            >
            > is exactly equivalent to this:
            >
            > if !exists("foo")
            > let foo = "bar"
            > endif
            >
            > Regards,
            > David
            >
            > ---
            > "Love is what's in the room with you at Christmas if you stop
            > opening presents and listen."
            >
            > Bobby - age 7
            >
          • Eggum, DavidX S
            ... assignment operator, ... is not yet ... Along those lines, why not define a conditional attribute that would apply to functions? ... ... When a function by
            Message 5 of 5 , Dec 7, 2006
              > :let {var} ?= {expr} This is a conditional variable
              assignment operator,
              > it only has an effect if the variable
              is not yet
              > defined. This statement:
              >
              > let foo ?= "bar"
              >
              > is exactly equivalent to this:
              >
              > if !exists("foo")
              > let foo = "bar"
              > endif

              Along those lines, why not define a conditional attribute that would
              apply to functions?

              :fu[nction][!?] {name}([arguments]) [range] [abort] [dict]
              ...

              When a function by this name already exists and
              [!] or
              [?] is not used an error message is given. When [!]
              is
              used, an existing function is silently replaced; when
              [?] is used, the function is ignored.

              The same goes for :command[?]
            Your message has been successfully submitted and would be delivered to recipients shortly.