Sublime Forum

Snippet Capabilities Questions

#1

This is sort of a snippet question and sort of a plugin question. I’m trying to figure out which features of a language mode that doesn’t yet exist might be supported by snippets and which might require full plugin support. In particular, the language I’m working to support is VHDL. There is a syntax mode in the package repository, but I’m attempting to emulate the more full featured language support that currently exists in Emacs vhdl-mode which is pretty extensive. But… baby steps first.

So, onto the question, snippets seem pretty powerful however I’m not sure they’ll completely do the trick.

Question 1) Can a snippet hide/erase portions of a declaration that are possible, but not always present?

For example, one of the most basic VHDL language blocks is the entity description. It looks like this:

entity <entity name> is
    generic (
        generic_object_1 : type := default value;
        ....
        generic_object_n : type := default value
    port (
        port_1 : direction type;
        ....
        port_2 : direction type
    );
end entity <entity name>;

None of these items save for the first and last line are mandatory. Most frequently, the port block is filled out, and sometimes the generic block is filled out. Is there a way to have the snippet hop to a block object, but if the user types enter with no text entry, it’ll omit that portion of the block and skip to the next?

Question 2) Is it possible to overwrite the triggering text?

For example, another language construct is a process. There are a couple different forms for this, but here’s an example:

PROCESS_NAME : process (some, stuff, goes, here)
begin
    Other code here;
end process PROCESS_NAME;

What I’d LIKE to have happen is that the user type something like ‘procseq’ and hit tab. Then it undoes that word, moves back to the start of the line, prompts for that name, and then carries on through the field. Another variation might be triggered by ‘proccomb’ and tab. I just don’t want the snippet evocation command to be in the file after the snippet is triggered.

Question 3) Is it possible to embed point control in a snippet?

This one is kind of basic, but say I have a large mandatory comment header that needs to go into the file. Seems perfect for a snippet however I want to make sure it always goes at row 1, col 1. Is there a way to do this inside the snippet? If not, presumably a workaround might be to create a plugin command that upon evocation, moves the point to 1,1 and then triggers the snippet. But if I can do it within the snippet itself that would be good.

I think that takes care of it. I managed to find my other answer while researching these other questions (the language is kind of verbose, so there’s a lot of those blocks that start with a name, and the same name is repeated at the end – mirroring text fields does that trick.) Thanks in advance and I’ll be checking back. This is actually kind of exciting – the first editor I think that could really encompass this very complex language mode.

0 Likes

#2

Well with some experimentation, I discovered that if you have a “code word” for your snippet trigger it already does overwrite the region. I hadn’t noticed before because the python snippet triggers were already the languages keyword (like ‘class’) so I hadn’t noticed what happened.

I still don’t know if there’s a way to make portions of a snippet hide (or not trigger) and not sure (but from what I’ve read I don’t think so) if I can move the point upon triggering a snippet.

I do have a 4th question I’ve been unable to sort out. The unofficial documentation says that there are other global variables that might be referenced in a snippet, and they’re in .sublime-options however the only mention I’ve seen to this file is actually in the snippets documentation. I did run across something that looked similar in a YAML file format, but that didn’t look like the more usual JSON settings format, and I’m really not sure if that’s the most appropriate place. I’d like to (in the snippet) substitute some more user defined stuff (company name, etc). So:

Question 4) How does one define additional ‘global’ substitution parameters for a snippet?

related because I didn’t find it

Question 5) Is there a snippet substitution for current date?

Thanks for listening.

0 Likes

#3

number 1 is usually solved by having one of the tab stops select the content that is optional, so one can press TabDel to quickly delete it and move on :slight_smile:

the answer to number 2 is the trigger will always be overwritten unless this bug is encountered (at least, I think the completions bug applies to snippets also, could be wrong):

number 3 is not possible from a snippet alone, but could be done with a plugin

number 4 can be answered here:

number 5 here:

0 Likes

#4

Thank you. I had found the bit about the custom variables in shellVariables. That’s the XML looking document. It’s a bit unfortunate that that’s the location as I think that’s a lot harder for an end user to edit but for now it’s the necessary step. Maybe sometime in the future a snippet could pull a user defined text out of a settings file instead since that is a much less verbose and easier to edit file.

The bit with the tab stops I’ll have to research and experiment with. I don’t think it’ll behave the way I want, but it might be sufficient in the end. There does exist a VHDL package already and I extracted that and studied the snippets that exist there and saw what compromises were made there.

The date inclusion was an interesting thing I’ll have to experiment with. I had not really tinkered with Macros just yet. Nor commands. (Or maybe they’re the same thing – I’m not entirely sure.)

Thanks for the references and information. I had been searching the undocumented docs, but hadn’t thought to try to search the tickets too.

0 Likes

#5

agreed, when one doesn’t know where to look, it’s not obvious at all :wink:

one could always write a plugin to build their own snippet behavior - the great thing about ST is it’s extensibility :slightly_smiling:
maybe someone has already done something similar - a quick search brought up https://packagecontrol.io/packages/SnippetCaller

0 Likes

#6

Oh well yes, I already have some ideas along those lines. However, my python is definitely in the hack range. I’ve written some things for utility work at work like bit reversals and MIF file creation but I am not a heavy duty user so I’ve got that to contend with, then learning the API on top of that. However Sublime is the first editor I’ve seen since Emacs that has the potential to do what I’d like to see it do, so I’m somewhat hopeful. All prior candidates (Notepad++, TextMate, etc) have had to hack things to approximate what I can do with vhdl-mode in emacs and still only only get part of the way there.

And there still may be some behavior I can’t duplicate. For example, there is such a thing as stutter-step editing in vhdl-mode where for a language construct (for example ‘<=’ which is a signal assignment symbol) that requires an awkward right hand movement can be simplified to just ‘,’ (two commas – proportional font makes that look strange) and the editor automatically inserts the left facing arrow symbol. Now I’ve successfully duplicated this with snippets but that requires a tab afterwards. Not a bad compromise, and maybe that’s the best that can be done.

But the potential is there. Obviously we’re monitoring text for snippet completion. I might be able to hook into that and look for stutter completions too!

Anyway, we’ll see how far I get. The holy grail would be beautification but the lisp routine for that in vhdl-mode is pretty intense and thus far it’s been so difficult to duplicate that most other editors just suggest having an emacs installation and then runs the file through emacs with the beautify command! It works, my non-emacs-using coworker does that, but it’s a pretty crude hack.

So my initial projects are snippets for the language with increasing complexity, maybe a simple plugin (move point to 1,1 and call insert snippet for header, move point to EOF and call insert snippet for footer), and then my first big project will be port duplication, something language specific, but I’m pretty sure I can write a plugin for that one once I understand things more.

0 Likes

#7

you could just create a keybinding that will work when you press < followed by = or just one for when you press = and < is the character immediately preceding the text caret. e.g.

though the suggestion there doesn’t take into account which file type / syntax to apply it to, but that is easily added by looking at how the default keybindings do it. I’m on mobile right now so can’t really elaborate further I’m afraid

0 Likes