Sublime Text 3 - ensure _only_ one trailing newline at end of file
Asked Answered
A

1

23

I'm using Sublime Text 3 and want to ensure I get only a single new line at the end of a file on save. At the moment, 90% of the time my whitespace works perfectly, using:

"ensure_newline_at_eof_on_save": true

and

"trim_trailing_white_space_on_save": true

... however, every once in a while the file saves with two new lines at the end of the file.

This appears to occur when there is white space on the final newline prior to save, with the config settings adding a newline, then deleting the whitespace. Changing the order of these settings in config doesn't resolve this.

I haven't been able to find other reasons of this, so it may well be the only cause, though ideally I'd like to check if there's ever more than one newline on save.

The environment I'm working in fails its tests unless a file has exactly one new line at its end, so this is a bit of a pain. My question is whether there's a plugin / way to be stricter on save, ensuring one and only one trailing new line.

Albedo answered 13/6, 2016 at 16:22 Comment(2)
Under what conditions "every once in a while" is a file saved with two newlines? We can't help you unless we can reproduce the problem.Tindall
Thanks @Tindall - good point, I've updated the question. This is the only occasion I can see that causes the issue. Appreciate the advice.Albedo
S
21

EDIT:

I've expanded the plugin, that I posted below, a lot and it is now available to install using Package Control.

  • Single Trailing Newline is a Sublime Text package that makes sure that there is exactly one trailing newline at the end of a file. It works by deleting all the whitespace and newlines at the end of the file (if there are any) and then inserting a single newline.

  • The plugin can be set to run automatically every time a file is saved. This is disabled by default but by changing the settings it can be enabled either for all files or for only files of specific syntaxes.

  • Command palette entries are provided to change the package's settings; adding/removing the syntaxes that will trigger the plugin, and to allow or prevent the plugin from running with all syntaxes.

Original Answer:

Here's a plugin that will do it.

Save the following code in a file with a .py extension, e.g. EnsureExactlyOneTrailingNewLineAtEndOfFileOnSave.py and copy the file into your packages directory. When you save a file it will strip all trailing newlines and whitespace at the end of the file and then add a single trailing newline.

#
# A Sublime Text plugin to ensure that exactly one trailing
# newline is at the end of all files when files are saved.
#
# License: MIT License
#

import sublime, sublime_plugin

class OneTrailingNewLineAtEndOfFileOnSaveListener(sublime_plugin.EventListener):

    def on_pre_save(self, view):
        # A sublime_plugin.TextCommand class is needed for an edit object.
        view.run_command("one_trailing_new_line_at_end_of_file")
        return None

class OneTrailingNewLineAtEndOfFileCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        # Ignore empty files.
        if self.view.size() == 0:
            return

        # Work backwards from the end of the file looking for the last
        # significant char (one that is neither whitespace nor a newline).

        pos = self.view.size() - 1
        whitespace = ("\n", "\t", " ")

        while pos >= 0 and self.view.substr(pos) in whitespace:
            pos -= 1

        # Delete from the last significant char to the end of
        # the file and then add a single trailing newline.

        del_region = sublime.Region(pos + 1, self.view.size())
        self.view.erase(edit, del_region)
        self.view.insert(edit, self.view.size(), "\n")
Syllabogram answered 22/6, 2016 at 18:31 Comment(4)
That works just perfectly! Thanks so much for putting that together @mattst, + a million if I could :)Albedo
@Albedo No problem, its something I've wanted for myself for a while. See my edited answer, the expanded plugin can be set to work with only specific syntaxes and has other features as well.Syllabogram
@Albedo The plugin has been further expanded (see my post which has been edited again) and it is now available on Package Control. I suggest you un-install the manual installation and then install using Package Control so that you will automatically get updates.Syllabogram
Thank you for this! Was just odd finding the preferences in its own setting, my initial thought was that this was added to the general settings page, so having to add the snippet to the custom user settings threw me off! but works like a charm! just added {"enable_for_all_syntaxes": true}Auxochrome

© 2022 - 2024 — McMap. All rights reserved.