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

Re: why is exec limited?

Expand Messages
  • 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 1 of 5 , Dec 5, 2008
    • 0 Attachment
      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 2 of 5 , Jan 12, 2009
      • 0 Attachment
        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 3 of 5 , Jan 12, 2009
        • 0 Attachment
          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.