Snippets: get the selection?


#1

In TextMate and Sublime snippets, there are several placeholders such as $SELECTION.

This way I can have an optional selection if the snippet is called from a command, or an edit point if the snippet is called with a tab shortcut.

Such as

(function() {
  'use strict';

 $SELECTION $1

})();

I’ve already set up the tab-expansion version in Atom, but how about the wrap command?


#2

If you are trying to use $SELECTION in a snippet, it won’t work. You would have to use coffeescript. See related issues: https://github.com/atom/snippets/issues/33 & https://github.com/atom/snippets/issues/46.


#3

Use coffescript how?


#4

Pseudo code:

selection = editor.getLastSelection()
selectionRange = selection.getBufferRange()
text = selection.getText()
newText = "(function() {\n  'use strict';\n\n#{text}\n\n})();"
editor.setTextInBufferRange(selectionRange, newText)

Reference API.


#5

Would greatly appreciate if you could post a fuller version of your suggestion. I am not very familiar with advanced techniques needed to build a package and my only chance is to fiddle around with snippets.cson or init.coffee if either of those two locations can be used for this.
I’m desperately searching for an option to wrap words/lines and am not able to find any decent solution.
As an example, i have some php template files which sometime need html to be wrapped with php and vice versa at other times.
Deeply appreciate any help.
thanks


#6

Probably not what you want to hear, but I learned by going through the Flight Manual docs. Specifically, see the section on writing a package to modify text. However, go through both package examples, then try to add a new package that performs what you want. If you are having problems with anything after that, ask a question on the forums and ping me.


#7

Thanks @dsandstrom. Yeah, I did see both those before posting here. Unfortunately I lack skills needed to create a package. I have spent better part of the day trying various options but sadly I will have to give up for now.
In any case, cheers mate.


#8

You don’t need a package (unless this one does what you want). You can do this all via init.coffee. I’ve heavily annotated it so that every part of the function is obvious. (Note: this is almost literally what @dsandstrom posted, just in actual code form.)

# Wrap selected text with other text.
atom.commands.add 'atom-text-editor', 'user:wrap-selection', -> # Defines a command to work within the TextEditor.
  return unless editor = atom.workspace.getActiveTextEditor() # Get the active editor object and also return immediately if something goes wrong and there's no active text editor.

  selection = editor.getLastSelection() # Get the most recent selection.
  text = selection.getText() # A selection is an object with a bunch of information attached, so we need to get the text from it.
  prefix = "<?php"
  suffix = "?>"

  # This block makes sure that there are spaces between the prefix, suffix, and content. In the case of the example tag, this is necessary.
  if text[0] != " "
    prefix = prefix + " "
  if text[text.length - 1] != " "
    suffix = " " + suffix

  # insertText() replaces the whole selection. The options argument makes sure that the resulting text is selected.
  selection.insertText(prefix + selection.getText() + suffix, {select: true})

And then just add something to your keymap.cson:

'atom-text-editor':
  'ctrl-w': 'user:wrap-selection'

You can actually generate a blank package using Atom’s package generator and drop this code straight in under the toggle method and it would work just fine. That’s how easy package creation is in Atom. I don’t think that’s really a concern unless this snippet is expanded and made robust enough to allow for arbitrary wrap text without the user having to change the code. The auto-spacing behavior would also have to be smarter.


#9

Works great @DamnedScholar! Many thanks for this.

Going the package way is definitely the sensible (and elegant) way… but this will get me going for now. I will probably replicate this 2 or 3 times for the most critical stuff I want for now and come back when I have a bit of a breather from the current project.

Thanks for the link as well. I had seen it but unfortunately it didn’t do the job.

Again, appreciate your reply.


#10

It’s very much appreciated, thank you for taking the time to write up working code and sharing it.