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

[PATCH] if_lua (was: if_lua patch)

Expand Messages
  • Luis Carvalho
    ... OK, thanks for the suggestion. I m attaching a patch generated by hg diff . To summarize the main changes: - New funcref type, including new vim.funcref()
    Message 1 of 13 , Sep 1, 2012
      ZyX wrote:
      > > No, since the patches are few and far between.
      >
      > Pulling patches from the repository and saving them there is
      > convenient. When I was adding third argument to sort() patch was also
      > not big but I still cloned vim to bitbucket. This decision appeared to
      > be right when I started to extend python interface.
      >
      > Even if you don’t want to create commits, do use “hg diff”. Two
      > patches for two files with requirement to switch to another directory
      > before applying each one is very inconvenient.

      OK, thanks for the suggestion. I'm attaching a patch generated by 'hg diff'.
      To summarize the main changes:

      - New funcref type, including new vim.funcref() function
      - vim.dict() and vim.list() now accept an initializer table as argument
      - Updated docs
      - A few bug fixes (following this thread)


      > > I don't think that's an error in if_lua: the documentation doesn't say
      > > anything about dictionaries not allowing empty strings as keys -- :help
      > > Dictionary only says that 'a key is always a String' -- and hence the absence
      > > of error when printing d in your example. What is not allowed is for you to
      > > read or set empty keys in Vim (using 'let'), but I don't want to replicate
      > > that in if_lua. For instance, you can do this:
      > >
      > > vim -u NONE -c 'let d={} | lua vim.eval("d")[""] = "empty"'
      > > -c 'for [k,v] in items(d) | echo "|".k."| -> ".v | endfor'
      > >
      > > So, to be consistent, if you set an empty key in if_lua, you can read or reset
      > > it there.
      >
      > Yes, you can do “for [k, v] in items(d)”. But you can’t do “for k in
      > keys(d) | let v=d[k]”. I can’t prove that this won’t break anything,
      > maybe you can?
      >
      > Help does not mention this probably because error message is clear
      > enough, I constantly see such things in a doc: “:h E???” exists, but
      > in the text there is nothing concerning error message.

      I agree that there must be a reason for the parser to avoid empty strings, but
      then the documentation should change to reflect this behavior. Ideally this
      behavior should be coded in the API, probably making dict_add check the
      dictitem argument. While I still maintain that that's not an if_lua issue,
      I've updated the code to check for empty keys when setting dict entries, just
      in case it breaks something and for consistency.

      > >> And you have missed another error:
      > >>
      > >> vim -u NONE -c 'lua vim.eval("g:")["input"]=vim.funcref("tr")' -c 'call input("Yes?")'
      > >>
      > >> results in an error “not enough arguments to tr” while it should result in an error “funcref variables must start with a capital” (see my patch to python interface [1] and extend() function [2]).
      > >
      > > There's no error here either. The problem is that tr() expects three
      > > arguments, and not that the variable must start with a capital letter (g:input
      > > already exists.) Try this:
      > >
      > > vim -u NONE -c 'lua vim.eval("g:").input=vim.funcref("tolower")'
      > > -c 'echo input("Yes?")'
      >
      > It is just an example. Vim has very weird way of disallowing
      > overriding built-in and user functions: a check everywhere you can add
      > a value to a dictionary. The fact that you *allow overriding built-in
      > functions* is an error. Not the fact that “tr” expects three arguments
      > or something else.
      >
      > Existence of your behavior in lua interface and my in python (unlike
      > my patch to extend() patch to if_py* was not merged) defeats the
      > purpose of such checks.

      Again, the issue here is not that funcref variables must start with a capital
      letter -- only the parser should check that, not if_lua -- but that if_lua is
      assigning funcrefs to a "builtin" scope dictionary (g: or l:). The fix is
      straightforward: if_lua now checks if dict->dv_scope == VAR_DEF_SCOPE and if
      the value is a funcref and complains if that's the case.

      > > I think you're mixing the fact that Vim Funcref variables should start with a
      > > capital letter. Funcrefs in lua are just a value; for instance, this should
      > > work:
      > >
      > > :lua print(vim.funcref"tr"("<tag>", "<>", "{}"))
      > > " {tag}
      >
      > No, I am not. I do not care how you can name funcrefs in lua, you must
      > not allow using lua to override built-in or user functions by adding
      > something to scope dictionary. The proper way of fixing this all is
      > modifying parser, but modifying lua interface is much simpler. If you

      As I said, you shouldn't really care about Lua "naming" funcrefs, since that's
      a moot point (funcrefs in Lua are just values, they have no names.) But you're
      right that the issue is checking for the dictionary to be a scope; see comment
      above.

      > can modify the parser go ahead and get rid of E704 and E705: in the
      > current state there is exactly no way to safely assign funcref to a
      > variable, only to dictionary key/list item. I can see why parser does
      > this (deref_func_name: it first tries to get a funcref variable and
      > returns name as-is in case of failure), but unsure how to fix it
      > properly (quick fix is returning name as-is if find_internal_func
      > returned something other than -1 or find_func — other than NULL). I
      > also don’t think this fix will be accepted by Bram: it only pretends
      > to solve a problem as now masking functions by variables is replaced
      > by masking variables by a functions:
      >
      > let input="abc"
      > may work properly but
      >
      > function Input()
      > return getchar()
      > endfunction
      > let Input=function('input')
      > call Input("abc")
      > won’t.

      You lost me in this last example and the masking comment, but I believe I do
      not need to change the parser (and shouldn't need to.)

      ZyX wrote:
      > > Right. I think you meant:
      > >
      > > :lua vim.eval('g:').list = vim.list{'abc'}
      > >
      > > or
      > >
      > > :lua vim.eval('g:').dict = vim.dict{key = 'abc'}
      > >
      > > since you forgot the key.
      >
      > No, I meant exactly what I typed. Before reading docs expected behavior was either converting it to “{"1": "abc"}” or an error.

      Ah, I see: you wanted to check for an error since {'abc'} is not valid in Vim.
      I've changed the behavior to be more in line with Lua (and Vim) since numbers
      are usually converted to strings: now vim.dict{'abc'} returns {'1': 'abc'}.

      Thanks once again for your feedback and thorough tests!

      Cheers,
      Luis

      --
      Computers are useless. They can only give you answers.
      -- Pablo Picasso

      --
      Luis Carvalho (Kozure)
      lua -e 'print((("lexcarvalho@..."):gsub("(%u+%.)","")))'

      --
      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
    Your message has been successfully submitted and would be delivered to recipients shortly.