vim-jp / issues

有志で既知のバグや要望を検討・管理し、オフィシャルへの還元をしていきます。
https://vim-jp.org/
341 stars 11 forks source link

vim9scriptを叩く #1332

Open k-takata opened 4 years ago

k-takata commented 4 years ago

Vimに導入されたばかりのvim9scriptについて議論しましょう。

vim9scriptについては、vim9.txt を参照。

次のリリースが出たら、このissueは閉じます。

mattn commented 4 years ago

See https://github.com/vim-jp/issues/issues/1331

mattn commented 4 years ago

リストのスライスが使えない。

def Proc(): list<string>
  let ll: list<string> = ["1", "2", "3"]
  return ll[1:]
enddef

call Proc()
k-takata commented 4 years ago

list<string> 型で空のリストを扱えない。

def Func(): list<string>
  return []
enddef

E1013: type mismatch, expected list<string> but got list<any>

mattn commented 4 years ago

関数スコープ、引数スコープは無くても良くなったはずなのに a:l: が邪魔(型指定として扱われてしまう)をして1文字変数を作れない。

def Proc(): void
  let a: number = 1
enddef
mattn commented 4 years ago

nr2float/float2nr が無い。number から float にキャストする際は 0.0 + n で行けるけど float から number にする方法がない。

def Proc(n: float): number
  return n
enddef
k-takata commented 4 years ago

float2nr はありますよね?

mattn commented 4 years ago

呼び出せない...

k-takata commented 4 years ago

動きました

def Proc(n: float): number
  return float2nr(n)
enddef

echo Proc(3.14)
mattn commented 4 years ago

たしかに

mattn commented 4 years ago

辞書も同様。

https://github.com/vim/vim/blob/4549ece47cc8d6487d8e64ae37361fea87e3ad39/src/vim9compile.c#L2292-L2293

k-takata commented 4 years ago

README_VIM9.md に記載ミス https://github.com/brammool/vim9/pull/1

k-takata commented 4 years ago

todo.txt が更新されました。 https://github.com/vim/vim/commit/560979ed4f0216f902a2c247e937f00a27dcb198#diff-38d7929bd26d74d92ceddf984bbfc8dbR45-R78

type|type 型が未実装なのが載ってないなぁ

k-takata commented 4 years ago

:help vim9-types

The following builtin types are supported:
    bool
    number
    float
    string
    blob
    list<type>
    dict<type>
    (a: type, b: type): type
    job
    channel

func が載っていない。(さらに言えば、vim9compile.c の parse_type() では "func" だけど、vartype_name() では "function" と "partial" になっていて実装が一致していない)

These types can be used in declarations, but no variable will have this type:
    type|type
    void
    any

type|typeanyは変数の型としても使えてもよさそうな気がするが…

mattn commented 4 years ago

func 実装が無いんですよね。

https://twitter.com/mattn_jp/status/1221320829247475712

Bakudankun commented 4 years ago

import ... as ... は未実装?

" test.vim
vim9script
import Hoge as Fuga from './import.vim' " => E1047: syntax error in import
echo Fuga
" import.vim
vim9script
export let Hoge = 'Hoge'
Bakudankun commented 4 years ago

辞書内の関数が call 無しで呼び出せない……

vim9script
def Fuga()
    echo 'Fuga'
enddef

let Hoge = #{Fuga: funcref('Fuga')}

Fuga() " => Fuga

call Hoge.Fuga() " => Fuga

Hoge.Fuga() " => E492: エディタのコマンドではありません: Hoge.Fuga()
k-takata commented 4 years ago

リストに対して += が使えない。おそらく Blob も。

li: list<any> = []
li += ['foo']

E1013: type mismatch, expected number but got list<string>

一応、ソースには TODO が書かれている。 https://github.com/vim/vim/blob/c2a4b35b86fa8b28a34a9aea8ad16c87dbc6d834/src/vim9compile.c#L3483-L3489

mityu commented 4 years ago

関数内で:execute の後ろに変数を持ってくるとエラーが出ます。

def Hoge(): void
  let cmd: string = 'echo "hoge"'
  execute cmd "printf('%s', cmd) 等でもエラーが出ます。
enddef
call Hoge()
function Hoge, line 1
E121: Undefined variable: cmd

追記: エラー箇所は関数内の2行目だと思われます。(https://github.com/vim-jp/issues/issues/1332#issuecomment-583734831)

mityu commented 4 years ago

:function:def で同名の関数を定義した場合、常に :def で定義された方が呼び出されます。

def! Hoge()
  echo 'def! Hoge()'
enddef
function! Hoge()
  echo 'function! Hoge()'
endfunction
call Hoge()

function! Fuga()
  echo 'function! Fuga()'
endfunction
def! Fuga()
  echo 'def! Fuga()'
enddef
call Fuga()
def! Hoge()
def! Fuga()
mityu commented 4 years ago

関数内のどこでエラーが出てもエラー箇所がline 1となる模様です。

def! Hoge(): void
  hoge
enddef
call Hoge()  " =>  function Hoge, line 1  E492: Not an editor command:   hoge

def! Hoge(): void
  let var: any
  hoge
enddef
call Hoge()  " =>  function Hoge, line 1  E492: Not an editor command:   hoge
skanehira commented 4 years ago

関数外だと型チェックされていないっぽい?

vim9script

let animals: list<string> = [1, 'cat', 'dog']
echo animals

関数内の場合はE1013: type mismatch, expected list<string> but got list<number>がでます。

vim9script

def Test()
  let animals: list<string> = [1, 'cat', 'dog']
  echo animals
enddef
kuuote commented 4 years ago

vim9script宣言の後にfunctionを使おうとするとfunction内で引数が使えないようです

vim9script

let hoge: string = "hoge"

function Hoge(fuga)
  echo a:fuga
endfunction

call Hoge(hoge)

上記のコードを実行すると

function <SNR>169_Hoge, 行 1
E121: 未定義の変数です: a:fuga

のようなエラーが出ます

skanehira commented 4 years ago

これが実行できてしまいました。型チェックガバガバ…

vim9script
def A()
  let animals: list<string> = ['gorilla', 2, 3]
  echo animals
enddef
call A()
skanehira commented 4 years ago

readfile()がany型を返すようです。リストではないのでfor回せなかったです。

vim9script

def ReadFile()
  " result => E1013: type mismatch, expected list<string> but got any
  let text: list<string> = readfile("badapple.txt")
enddef

call ReadFile()

一応回避策はあります。

vim9script

function! s:read_file() abort
  return readfile("badapple.txt")
endfunction

def ReadFile(text: list<string>)
  for i in text
    echo i
  endfor
enddef

call ReadFile(s:read_file())
skanehira commented 4 years ago

ブロック内でブロック外で宣言済みの変数を再宣言できない様ですね。 スコープごと変数のスタック領域を持っているわけではなさそう…?

vim9script

def A()
  let num = 0
  {
    let num = 1
  }
  echo num
enddef

call A()
kuuote commented 4 years ago

v8.2.0259 rangeで生成された空のリストをforループにかけると落ちるケースがあるみたいです

def! s:hoge()
  for i in range(3, 1)
    echo i
  endfor
enddef

call s:hoge()
mattn commented 4 years ago
def Proc(x: list<float>, y: list<float>)
  let r = x[0] * y[0]
enddef

call Proc([1.0], [2.0])
E1036: * requires number or float arguments              

普通の掛け算ができない。

kuuote commented 4 years ago
def! s:hoge(is_cmd)
  let tag = 'vim9'
  if is_cmd
    "invalid
    execute "help " .. tag
  else
    "valid
    execute("help " .. tag)
  endif
enddef

Exコマンドのexecuteの引数が解決されないまま渡ってるっぽい

k-takata commented 4 years ago

https://github.com/vim-jp/issues/issues/1332#issuecomment-581258934 PR出してみた。https://github.com/vim/vim/pull/5669

mityu commented 4 years ago

https://github.com/vim-jp/issues/issues/1332#issuecomment-583729537 PR出してみました。 https://github.com/vim/vim/pull/5699

mityu commented 4 years ago

Vim 8.2.348 です。 return文でバッファ/ウィンドウ/タブローカルの変数を参照する関数を定義しようとすると SEGV で落ちます。

let b:buflocal_num = 0
let t:tablocal_num = 1
let w:winlocal_num = 2
def! s:bug(): number
  return b:buflocal_num
  " return t:tablocal_num
  " return w:winlocal_num
enddef

以下の様に回避しようとしても同様に落ちます。

def! s:bug(): number
  let num = b:buflocal_num
  " let num = t:tablocal_num
  " let num = w:winlocal_num
  return num
enddef
tennashi commented 4 years ago

Vim 8.2.363 import した関数を funcref()/function() で見付けられない

import { Hoge } from './test.vim'

let A = funcref('Hoge')
A()
line   21:
E700: Unknown function: Hoge
line   22:
E117: Unknown function: A

ここで間違えて文字列ではなく Hoge そのものを渡すと SEGV で落ちる

import { Hoge } from './test.vim'

let A = funcref(Hoge)
A()