I have a snippet defined as followed:

data ${1:Type}
  = ${2:Constructor}
  | ${3:Constructor}

I'd like to have new cases added along the way:

data T
  = A " <Tab>
  | B " <Tab>
  | C " <Tab>
  | D

How can I do it?

1 Answer 1


I would suggest using the UltiSnip's context feature. This feature requires you to specify a python expression which returns True iff the cursor is currently in a valid context. In this case, the context expression is a function isDataDecl() which we can define above the context definition.

The code below will match data declarations of the form you described above. You can tweak it to have less strict requirements, but it works as a proof of concept. In the snippet below I added the requirement for a | at the end of the line to avoid accidentally triggering the expansion for constructors when it is not desired. Thus, using it would look like this:

data T
  = A|<Tab>
  | B|<Tab>
  | C |<Tab>

(the spaces before the | will be removed)

global !p
def isDataDecl():
    pipeLine = re.compile("^\s+\|.*$")
    eqLine   = re.compile("^\s+=.*$")
    dataLine = re.compile("^data\s+.*$")
    line = snip.line
    while pipeLine.match(snip.buffer[line]):
        line = line-1
    return eqLine.match(snip.buffer[line]) and dataLine.match(snip.buffer[line-1])

context "isDataDecl()"
snippet '\s*\|$' "data constructor" ri

| ${1:Constructor}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.