Conditionally skip a field in yasnippet

Viewed 74

I'm trying to create a yasnippet for a MOVE statement i COBOL. Writing MOVE statements is something we do ALOT of and I want to be as fast and efficient as possible with it.

Usual it is something like this:

MOVE variable-1 TO variable-2

but sometimes you use functions as well:

MOVE FUNCTION LENGTH(variable-1) TO variable-2

So what I'm after is a snippet which skips field-2 if field-1 = "FUNCTION".

What I have right now is:

MOVE $1 ${2:$$(unless (or yas-modified-p yas-moving-away-p (equal (upcase (yas-field-value 1)) "FUNCTION")) (yas-skip-and-clear-field))} TO $0

This works great for the "MOVE FUNCTION ..." case but otherwise it don´t. Here when I hit after entered varaible-1 in field-1 i get (cursor is |):

MOVE variable-1 #<marker at 2998 in text.cbl>| TO

So it seems that the return value from yas-skip-and-clear-field get printed instead of doing the jump to $0.

How could I solve this? Or are there any better way of doing this?

2 Answers

If you add FUNCTION ALL INSTRINSIC to the Repository paragraph in the Configuration Section, you need not code FUNCTION in your MOVE statements. This might alleviate your problem without having to use yasnippet.

I wrote similar snippet for systemverilog 'logic', whose syntax is:

logic MySignal;

or

logic [31:0] mybus;

So ideally, if 'logic' followed by is typed, the snippet would expand the first field unconditionally. If that field contains [number:number], it expands the other field with name. If [] is not found, the field is considered to be a signal name.

It is not perfect, but here is what I have came with:

# -*- mode: snippet -*-
# name: logic
# key: logic
# --
logic ${1:range_or_signal}${2: $(if (string-match "\\[[0-9\s]+:[0-9\s]+\\]" (yas-field-value 1)) (concat " " (string-trim yas-text)) (yas-auto-next ""))};
$0

Basically the first field is always entered, and the other one is skipped if first one is not vector definition. The skipping is performed by yas-auto-next

Related