How do I enable Sublime-like paste and indent?


#1

Ok I’ve been Googling for an hour now and trying everything I can find, but nothing I do enables me to have what I consider basic copy paste functionality - how do people cope with this?? It seems to be a problem only when copying from outside of Atom.

All I’m after is Sublime Text’s ‘Paste and indent’ (cmd-shift-v), really. See below for an example:

Whereas pasting in Atom gives me (sorry I can only post one image):

for (var i = 0; i < json.profiles.length; i++) {
var obj = json.profiles[i];
if (obj.category == 1) {
}
else if (obj.category == 2) {
}

}

(What you’d also get in Sublime if you did a normal paste, which you’d never do in this case because it’s useful to nobody)

I’ve toggled the auto-indent on paste options and tried the ‘indent-on-toggle-paste’ package - nothing I’ve done actually seems to have any impact, it always loses the indentation.

What do I do??


#2

This is what I get in Atom, no matter what I try:


#3

I was able to make an init.coffee hack in just a couple of minutes to make that behavior the default pasting behavior when Atom has an active TextEditor.

atom.commands.add 'atom-text-editor', 'custom:sublime-paste', ->
  editor = atom.workspace.getActiveTextEditor()
  # If there's no active text editor, then default to the normal paste command.
  if not editor then atom.commands.dispatch document.querySelector('atom-workspace'), 'core:paste'
  else
    editor.pasteText({select: true})
    editor.autoIndentSelectedRows()

    # Place the cursor at the end of the pasted text.
    range = editor.getSelectedBufferRange()
    editor.setCursorBufferPosition(range.end, {autoscroll: false})

And in my keymap.cson:

'*':
  'ctrl-v': 'custom:sublime-paste'

The API is quite robust and many complex operations already exist as methods, so all that a user has to do is string them together into a sequence. My init.coffee file is 258 lines long, and most of it consists of hacks like the one above that I’ve done for people on this forum, most of which are ten lines of code or fewer (and I could compress this one to three lines if I didn’t care about readability). So, to get to the question that you felt emphatic enough about to use double the question marks, Atom is designed by and for people who are interested in having an editor that brings some power to daily tasks, but is malleable enough that users can design their own workflows and functionality to whatever extent they desire.


#4

Thanks for the assistance, it’s much appreciated, especially in light of my empathic punctuation :slight_smile:

However your script isn’t giving me the same functionality as Sublime Text’s cmd-shift-v.

Copying and pasting your very own code into, say, column 11, in Atom gives me:

()http://i.imgur.com/oWngPtG.png

The same with your script:

()http://i.imgur.com/uZ44f33.png

And in Sublime Text (cmd-shift-v):

()http://i.imgur.com/P6KhYQe.png

Call me old-fashioned but I don’t think you should need to hack a text editor to attain useful paste functionality.

(Sorry for the strange image links, I’m a new member so have to communicate in riddles)


#5

The fact that the code in the images isn’t colored indicates that there’s no active grammar in the file you’re pasting into. Atom needs to know what language it’s working with in order for it to know how to autoindent the text. You should try pasting that code into a file set as CoffeeScript (it works fine for me).

Your definition of “useful paste functionality” includes an additional feature on top of simply pasting the content. Not everybody is going to expect or desire that behavior, and it seems that the devs (who are certainly aware of Sublime’s features) did not care to implement it or receive enough user feedback that they felt it was important to have. They did implement an accessible and powerful init script and an API that makes hacking the editor feel like playing with LEGOs, which makes sense considering their intended audience.


#6

This is what I get when I paste that block into column 11 in a CoffeeScript file, using your script:

Maybe that’s the case, but I’m not sure in what circumstance I’d want my clipboard to paste the above - do you consider that useful?


#7

Okay, I see. My one-liner if is messing with the auto indent logic. This pastes as expected:

atom.commands.add 'atom-text-editor', 'custom:sublime-paste', ->
  editor = atom.workspace.getActiveTextEditor()
  # If there's no active text editor, then default to the normal paste command.
  if not editor
    atom.commands.dispatch document.querySelector('atom-workspace'), 'core:paste'
  else
    editor.pasteText({select: true})
    editor.autoIndentSelectedRows()
    
    # Place the cursor at the end of the pasted text.
    range = editor.getSelectedBufferRange()
    editor.setCursorBufferPosition(range.end, {autoscroll: false})

Maybe that’s the case, but I’m not sure in what circumstance I’d want my clipboard to paste the above - do you consider that useful?

I consider it useful because it successfully accomplishes the purpose of inserting the current clipboard text into the file. The default behavior should be to simply paste the content without making any assumptions about what should be done following the paste operation. You see this in Sublime, too: you have to press shift in order to auto-indent the pasted content.


#8

Thank you for taking the time to refine the script, that works great!


#9

Edit: Actually this script seems to only work in certain situations, and is a bit unpredictable, but I consider it better than nothing and still appreciate the time and effort!


#10

It relies entirely on Atom’s auto-indent function, which is informed by the settings in the language package. Like we saw with my hack, there are some cases that can’t be predicted in a simple regex (like having a one-line if before the else). If the indentation seems incorrect in other circumstances, then it may be that the settings of the language package need to be refined.

(Incidentally, in navigating to that file to grab the link, I noticed that there’s an autoIndentOnPaste setting that I did not remember.)