Hi, is there a way to exclude some patterns from “trim_trailing_white_space_on_save”?
For example I don’t want to trim spaces in comments.
trim_trailing_white_space exclude comments
Not directly; the implementation for this option is in Packages\Default\trim_trailing_white_space.py
and it just finds all instances of trailing white space and erases it (it also contains an event listener that does it on save).
It would be possible to override the command with one that works the way that you want it to, though. As it was iterating the sets of white space it could check their scope and reject sections that are scoped as comments (or are adjacent to comments possibly, depending on what you’re editing).
There may already be a package in PackageControl that does this.
You will need to install Package Resource Viewer, if you haven’t already, and invoke it from the command palette.
Select Default, then the file you want is at the bottom of the list of files.
All of this can also be done via the RegReplace plugin. I’ll admit it is a bit involved to set up, but it allows you to setup patterns and use scopes to qualify your matches. You can chain multiple patterns together. And you can apply patterns to files on save.
Anyways, it is also another option. I don’t have time just this moment to do a step by step, but maybe a little later I can.
Here you go. Assuming you have installed RegReplace:
-
Press ctrl + shift + p (or cmd + shift + p on OSX) to bring up the command palette.
-
type
RegReplace
to see all the RegReplace commands and selectRegReplace: Create New Regular Expression
. You will be presented with an output panel. -
In this example we will create a rule that looks for trailing spaces, but only in regions that are not comments. We will replace those trailing spaces with with an empty string to remove them them. We will need to set a command name, a find pattern, a replace pattern, and a scope filter; everything else will be left to the defaults. The panel is using Python syntax.
""" If you don't need a setting, just leave it as None. When the rule is parsed, the default will be used. Each variable is evaluated separately, so you cannot substitute variables in other variables. """ # name (str): Rule name. Required. name = "trailing_spaces_no_comments" # find (str): Regular expression pattern or literal string. # Use (?i) for case insensitive. Use (?s) for dotall. # See https://docs.python.org/3.4/library/re.html for more info on regex flags. # Required unless "scope" is defined. find = r'[\t ]+$' # replace (str - default=r'\0'): Replace pattern. replace = r'' # literal (bool - default=False): Preform a non-regex, literal search and replace. literal = None # literal_ignorecase (bool - default=False): Ignore case when "literal" is true. literal_ignorecase = None # scope (str): Scope to search for and to apply optional regex to. # Required unless "find" is defined. scope = None # scope_filter ([str] - default=[]): An array of scope qualifiers for the match. # Only used when "scope" is not defined. # # - Any instance of scope qualifies match: scope.name # - Entire match of scope qualifies match: !scope.name # - Any instance of scope disqualifies match: -scope.name # - Entire match of scope disqualifies match: -!scope.name scope_filter = ['-comment'] # greedy (bool - default=True): Apply action to all instances (find all). # Used when "find" is defined. greedy = None # greedy_scope (bool - default=True): Find all the scopes specified by "scope." greedy_scope = None # multi_pass (bool - default=False): Perform multiple sweeps on the scope region to find # and replace all instances of the regex when regex cannot be formatted to find # all instances. Since a replace can change a scope, this can be useful. multi_pass = None # plugin (str): Define replace plugin for more advanced replace logic. plugin = None # args (dict): Arguments for 'plugin'. args = None # ---------------------------------------------------------------------------------------- # test: Here you can setup a test command. This is not saved and is just used for this session. # - replacements ([str]): A list of regex rules to sequence together. # - find_only (bool): Highlight current find results and prompt for action. # - action (str): Apply the given action (fold|unfold|mark|unmark|select). # This overrides the default replace action. # - options (dict): optional parameters for actions (see documentation for more info). # - key (str): Unique name for highlighted region. # - scope (str - default="invalid"): Scope name to use as teh color. # - style (str - default="outline"): Highlight style (solid|underline|outline). # - multi_pass (bool): Repeatedly sweep with sequence to find all instances. # - no_selection (bool): Overrides the "selection_only" setting and forces no selections. # - regex_full_file_with_selections (bool): Apply regex search to full file then apply # action to results under selections. test = { "replacements": [], "find_only": True, "action": None, "options": {}, "multi_pass": False, "no_selection": False, "regex_full_file_with_selections": False } '''
-
Press ctrl + s (or cmd + s in OSX) to save. The rule will be added to
Packages/User/reg_replace_rules.sublime-settings
. You can press esc to dismiss the panel. -
Navigate via the menu to
Preferences->Packages->RegReplace->Settings - User
to bring up your general RegReplace user settings file. -
In the settings file, place the following settings. Notice we are using our rule’s name. Multiple could be chained:
{ // If on_save is true, RegReplace will search through the file patterns listed below right before a file is saved, // if the file name matches a file pattern, the sequence will be applied before the file is saved. // RegReplace will apply all sequences that apply to a given file in the order they appear below. "on_save": true, // on_save replacements "on_save_sequences": [ // Remove trailing spaces { "file_pattern": ["*"], "sequence": ["trailing_spaces_no_comments"] } ] }
I will make a small note. If a syntax language somehow excludes the trailing space from the comment scope, you are out of luck.
Edit: I’ll rephrase, you aren’t out of luck, but you’ll have to be a little more creative.