corvofeng / Vsnips

Ultisnips for vscode
38 stars 3 forks source link

[feature request] 考虑支持一下 vim script 的 `expand()` #10

Closed hikerpig closed 4 years ago

hikerpig commented 4 years ago

例如我在 generate.ts 文件里,想输入一个 log 语句 , console.log('[generate]', ),会这么写:

snippet cwfn "console with current filename"
console.log('[${1:`!v expand('%:r')`}]', $2)
endsnippet

vscode 里有 $TM_FILENAME 这个变量,不过 ultisnips 里并没有 builtin Variable 这一说,基本靠着 script 就能解决所有问题。

补充一下 expand 的说明

个人感觉 vim script 的 strtime 和 expand 应该都挺常用的。当然如果不好都实现的话,可以考虑下在 vimRewrite 里,把没有匹配的 script 保留下来,然后增加一些用户扩展函数的机制。

corvofeng commented 4 years ago

可以加吧, 应该和strtime的处理方式一样, 尝试替换成vscode支持的snippet占位符.

corvofeng commented 4 years ago

我读了一下expand的相关文档, %r可能在VSCode中不好支持, 从文档来看, %r的行为在VSCode中可能要与Vim中不一致了,

:echo expand('%:r') | def/my | name of file less one extension ('root')

Vim中有当前目录的, 但是VSCode中一般是基于项目打开的, 也不一定从命令行走, 所以这个%r就应该表示不带后缀的文件名了.

corvofeng commented 4 years ago

14

hikerpig commented 4 years ago

我感觉 jsFuncDecorator 转写的方式似乎把事情变得复杂了。

例如 js_get_simple_box ["arg1", "arg2", "arg3"] 为什么不转为 js_get_simple_box(arg1, arg2, arg3) 呢?

实际脚本的调用可以使用 node.js 的 vm 模块

corvofeng commented 4 years ago

我们先看下从js_get_simple_box ["arg1", "arg2", "arg3"]js_get_simple_box(arg1, arg2, arg3)经过了哪些操作:

1: 参数列表前移, 变成js_get_simple_box("arg1", "arg2", "arg3")

  1. 而后脱掉了", 变成js_get_simple_box(arg1, arg2, arg3)

我先说一下第一种参数前移带来的后果和解决方案, 此种情况下, 复杂一点的处理也可以支持. 首先, 要考虑到, 如果arg1中本身带有逗号, 那么参数列表形如"arg,1","arg2","arg3", 此时, 单纯的split(',') 会导致参数列表的不正确解析. 所以此时的参数列表的处理会变得复杂. 一种可能的解决方案是, 不处理参数, 将vsContext使用bind绑定至js_get_simple_box函数上, 再使用eval或是vm模块完成调用, 这种方案可以可以考虑接受. 另一种方案是, 解析出参数列表后, 在左右套上[], 使其变为["arg1", "arg2", "arg3"]这样可以和原始的形式一致.

第二种脱掉引号带来的后果: 以expand("%:r")为例, 调用时js_func(%:r), 这个语法是有问题的, 而且更加无法处理参数中含有逗号的形式, 是不能使用的.

综上所述, 我最多可以接受的方案是: js_get_simple_box("arg1", "arg2", "arg3"), 参数一定为字符串, 并且带有双引号.

hikerpig commented 4 years ago

昨天我的理解可能有点偏差,可能混淆了形参 param 和实参 arg ,'arg1' 这样被处理完的实参作为字符串的确应该是被引号包裹的。

我的直观感觉是,我们没有必要重新实现 vm 模块已经有了的功能,所以以下的这个方案也是我感觉可行而且合乎直觉的。

一种可能的解决方案是, 不处理参数, 将vsContext使用bind绑定至js_get_simple_box函数上, 再使用eval或是vm模块完成调用, 这种方案可以可以考虑接受



corvofeng commented 4 years ago

把没有匹配的 script 保留下来,然后增加一些用户扩展函数的机制。

一些标准的vim函数, 一般提了issue我会考虑加的, 类似一些自定义的Python函数, 默认可以自己写js进行覆盖, 参见example/fun.js, 我推荐自己的snippet尽量使用Python函数.

hikerpig commented 4 years ago

把没有匹配的 script 保留下来,然后增加一些用户扩展函数的机制。

一些标准的vim函数, 一般提了issue我会考虑加的, 类似一些自定义的Python函数, 默认可以自己写js进行覆盖, 参见example/fun.js, 我推荐自己的snippet尽量使用Python函数.

明白。我们有 userscript 的话的确应该这么做,毕竟对 vim 标准函数支持可能没个尽头。

现在剩下稍微麻烦一点的地方就是同一个函数vim里python 写一遍然后这边 js 再实现一遍,可能之后可以写一个 FAQ 啥的放在 readme 里吧。现在甚至有点考虑去给 ultisnips 加一个 js script 的功能了。

目前这个 issue 可以关掉了,关于 jsFuncDecorator 的问题假如有眉目的话我会再提新的 issue。

corvofeng commented 4 years ago

jsFuncDecorator 改过了

5486e90d63d1a3709cc59afa2d06d025570847e7