javascriptvimultisnips

Define UltiSnip With Variable Default Placeholder


I'm using the excellent UltiSnips Vim plugin to help improve my development workflow. I've been using it for several years now, and it has really helped me automate a lot of my redundant typing while coding.

Anyhow: I'm attempting to define a snippet that helps me generate Javascript require statements.

A normal Javascript require statement looks something like this:

let express = require('express');

So, here's the snippet I defined:

snippet req "require a module" b
let ${1} = require('${2}');
endsnippet

This lets me type req in Vim, which will then move my cursor to the ${1} position in the snippet so I can define the variable name. Once I hit a second time, my cursor will be moved to the location of ${2} in the snippet, this way I can define the actual Javascript module name to import.

This works fine, but what I'd like to do is take it one step further. I'd like to make a snippet such that:

When I enter a value for ${1}, the value ${2} is updated to be the value of ${1} by default. This way, I can save on typing the same module name twice in certain situations.

The idea is that I should be able to do something like this:

snippet req "require a module" b
let ${1} = require('${2:${1}}');
endsnippet

This way, if I type:

req<tab>express

I should end up with the following expanded line:

let express = require('express');

However, it should also work in this situation:

req<tab>exp<tab>express

Which would output:

let exp = require('express');

Does that make sense?

Anyhow: any help would be appreciated! The code sample above does not work like I thought it would. The ${2:${1}} bit is ignored and doesn't work as expected (it doesn't set the placeholder value of ${2} to ${1}).


Solution

  • The following snippet satisfy both req<tab>express and req<tab>exp<tab>express: (a slight modification of your idea)

    snippet req "require a module" b
    let ${1} = require('${0:$1}');
    endsnippet
    

    $1 is mirror for placeholder ${1}. Also replaced 2 with 0 as snippet ends in this placeholder. To add visual support just add ${VISUAL} to placeholders. As @lwassink provided instructions, i just give snippet:

    snippet req "require a module" b
    let ${1:${VISUAL}} = require('${0:$1}');
    endsnippet