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

Re: why is exec limited?

Expand Messages
  • Tony Mechelynck
    ... To run a separate script, use :source (q.v.), not :exec . The command ... would execute the hypothetical command ... but of course the :user command
    Message 1 of 5 , Dec 5, 2008
      On 06/12/08 00:29, Marc Weber wrote:
      > Thinking about TOVL I'm faced by a problem:
      > I'd like to expose the configuration, so that the user can customize it
      > easily.
      > A perfect fit would be just let the user edit or customize the code
      > snippet then run it in the right context using exec. But exec is
      > limited, isn't it?
      >
      > Example:
      > exec "echo \"foo\"\n\\.'bar'"
      >
      > This is this script:
      > echo "foo"
      > \.'bar'
      >
      > it should echo foobar.
      >
      > A use case would by TOVL:
      >
      > let d = NewPlugin()
      >
      > fun d.PluginLoad()
      > exec "user config"
      > endfun
      >
      > Marc

      To run a separate script, use ":source" (q.v.), not ":exec".

      The command

      :exec "user config"

      would execute the hypothetical command

      :user config

      but of course the ":user" command does not exist, so you get an error.
      What ":exec" does is executing as an ex-command what ":echo" would have
      displayed, given the same arguments. Notice that when you type an
      ex-command at the command-line, Vim executes it as soon as you hit
      <Enter> without waiting to see if you'll type zero or more whitespace
      characters followed by a backslash.


      Best regards,
      Tony.
      --
      TALL KNIGHT: We shall say Ni! again to you if you do not appease us.
      ARTHUR: All right! What do you want?
      TALL KNIGHT: We want ... a shrubbery!
      "Monty Python and the Holy Grail" PYTHON (MONTY)
      PICTURES LTD

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Marc Weber
      Hi Tony, I know about source. That s why I ve implemented this: FIXME: Is there a better way to execute multi line strings? function! library#Exec(cmd) let
      Message 2 of 5 , Dec 5, 2008
        Hi Tony,

        I know about source. That's why I've implemented this:
        " FIXME: Is there a better way to execute multi line strings?
        function! library#Exec(cmd)
        let lines = split(a:cmd,"\n")
        if (len(lines) > 1)
        " is there a better way? (TODO! try to not use temp files!)
        let file = tempname()
        call writefile(lines, file)
        exec 'source '.file
        call delete(file)
        elseif !empty(lines)
        exec lines[0]
        endif
        endfunction

        But that is ugly!
        In my use case the script doesn't really exist on disk (or better to say
        it does, but not as vimscript but serialized vim dictionary)
        But suing Exec() You've no chance getting the s: or <sfile> context.

        But its no longer urgent because I'm writing extra functions to add
        mappings and autocommands. This way they will be removed when disabling
        the pluign automatically..

        Marc

        --~--~---------~--~----~------------~-------~--~----~
        You received this message from the "vim_dev" maillist.
        For more information, visit http://www.vim.org/maillist.php
        -~----------~----~----~----~------~----~------~--~---
      • Agathoklis D. Hatzimanikas
        Hi Marc, ... Here is function (to parse external scipts, so and serialized vim dictionaries), that is trying to workaround the limitation of execute.
        Message 3 of 5 , Jan 12, 2009
          Hi Marc,

          On Sat, Dec 06, at 03:46 Marc Weber wrote:
          >
          > Hi Tony,
          >
          > I know about source. That's why I've implemented this:
          > " FIXME: Is there a better way to execute multi line strings?
          > function! library#Exec(cmd)
          > let lines = split(a:cmd,"\n")
          > if (len(lines) > 1)
          > " is there a better way? (TODO! try to not use temp files!)
          > let file = tempname()
          > call writefile(lines, file)
          > exec 'source '.file
          > call delete(file)
          > elseif !empty(lines)
          > exec lines[0]
          > endif
          > endfunction
          >
          > But that is ugly!
          > In my use case the script doesn't really exist on disk (or better to say
          > it does, but not as vimscript but serialized vim dictionary)
          > But suing Exec() You've no chance getting the s: or <sfile> context.
          >

          Here is function (to parse external scipts, so and serialized vim
          dictionaries), that is trying to workaround the limitation of execute.

          " Function: lib#source(file)
          "Description: create a list, so we can loop over it by using execute
          " Args: script to parse
          " Return: list
          " Notes: (limited usage)
          function! lib#source(file)
          let list = []
          let file = readfile(a:file)
          while !empty(file)
          let string = remove(file, 0)
          if (!empty(file) && match(file[0], '^\s*\') == -1)
          call add(list, string)
          else
          while (!empty(file) && match(file[0], '^\s*\') != -1)
          let string .= ' '.substitute(remove(file, 0), '^\s*\', '', '')
          endwhile
          call add(list, string)
          endif
          endwhile
          return list
          endfunction

          > Marc

          Regards,
          Ag.

          --~--~---------~--~----~------------~-------~--~----~
          You received this message from the "vim_dev" maillist.
          For more information, visit http://www.vim.org/maillist.php
          -~----------~----~----~----~------~----~------~--~---
        • Agathoklis D. Hatzimanikas
          ... The above function can parse any vim script, including single line statements, or loops like: for i in [1, 2] |echo i |endfor But it s not suitable for
          Message 4 of 5 , Jan 12, 2009
            On Mon, Jan 12, at 08:45 Agathoklis D. Hatzimanikas wrote:
            >
            > Hi Marc,
            >
            > On Sat, Dec 06, at 03:46 Marc Weber wrote:
            > >
            > > Hi Tony,
            > >
            > > I know about source. That's why I've implemented this:
            > > " FIXME: Is there a better way to execute multi line strings?
            > > function! library#Exec(cmd)
            > > let lines = split(a:cmd,"\n")
            > > if (len(lines) > 1)
            > > " is there a better way? (TODO! try to not use temp files!)
            > > let file = tempname()
            > > call writefile(lines, file)
            > > exec 'source '.file
            > > call delete(file)
            > > elseif !empty(lines)
            > > exec lines[0]
            > > endif
            > > endfunction
            > >
            > > But that is ugly!
            > > In my use case the script doesn't really exist on disk (or better to say
            > > it does, but not as vimscript but serialized vim dictionary)
            > > But suing Exec() You've no chance getting the s: or <sfile> context.
            > >
            >
            > Here is function (to parse external scipts, so and serialized vim
            > dictionaries), that is trying to workaround the limitation of execute.
            >
            > " Function: lib#source(file)
            > "Description: create a list, so we can loop over it by using execute
            > " Args: script to parse
            > " Return: list
            > " Notes: (limited usage)
            > function! lib#source(file)
            > let list = []
            > let file = readfile(a:file)
            > while !empty(file)
            > let string = remove(file, 0)
            > if (!empty(file) && match(file[0], '^\s*\') == -1)
            > call add(list, string)
            > else
            > while (!empty(file) && match(file[0], '^\s*\') != -1)
            > let string .= ' '.substitute(remove(file, 0), '^\s*\', '', '')
            > endwhile
            > call add(list, string)
            > endif
            > endwhile
            > return list
            > endfunction
            >

            The above function can parse any vim script, including single line
            statements, or loops like:

            for i in [1, 2]
            \|echo i
            \|endfor

            But it's not suitable for functions, so I rewrote it to support
            functions as well.

            function! lib#source(file)
            let list = []
            let reg = []
            let nr = 97
            let file = readfile(a:file)
            while !empty(file)
            let string = remove(file, 0)
            if match(string, '^fu\%[nction]') == -1
            if (!empty(file) && match(file[0], '^\s*\') == -1)
            call add(list, string)
            else
            while (!empty(file) && match(file[0], '^\s*\') != -1)
            let string .= ' '.substitute(remove(file, 0), '^\s*\', '', '')
            endwhile
            call add(list, string)
            endif
            else
            while match(file[0], '^endf\%[nction]') == -1
            let string .= "\n ".remove(file, 0)
            endwhile
            let string .= "\n ".remove(file, 0)
            exec "redir @".nr2char(nr)
            echo string
            redir END
            call add(reg, nr2char(nr))
            let nr += 1
            endif
            endwhile
            return [reg, list]
            endfunction

            Now returns a list with two list elements, so you can use something
            like:

            let [reglist, list] = lib#source('script.vim')
            for i in list
            exec i
            endfor
            if !empty(reglist)
            for register in reglist
            exec ":@".register
            endfor
            endif

            From a limited test it looks usable.

            Regards,
            Ag.

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