(Solved) Auto indent on save


#1

Hi. Is there any way to “auto indent” when i save?
how?

thanks!.


#2

Could you please describe what you want to do in detail as in step by step. It’s really hard to grasp the idea of what you have just written.
My guess is that you want to overload something like Ctrl+s to indent the whole file. But indentation is more of preference than a strict format so that might be a tad difficult.

Hope that I can help a bit more.


#3

You can use something like this

atom.workspace.observeTextEditors (editor) ->
  editor.buffer.onWillSave ->
    selections = editor.getSelectedBufferRanges()
    editor.selectAll()
    editor.autoIndentSelectedRows()
    console.log 'Auto-indenting...'
    editor.setSelectedBufferRanges(selections)

This likely has some rough edges, but at least it gives you a starting point.


#4

Slight improvement (thanks for making me realize I still had the old way of subscribing in my init script @thomasjo !), paste the following in your Init Script:

atom.workspace.observeTextEditors (editor) ->
  editor.buffer.onWillSave ->
    return if editor?.getGrammar()?.scopeName is 'source.coffee'
    editor.autoIndentBufferRows 0, editor.getBuffer().getLineCount() - 1

Feel free to remove return if editor?.getGrammar()?.scopeName is 'source.coffee' if you also want to auto-indent CoffeeScript files, but I had some issues with auto-indenting coffee files. It’d try to nest all function blocks.


#5

Yes, sorry, i want to overload ctrl+s to indent the whole file. … and then save.
Thanks


#6

I’m trying to learn Atom. I do not know where to put these codes. What part of the atom docs you recommend me ?.


#7

In Atom: File -> Open Your Init Script. This will open your ~/.atom/init.coffee file, just append the code above and save it. After a restart or reload (alt+ctrl+r on Windows) your files will be auto-indented when you save them.


#8

Thank you all. @thomasjo your version is awesome!.
oooh, sublime text, die!.


#9

you’re right. thanks!


#10

Well it seems it’s all fixed. Glad to know. Keep at it.


#11

Awesome! Thank you very much for the tip.


#12

Hey, how would you go about also excluding the auto indent of .yml files? The auto indeed messes up my .yml file.


#13

Try the following:

# Indents files on save.
atom.workspace.observeTextEditors (editor) ->
  excludedGrammars = ['source.coffee', 'source.yaml']
  editor.buffer.onWillSave ->
    currentGrammar = editor.getGrammar()?.scopeName
    return if currentGrammar in excludedGrammars
    editor.autoIndentBufferRows 0, editor.getBuffer().getLineCount() - 1

To exclude more grammars, just add them to the excludedGrammars array.

To find the scope name of the grammar you want to exclude:

  • Create a new file.
  • Set it to the grammar you want to exclude. Click on ‘Plain Text’ in the Status Bar (or Ctrl+Shift+L on Windows) and pick it from the list.
  • Log the cursor scope by running the Editor: Log Cursor Scope command (Ctrl+Shift+Alt+P on Windows).
  • A notification appears with the scope at the cursor and since it is an empty file, it is the scope of the grammar.

#14

Thanks this works great.


#15

Thanks for that snippet Alchiadus. The one I came up with did the job but selected all the text and ran the auto-indent command leaving the text selected at the end: quite annoying after a while.

Is there any way it could be quickly turned off? There are a couple of cases where it would be preferable to save just one particular file without indentation occuring.


#16

Try the following snippet:

{CompositeDisposable} = require 'atom'

# Indents files on save.
autoIndentFilesOnSaveDisposables = new CompositeDisposable
do enableAutoIndentFilesOnSave = ->
  autoIndentFilesOnSaveDisposables.add atom.workspace.observeTextEditors (editor) ->
    excludedGrammars = ['source.coffee', 'source.yaml']
    autoIndentFilesOnSaveDisposables.add editor.buffer.onWillSave ->
      currentGrammar = editor.getGrammar()?.scopeName
      return if currentGrammar in excludedGrammars
      editor.autoIndentBufferRows 0, editor.getBuffer().getLineCount() - 1
atom.commands.add 'atom-workspace', 'custom:enable-auto-indent-files-on-save', ->
  enableAutoIndentFilesOnSave()
atom.commands.add 'atom-workspace', 'custom:disable-auto-indent-files-on-save', ->
  autoIndentFilesOnSaveDisposables.dispose()

As before, automatic indentation is enabled by default. If this is undesired simply remove the keyword do.
To temporarily disable automatic indentation on all files, enter custom:disable-auto-indent-files-on-save into the Command Palette. Enable it again later with custom:enable-auto-indent-files-on-save.

Note that it disables or enables indentation on all files, not just the current file. Unless I’m not seeing an obvious solution, to make it file specific you’d need to keep a mapping between editor/buffer and its specific disposable. Then, on removal, look up the disposable for the current editor/buffer and dispose of only that one.


#17

I get an error when using that last snippet.

Failed to load `init.coffee`. CompositeDisposable is not defined.

I found your previous snippet also has the issue of polluting the event history. To undo to something you did before a save you have to spam undo to undo the auto-indent on each line.


I was thinking it would be better if the auto indent command would auto select the whole file and indent it when nothing in the file was selected. So it acts as:

IF nothing selected in current file THEN
    select all
    auto-indent
    deselect all
ELSE
    auto-indent
END

Not sure how doable that is but it does have benefits. First of all it gives more control over when the file is indented and second it only adds 3 actions to the undo stack making it easy to revert.

I’m sure it’s stupidly simple to do and I just don’t understand how these scripts work yet. All I really need to do is to detect if a selection is present and do this set of actions else do these. So really I just need to be able to create a custom action and have that trigger other actions.