Emacs 离开域上的yasnippet条件变换

Emacs 离开域上的yasnippet条件变换,emacs,yasnippet,Emacs,Yasnippet,我正在编写一个代码段(用于Go),希望在移动到下一个字段时有条件地转换一个字段。具体地说,如果我不编辑字段,我希望字段为空;如果我不编辑字段,希望字段用括号括起来 我的不成功代码段,表达了我想要的内容,但未能转换已编辑的字段: func ${1:$$(when (and yas-modified-p yas-moving-away-p) (concat "(" yas-text ")"))} FuncName 我想要的是,当在字段中键入t Type时,代码段将按如下

我正在编写一个代码段(用于Go),希望在移动到下一个字段时有条件地转换一个字段。具体地说,如果我不编辑字段,我希望字段为空;如果我不编辑字段,希望字段用括号括起来

我的不成功代码段,表达了我想要的内容,但未能转换已编辑的字段:

func ${1:$$(when (and yas-modified-p yas-moving-away-p) 
             (concat "(" yas-text ")"))} FuncName
我想要的是,当在字段中键入
t Type
时,代码段将按如下方式展开:

func (t Type) FuncName
当跳过未编辑的字段时,它会如下展开:

func FuncName

我知道该条件会按预期执行,因为如果我将
(concat…
更改为
(message“XXX”)
,我会看到打印在微型缓冲区中的跟踪,但我无法理解为什么转换不起作用。

在您的示例中,我认为连接字符串的结果被丢弃。我认为您需要将新字符串实际插入缓冲区

我对yasnippet语法不是很熟悉,因此这可能不是最干净的解决方案,但以下内容似乎对我很有用:

func ${1:$$(when (and yas-modified-p 
                      yas-moving-away-p) 
              (insert ")" )
              (backward-char (+ 1 (length yas-text)))
              (insert "("))} ${2:funcName} {
    $0
}

文档建议您需要将elisp表单包装在“backticks”中,以便将返回值合并到代码段中(很像shell脚本中的命令替换)


让代码段以

func () FuncName

如果保留为空,请删除括号?

这几乎奏效,但由于
向后单词
只需要一个单词,因此在片段扩展后,输入的
t Type
将变成
t(Type)
。很好,我没有注意到这一点。幸运的是,您可以简单地使用
yas text
的长度,而不是单个单词。我已经更新了我的示例来演示这一点。事实上,这似乎是首选的解决方案。如果字段的值不是空字符串,则可以在第一个字段周围使用两个镜像,分别有条件地返回“(”和“)”字符串。这是最好的方法。由于对emacs lisp不太熟悉,我不得不在达到以下目标之前进行一些尝试和错误:
func${1:$(when(>(length yas text)0)”(“”)}$1${1:$(when(>(length yas text)0)”)}FuncName
。有没有更紧凑的方法来实现这一点?