atom / snippets

Atom snippets package
MIT License
204 stars 102 forks source link

Tab stops at the start of an indented line select all leading whitespace #140

Closed nathanbuchar closed 7 years ago

nathanbuchar commented 9 years ago

This is a pretty specific bug, hopefully I explain it well!

If you have a snippet with a tab stop that starts at the beginning of a line, it will also select all space to the left of the tab stop. Therefore, if you're attempting to place the snippet within an indented area, the tab stop will also select all the empty space to the left.

However, this appears to only happen when the snippet is preceded by a multi-line comment.

Below, you'll see two identical snippets, however the first one has a preceding multi-line comment. When tabbing to the class_name tab stop, you'll see that it selects too much space, but this is not the case for the second example (the built-in proto snippet).

It should be noted that the multi-line comment must be defined as part of the snippet. Writing a multi-line comment, then invoking the proto snippet will not cause this bug to occur.

screen shot 2015-05-20 at 10 40 37 am

screen shot 2015-05-20 at 10 41 45 am

My snippet definition:

'.source.js'
  'Prototypal method':
    'prefix': 'method'
    'body': """
      /**
       * @method ${1:method_name}
       * @description ${2:description}
       */
      ${3:class_name}.prototype.${1:method_name} = function (${4:first_argument}) {
        ${5:// body...}
      };
    """

Here, ${3:class_name} follows a multi-line comment, and also is also at the start of a line.

winstliu commented 9 years ago

I believe I've seen this while writing my own snippets as well using something like

switch(${1:something})
{
    case ${2:somethingElse}
    {
        ${3:/* code */}
    }
   ${4:/* Add more cases through the case snippet */}
}
nathanbuchar commented 9 years ago

149 is exhibiting similar behavior, but in that case it's important to note that the tab stop is preceded by a multi-line comment made from // instead of /** */ as was the case with mine.

caleb531 commented 9 years ago

I can confirm that the issue also occurs for me when the snippet is indented and the tab stop is followed by a newline (\n). Here's the snippet I used:

'.source.python':
  'if':
    'prefix': 'if'
    'body': "if ${1:condition}:\n\t${2:pass}\n$3"

bug

Strangely enough, when the tab stop is preceded by a newline and a tab (\n\t), then the preceding whitespace is not selected, which is the expected behavior:

'.source.python':
  'if':
    'prefix': 'if'
    'body': "if ${1:condition}:\n\t${2:pass}\n\t$3"

weird-case

ilourt commented 8 years ago

I have the same behavior.

Is there a plan to correct it?

keathley commented 8 years ago

I'm also having this issue in the language-elixir package. The snippet should produce:

  @moduledoc """
  documentation
  """

But as others have noted it selects all of the proceeding whitespace:

atom_example

The snippet definition:

  'moduledoc':
    'prefix': 'moduledoc'
    'body': """
      @moduledoc \"\"\"
      ${0:documentation}
      \"\"\"
    """

The workaround that I've been using is to just change the snippet to:

  'moduledoc':
    'prefix': 'moduledoc'
    'body': """
      @moduledoc \"\"\"$0
      \"\"\"
    """

This requires the user to insert a new line themselves after the snippet is expanded. It works, but it would be nice to figure out a real solution to this. I'm happy to do research or provide other information if it helps.

nathanbuchar commented 7 years ago

Woohoo! Thanks @50Wliu :)