VSCode 高级自定义代码段 [英] VSCode Advanced Custom Snippets

查看:50
本文介绍了VSCode 高级自定义代码段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文

在过去的 18 个月里,我一直在使用 VSCode 的 LaTeX Workshop 扩展来满足我所有的 LaTeXing 需求.到目前为止,我主要将它用于长篇文章和报告,偶尔用于课堂笔记.到目前为止,我已经能够通过几个自定义宏(线性代数排版很容易)使其实时工作得足够好.然而,随着我进入不同的课程,我希望通过实施

Context

For the past 18 months, I've been using the LaTeX Workshop extension of VSCode for all my LaTeXing needs. Up to this point, I've primarily used it for longer-form articles and reports, and sporadically for note-taking purposes in class. I've been able to make it work sufficiently well in real-time so far with just a few custom macros (Linear Algebra typesets pretty easily). However, as I move on to different classes, I'm looking to expand my real-time abilities by implementing Gilles Castel's excellent Vim-based workflow in VSCode. Unfortunately, VSCode seems to obscure or lack (by default) a great deal of the features (especially related to snippets) of which Castel makes use.

My Question

For the purposes of this post, I'd like to focus on his fraction macro (I believe that if I can get this working, I can get much of the rest of it working). Basically, the problem appears to be that VSCode has fairly limited snippets functionality, especially compared to Vim's UltiSnips. Using UltiSnips, Castel has defined an auto-expanding macro (I'm not sure if VSCode supports auto-expanding snippets) that, when a / is typed, takes the preceding word (or words if parentheses are present) and transforms it into the LaTeX fraction format. For example:

//             --> frac{}{}
3/             --> frac{3}{}
4pi^2/        --> frac{4pi^2}{}
(1 + 2 + 3)/   --> frac{1 + 2 + 3}{}
(1 + (2 + 3)/) --> (1 + frac{2 + 3}{})
(1 + (2 + 3))/ --> frac{1 + (2 + 3)}{}

How can I implement this behavior in VSCode?

My Leads

I have spent a significant amount of time researching this, and I have strong reasons to believe that it's possible, and similarly strong reasons to believe that any successful answer to my question is going to have to ELI5 it to me -- this kind of software customization isn't exactly my cup of soup, but I'm definitely willing to learn!

First off, there are two promising VSCode extensions that may be able to implement UltiSnips: Vsnips and HyperSnips. Vsnips looks decent, but it seems to rely on an existing familiarity with UltiSnips and how to configure UltiSnips for your specific computer (if this does end up being important, I use a 2019 MacBook Pro and my software is up to date [macOS Catalina 10.15.5 as of this post]). I haven't been able to figure out even that much with regard to HyperSnips -- neither is very well documented, and none of the documentation is written for readers of my level.

Although I said that VSCode's internal snippets engine appears to be fairly limited, I may be wrong. It seems to interface with another snippets engine called TextMate.

That's all I can think to do for now. If there's any further information that I can provide, please let me know! Thanks!

解决方案

After you install HyperSnips, use its command HyperSnips: Open snippets directory to open the directory where you will put your snippets.

Snippets in all.hsnips will be available in all language files. You can also put your snippets into something like latex.hsnips or Latex.hsnips in the same directory and both versions work for me.


Modifying the code from Castel's guide put this into your chosen <language>.hsnips file:

snippet // "Fraction simple" A
frac{$1}{$2}$0
endsnippet

snippet `((d+)|(d*)(\)?([A-Za-z]+)((^|_)({d+}|d))*)/` "Fraction no ()" A
frac{``rv = m[1]``}{$1}$0
endsnippet

Note that interpolated code goes into double backticks "``" and the value from that code must be assigned to rv (return value). Whatever is assigned to rv will appear in the snippet output. Note also there are additional tabstops $1, $2 and $0 in the above snippets - there values can be accessed by the interpolated code within the t array but you don't need that here.

And then here is the final snippet that works for the harder case of embedded parentheses within your "prefix" like (1 + (2 + 3))/. I think of (1 + (2 + 3))/ just like a traditional vscode snippet prefix EXCEPT that you can use regex expressions as the prefix!! Regex prefixes/triggers must within backticks.

snippet `^.*)/` "Fraction with ()" A
``
    let str = m[0];
    str = str.slice(0, -1);
    let lastIndex = str.length - 1;

    let depth = 0;
    let i = str.length - 1;

    while (true) {
        if (str[i] == ')') depth += 1;
        if (str[i] == '(') depth -= 1;
        if (depth == 0) break;
        i -= 1;
    }

    let results = str.slice(0, i) + "\frac{" + str.slice(i+1, -1) + "}";
    results += "{$1}$0";
    rv = results;
    ``
endsnippet

Here ^.*)/ is the prefix/trigger. The extension looks at all your code as you type for that pattern which is basically at least one ) before a / and then match everything before those to the previous word boundary. And then that match info is available within the matched code as m[0]. You can have capture groups with your prefix/trigger and access them in m[1], etc. but that isn't needed here.

As you can see, the code to be interpolated must be javascript for this extension to work.

The location of that first set of backticks is important! Here

snippet `^.*)/` "Fraction with ()" A
``
   <other code indented here>
   ``  <indented or flush left, didn't seem to matter in my testing>
endsnippet

the indented code is easier to read IMO, but the output will also be indented unless that first set of backticks is not indented (unless of course you want the output indented). I don't that if that is a "quirk" or as planned. But the position of that first set of backticks seems to determine the location of the output.

The body of this final snippet (again code from the guide you linked to, but translated to javascript by me from his python code) just figures out how far to backtrack (character by character) to get an even number of parentheses. Any preceding part of the input prefix/trigger goes before the frac part.

After making changes to this file, always run the command HyperSnips: Reload Snippets to ensure they are ready for testing immediately.

Demo in action:

这篇关于VSCode 高级自定义代码段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆