是否可以将一个片段的输出包含在另一个片段中?

时间:2018-02-23 14:36:18

标签: sublimetext3 code-snippets

生命很短暂,所以我创建了一组片段。其中一个名为Muletilla.sublime-snippet,看起来像这样

<snippet>
  <content><![CDATA[
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

${1:}
]]></content>
  <!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
  <tabTrigger>muletilla</tabTrigger>
  <!-- Optional: Set a scope to limit where the snippet will trigger -->
  <scope>source.php</scope>
  <description>Create the mulelitlla!</description>
</snippet>

输出

if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

另一个名为CreateCustomController.sublime-snippet,看起来像这样:

<snippet>
  <content><![CDATA[
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class Custom${1:Module}Controller extends SugarController
{
  public function action_${2:name}()
  {
    ${3:// add logic here}
  }
}
]]></content>
  <!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
  <tabTrigger>controller</tabTrigger>
  <!-- Optional: Set a scope to limit where the snippet will trigger -->
  <scope>source.php</scope>
  <description>create a custom controller</description>
</snippet>

如您所见,我需要再次使用muletilla输出,我需要在其他snipptes中执行相同的操作。可以将一个片段的输出包含在另一个片段中吗?

在这种情况下,请在我创建的任何其他代码段中使用muletilla的输出。

提前致谢

1 个答案:

答案 0 :(得分:1)

这种事情在我猜你想要它的意义上是不可能直接实现的,其中你可以在第二个片段中添加一些东西来告诉它它应该拉入第一个片段的内容并插入它内联以及其他所有内容。

有人可能会认为,当一个代码片段即将展开并在运行时重写它时,插件可能会被捕获。但是,在一般情况下,当片段即将插入时,插件没有真正的方法可以捕获,因为缓冲区完成,sublime-snippetsublime-completions文件都在可以完成的项目列表中混合在一起。

一个可能的解决方案是从其他地方获取其片段数据的插件,并将其作为自定义完成提供,而不是直接使用片段。在这种情况下,插件本身将负责提供插入的内容,它可以根据需要重写。

另一种解决方案是允许您以中间格式指定代码段的程序包,以便它可以为您生成最终的代码段,在这种情况下,它将解除在必须手动更新所有代码段时的负担。子片段更改。

那就是说,不幸的是,我不知道任何现有的包装都能做到这两件事。

对于您问题中列出的情况,如果您将第一个代码段的结尾指定为${0}而不是${1},Sublime会将其展开并将光标放在{$0}点上提供任何扩展领域。这将允许您触发它,然后立即触发第二个而不先按Tab键。

然而,这只是保存按键。

虽然这不是一般解决方案,但这里是另一种使用核心Sublime在这里做你想做的事情的方法。

首先,您需要在tmPreferences包中创建一个User文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>scope</key>
  <string>source.php</string>
  <key>settings</key>
  <dict>
    <key>shellVariables</key>
    <array>
      <dict>
        <key>name</key>
        <string>muletilla</string>
        <key>value</key>
        <string><![CDATA[if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');]]>
        </string>
      </dict>
    </array>
  </dict>
  <key>uuid</key>
  <string>75888874-b1ed-460d-ab0e-9d1741d50188</string>
</dict>
</plist>

文件名无关紧要(只有扩展名很重要),您需要将scope更改为合适的名称。

shellVariables内部,您可以定义自定义变量及其内容。此示例创建一个名为muletilla的变量,其内容是第一个代码段的第一行(公共文本)。

请注意,CDATA的内容已插入逐字;这意味着任何前导或尾随换行都将进入,并且您不能在值中使用任何变量替换,因为它们将按原样插入而不会进一步扩展。

有了这个,你的第一个片段就变成了:

<snippet>
  <content><![CDATA[
${muletilla}

${0}
]]></content>
  <!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
  <tabTrigger>muletilla</tabTrigger>
  <!-- Optional: Set a scope to limit where the snippet will trigger -->
  <scope>source.php</scope>
  <description>Create the mulelitlla!</description>
</snippet>

第二个片段变为:

<snippet>
  <content><![CDATA[
${muletilla}

class Custom${1:Module}Controller extends SugarController
{
  public function action_${2:name}()
  {
    ${0:// add logic here}
  }
}
]]></content>
  <!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
  <tabTrigger>controller</tabTrigger>
  <!-- Optional: Set a scope to limit where the snippet will trigger -->
  <scope>source.php</scope>
  <description>create a custom controller</description>
</snippet>

这适用于这种情况,但如果您希望公共文本包含某种类型的占位符,则会出现问题。如果你想要改变它,你必须记住定义变量的位置,而不是简单地引用另一个片段,这也可能更加痛苦。