├── .gitignore
├── .python-version
├── Default.sublime-commands
├── MIT-LICENSE
├── Main.sublime-menu
├── README.md
├── messages.json
├── messages
├── install.txt
└── v1.0.0.txt
├── packages.json
├── settings.py
├── sublime-package.json
├── tox.ini
├── trailing_spaces.py
└── trailing_spaces.sublime-settings
/.gitignore:
--------------------------------------------------------------------------------
1 | .mypy_cache
2 | TODO.md
3 | *.pyc
4 |
--------------------------------------------------------------------------------
/.python-version:
--------------------------------------------------------------------------------
1 | 3.8
2 |
--------------------------------------------------------------------------------
/Default.sublime-commands:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "caption": "Trailing Spaces: Toggle Trailing Spaces Highlighting",
4 | "command": "toggle_trailing_spaces"
5 | },
6 | {
7 | "caption": "Trailing Spaces: Delete Trailing Spaces",
8 | "command": "delete_trailing_spaces"
9 | },
10 | {
11 | "caption": "Preferences: Trailing Spaces Settings",
12 | "command": "edit_settings",
13 | "args": {
14 | "base_file": "${packages}/TrailingSpaces/trailing_spaces.sublime-settings",
15 | "default": "// Settings in here override those in \"TrailingSpaces/trailing_spaces.sublime-settings\"\n\n{\n\t$0\n}\n",
16 | },
17 | },
18 |
19 | ]
20 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2010 Jean-Denis Vauguet
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Main.sublime-menu:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "edit",
4 | "children":
5 | [
6 | {
7 | "caption": "Trailing Spaces",
8 | "id": "trailing-spaces",
9 | "children":
10 | [
11 | {
12 | "command": "delete_trailing_spaces",
13 | "caption": "Delete"
14 | },
15 | { "caption": "-" },
16 | {
17 | "command": "toggle_trailing_spaces_modified_lines_only",
18 | "caption": "Modified Lines Only",
19 | "checkbox": true
20 | },
21 | {
22 | "command": "toggle_trailing_spaces",
23 | "caption": "Highlight Regions",
24 | "checkbox": true
25 | }
26 | ]
27 | }
28 | ]
29 | },
30 | {
31 | "id": "preferences",
32 | "children":
33 | [
34 | {
35 | "caption": "Package Settings",
36 | "mnemonic": "P",
37 | "id": "package-settings",
38 | "children":
39 | [
40 | {
41 | "caption": "Trailing Spaces",
42 | "children":
43 | [
44 | {
45 | "command": "edit_settings",
46 | "args": {
47 | "base_file": "${packages}/TrailingSpaces/trailing_spaces.sublime-settings",
48 | "default": "// Settings in here override those in \"TrailingSpaces/trailing_spaces.sublime-settings\"\n\n{\n\t$0\n}\n",
49 | },
50 | "caption": "Settings"
51 | },
52 | { "caption": "-" },
53 | {
54 | "command": "open_file",
55 | "args": {
56 | "file": "${packages}/TrailingSpaces/README.md",
57 | },
58 | "caption": "Help"
59 | },
60 | ]
61 | }
62 | ]
63 | }
64 | ]
65 | }
66 | ]
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Trailing Spaces
2 | ===============
3 |
4 | A [Sublime Text](http://www.sublimetext.com) plugin that allows you to…
5 |
6 | **highlight trailing spaces and delete them in a flash!**
7 |
8 | ---
9 |
10 | - [Synopsis](#synopsis)
11 | - [Installation](#installation)
12 | - [Alternative installation methods](#alternative-installation-methods)
13 | - [From github](#from-github)
14 | - [Manually](#manually)
15 | - [Usage](#usage)
16 | - [Deletion](#deletion)
17 | - [Toggling highlighting](#toggling-highlighting)
18 | - [Options](#options)
19 | - [Changing the highlighting color](#changing-the-highlighting-color)
20 | - [Keeping trailing spaces invisible](#keeping-trailing-spaces-invisible)
21 | - [Include Current Line](#include-current-line)
22 | - [Include Empty Lines](#include-empty-lines)
23 | - [Modified Lines Only](#modified-lines-only)
24 | - [Trim On Save](#trim-on-save)
25 | - [Save After Trim](#save-after-trim)
26 | - [Live Matching vs On-demand Matching](#live-matching-vs-on-demand-matching)
27 | - [Ignore Scope](#ignore-scope)
28 | - [For power-users only!](#for-power-users-only)
29 | - [Disabled for large files](#disabled-for-large-files)
30 | - [The matching pattern](#the-matching-pattern)
31 | - [About Sublime Text's built-in features](#about-sublime-texts-built-in-features)
32 |
33 | Synopsis
34 | --------
35 |
36 | Sublime Text provides a way to automate deletion of trailing spaces *upon file
37 | saving* (more on this at the end of this file). Depending on your settings, it
38 | may be more handy to just highlight them and/or delete them by hand, at any
39 | time. This plugin provides just that, and a *lot* of options to fine-tune the
40 | way you want to decimate trailing spaces.
41 |
42 | Installation
43 | ------------
44 |
45 | It is available through
46 | [Sublime Package Control](http://wbond.net/sublime_packages/package_control) and
47 | this is the recommended way of installation (brings configuration instructions,
48 | automatic updates with changelogs…).
49 |
50 | ### Alternative installation methods
51 |
52 | #### From github
53 |
54 | You can install from github if you want, although Package Control automates
55 | just that. Go to your `Packages` directory (find out where it is by running
56 | `Preferences: Browse Packages` from The _Command Palette_) and clone this repository:
57 |
58 | git clone https://github.com/SublimeText/TrailingSpaces.git
59 |
60 | #### Manually
61 |
62 | [Download](https://github.com/SublimeText/TrailingSpaces/archive/master.zip)
63 | the plugin as a zip. Copy the *Trailing Spaces* directory to its location
64 | (see prior section).
65 |
66 | Usage
67 | -----
68 |
69 | ### Deletion
70 |
71 | The main feature you gain from using this plugin is that of deleting all
72 | trailing spaces in the currently edited document. In order to use this
73 | deletion feature, you may either:
74 |
75 | * click on "Edit / Trailing Spaces / Delete";
76 | * bind the deletion command to a keyboard shortcut:
77 |
78 | To add a key binding, open "Preferences / Key Bindings - User" and add:
79 |
80 | ``` js
81 | { "keys": ["ctrl+shift+t"], "command": "delete_trailing_spaces" }
82 | ```
83 |
84 | With this setting, pressing Ctrl + Shift + t will delete all
85 | trailing spaces at once in the current file! For OSX users, quoting wbond:
86 | "When porting a key binding across OSes, it is common for the ctrl key on
87 | Windows and Linux to be swapped out for super on OS X"
88 | (eg. use "super+shift+t" instead).
89 |
90 | *Beware*: the binding from this example overrides the default ST's mapping
91 | for reopening last closed file. You can look at the default bindings in
92 | "Preferences / Key Bindings - Default".
93 |
94 | ### Toggling highlighting
95 |
96 | At any time, you can toggle highlighting on and off. You may either:
97 |
98 | - click on "Edit / Trailing Spaces / Highlight Regions"
99 | - bind the toggling command to a keyboard shortcut:
100 |
101 | ``` js
102 | // I like "d", as in "detect" (overrides a default binding, though).
103 | { "keys": ["ctrl+shift+d"], "command": "toggle_trailing_spaces" }
104 | ```
105 |
106 | Options
107 | -------
108 |
109 | Several options are available to customize the plugin's behavior. Those
110 | settings are stored in a configuration file, as JSON. You must use a specific
111 | file: Go to "Preferences / Package Settings / Trailing Spaces / Settings" to
112 | add you custom settings.
113 |
114 | A few of them are also accessible through the "Edit / Trailing Spaces" menu.
115 | Sometimes, editing a setting will require a fresh Sublime Text to be applied
116 | properly, so try relaunching ST before reporting an issue ;)
117 |
118 | All settings are global (ie. applied to all opened documents).
119 |
120 | ### Changing the highlighting color
121 |
122 | *Default: "invalid"*
123 |
124 | You may change the highlighting color, providing a color scope name such as
125 | "error", "comment"… just like that:
126 |
127 | ``` js
128 | { "highlight_color": "comment" }
129 | ```
130 |
131 | The scope should be defined in your current theme file. Here is a dummy,
132 | fully-fledged example (feel free to cut irrelevant pieces for your settings)
133 | of such a custom color scope:
134 |
135 | ``` xml
136 |
137 | name
138 | Invalid - Illegal
139 | scope
140 | invalid.illegal
141 | settings
142 |
143 | background
144 | #F93232
145 | fontStyle
146 |
147 | foreground
148 | #F9F2CE
149 |
150 |
151 | ```
152 |
153 | You would then use the value of "invalid.illegal".
154 |
155 | ### Keeping trailing spaces invisible
156 |
157 | You can make trailing spaces "invisible" yet still rely on the deletion
158 | command. To do that, set the highlight scope to an empty string:
159 |
160 | ``` js
161 | { "highlight_color": "" }
162 | ```
163 |
164 | Beware: this is **not** the same as *disabling* the highlighting (see "On-
165 | Demand Matching" below). With this setting, the plugin still runs when opening
166 | a file, and in the background afterwards; you just won't see the trailing
167 | spaces (they are being highlighted with a "transparent" color).
168 |
169 | ### Include Current Line
170 |
171 | *Default: true*
172 |
173 | Highlighting of trailing spaces in the currently edited line can be annoying:
174 | each time you are about to start a new word, the space you type is matched as
175 | a trailing spaces. Currently edited line can thus be ignored:
176 |
177 | ``` js
178 | { "include_current_line": false }
179 | ```
180 |
181 | Even though the trailing spaces are not highlighted on this line, they are
182 | still internally matched and will be delete when firing the deletion command.
183 |
184 | ### Include Empty Lines
185 |
186 | *Default: true*
187 |
188 | When firing the deletion command, empty lines are matched as trailing regions,
189 | and end up being deleted. You can specifically ignore them:
190 |
191 | ``` js
192 | { "include_empty_lines": false }
193 | ```
194 |
195 | They will not be highlighted either.
196 |
197 | ### Modified Lines Only
198 |
199 | *Default: false (reopen ST to update)*
200 |
201 | When firing the deletion command, trailing regions *in the entire document* are
202 | deleted. There are some use-cases when deleting trailing spaces *only on lines
203 | you edited* is smarter; for instance when commiting changes to some third-party
204 | source code.
205 |
206 | At any time, you can change which area is covered when deleting trailing
207 | regions. You may either:
208 |
209 | - click on "Edit / Trailing Spaces / Modified Lines Only"
210 | - specify as a setting:
211 |
212 | ``` js
213 | { "modified_lines_only": true }
214 | ```
215 |
216 | There is also a command to toggle this feature on and off. You may thus define
217 | a key binding:
218 |
219 | ``` js
220 | { "keys": ["pick+a+shortcut"], "command": "toggle_trailing_spaces_modified_lines_only" }
221 | ```
222 |
223 | ### Trim On Save
224 |
225 | *Default: false*
226 |
227 | Setting this to `true` will ensure trailing spaces are deleted when you save
228 | your document. It abides by the other settings, such as *Modified Lines Only*.
229 |
230 | ``` js
231 | { "trim_on_save": true }
232 | ```
233 |
234 | ### Save After Trim
235 |
236 | *Default: false*
237 |
238 | You may not want to always trim trailing spaces on save, but the other way
239 | around could prove useful. Setting this to `true` will automatically save your
240 | document after you fire the deletion command:
241 |
242 | ``` js
243 | { "save_after_trim": true }
244 | ```
245 |
246 | It is obviously ignored if *Trim On Save* is on.
247 |
248 | ### Live Matching vs On-demand Matching
249 |
250 | *Default: true (reopen ST to update)*
251 |
252 | By default, trailing regions are matched every time you edit the document, and
253 | when you open it.
254 |
255 | This feature is entirely optional and you may set it off: firing the deletion
256 | command will cause the trailing spaces to be deleted as expected even though
257 | they were not matched prior to your request. If you are afraid of the plugin
258 | to cause slowness (for instance, you already installed several *heavy*
259 | plugins), you can disable live matching:
260 |
261 | ``` js
262 | { "enabled": false }
263 | ```
264 |
265 | In this case, for no trailing regions are matched until you request them to be
266 | deleted, no highlighting occurs—it is in fact disabled, regardless of your
267 | "scope" setting. If you want to check the trailing spaces regions, you can
268 | toggle highlighting on and off. In this case, it may come in handy to define
269 | a binding for the toggling command. When "On-demand Matching" is on and some
270 | trailing spaces are highlighted, added ones will obviously not be. Toggling
271 | highlight off and on will refresh them.
272 |
273 | ### Ignore Scope
274 |
275 | *Default: ["text.find-in-files", "source.build_output", "source.diff", "text.html.markdown"]*
276 |
277 | With this option you can ignore lines being highlighted based on the scope of
278 | their trailing region.
279 |
280 | If at least one scope in the configured list matches a scope in the trailing
281 | region of the line, it won't be highlighted.
282 |
283 | By default, the scope under the mouse cursor is shown by pressing
284 | `Option+Command+P` (OS X) or `Ctrl+Alt+Shift+P` (Windows, Linux)
285 |
286 | ``` js
287 | // Trailing spaces for Find Results, Build output, Diff and Markdown are ignored
288 | { "scope_ignore": ["text.find-in-files", "source.build_output", "source.diff", "text.html.markdown"] }
289 | ```
290 |
291 | ### For power-users only!
292 |
293 | #### Disabled for large files
294 |
295 | The plugin is disabled altogether for large files, for it may cause slowness.
296 | The default threshold is around 1 million of characters. This is
297 | configurable (in "File Settings - User") and the unit is number of chars:
298 |
299 | ``` js
300 | { "file_max_size": 1000}
301 | ```
302 |
303 | #### The matching pattern
304 |
305 | *Default: [ \t]+*
306 |
307 | Trailing spaces are line-ending regions containing at least one simple space,
308 | tabs, or both. This pattern should be all you ever need, but if you *do* want
309 | to abide by another definition to cover edge-cases, go ahead:
310 |
311 | ``` js
312 | // *danger* will match newline chars and many other folks
313 | "regexp": "[\\s]+"
314 | ```
315 |
316 | About Sublime Text's built-in features
317 | --------------------------------------
318 |
319 | Trailing Spaces is designed to be a drop-in replacement of the limited
320 | *Trim Whitespace On Save* built-in feature. ST is indeed able to delete
321 | trailing spaces upon saving files, and maybe that's all you need!
322 |
323 | In order to enable this behavior, edit "Preferences / Settings"
324 | to add the following:
325 |
326 | ``` js
327 | { "trim_trailing_white_space_on_save": true }
328 | ```
329 |
330 | As Trailing Spaces bypasses this setting, you will have to uninstall it to
331 | benefit from this setting.
332 |
333 | Made a little less obvious in the documentation are settings to showcase
334 | whitespaces (*not only trailing ones!*):
335 |
336 | ``` js
337 | { "draw_white_space": "all" }
338 | ```
339 |
340 | and to ensure a newline is kept at end of file upon saving:
341 |
342 | ``` js
343 | { "ensure_newline_at_eof_on_save": true }
344 | ```
345 |
346 | The former will display *all* whitespaces in your files. There is another value
347 | of "selection" which display whitespaces under (you got it) your current text
348 | selection.
349 |
--------------------------------------------------------------------------------
/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "install": "messages/install.txt",
3 | "v1.0.0": "messages/v1.0.0.txt"
4 | }
5 |
--------------------------------------------------------------------------------
/messages/install.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | Thank you for installing Trailing Spaces
4 | ----------------------------------------
5 |
6 | You're now ready to give trailing spaces *a hard time*!
7 |
8 |
9 | Documentation
10 | =============
11 |
12 | Although the usage of this plugin is dead simple, it comes with several options. All
13 | details are available in the documentation, and you can read it by clicking on
14 | "Preferences / Package Settings / Trailing Spaces / Help", or in a prettier form, by
15 | browsing https://github.com/SublimeText/TrailingSpaces.
16 |
17 | Key Binding
18 | ===========
19 |
20 | This plugin does not come with a default key binding for the deletion command. You can
21 | pick your own key binding and define it in "Preferences / Key Bindings - User", or just
22 | stick to using the menu entry under "Edit". Check the help for advice on this.
23 |
24 | Upgrades & Issues
25 | =================
26 |
27 | Package Control will automatically update all packages every time the editor is started,
28 | so there is nothing for you to worry about. If you however do find the plugin not to work
29 | as it used to, head to the issues tracker (see links below) to report the problem.
30 |
31 | Useful Links
32 | ============
33 |
34 | * Documentation & Code: https://github.com/SublimeText/TrailingSpaces
35 | * Report issues / Request New Features / Roadmap: https://github.com/SublimeText/TrailingSpaces/issues
36 | * Follow me on twitter: @jdvauguet
37 |
--------------------------------------------------------------------------------
/messages/v1.0.0.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | Trailing Spaces update [v1.0.0]
4 | -------------------------------
5 |
6 | Hope you've been happy gaving trailin' a hard time so far.
7 |
8 | I added several features to help you in this honorable quest…
9 |
10 | All details accessible through:
11 |
12 | "Preferences / Package Settings / Trailing Spaces / Help"
13 |
14 |
15 |
16 | New feature: Modified Lines Only
17 | ================================
18 |
19 | As proposed by a fellow user, it is now possible to target only the lines
20 | modified by You and You Only when deleting trailing spaces.
21 |
22 | This feature will certainly please coders who edit third-party code filled
23 | with trailing spaces but do not want to commit giant diffs, just their little
24 | fix, while keeping it clean.
25 |
26 | New feature: Trim On Save
27 | =========================
28 |
29 | This option allows for automatic deletion upon saving. No more lost trailing
30 | spaces! A perfect combo to the "Modified Lines Only" setting I guess.
31 |
32 | New feature: Save After Trim
33 | ============================
34 |
35 | A different kind of automation: many users just want those trailings out and
36 | forget 'bout them. It is now made even easier with this auto-saving hook. Fire
37 | the deletion command, and your document is clean on the hard drive!
38 |
39 | At the current time, "Trim On Save" and "Save After Trim" cannot be both
40 | enabled (the former wins), but this is on the roadmap.
41 |
42 | New Menu
43 | ========
44 |
45 | Some of the settings seemed a bit more important than the others. Along the
46 | deletion command, the toggling command/state and the "Modified Lines Only"
47 | setting have been elected first-class citizens of the new "Edit / Trailing
48 | Spaces" menu. Any change made by click here is live, persistent and reflected
49 | in the JSON settings file. Settings are global to all open documents.
50 |
51 | Improvements & Misc.
52 | ====================
53 |
54 | - Support for custom matching patterns (danger!).
55 | - Performance improvements (reduced overhead, with some room for further
56 | improvements).
57 | - Better documentation (both code & user doc).
58 | - Lazy "On-demand" matching improved.
59 |
60 | Useful Links
61 | ============
62 |
63 | * Documentation & Code: https://github.com/SublimeText/TrailingSpaces
64 | * Report issues / Request New Features / Roadmap: https://github.com/SublimeText/TrailingSpaces/issues
65 | * Follow me on twitter: @jdvauguet
66 |
--------------------------------------------------------------------------------
/packages.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema_version": "1.2",
3 | "packages": [
4 | {
5 | "name": "TrailingSpaces",
6 | "description": "Highlight trailing spaces and delete them in a flash.",
7 | "author": "Jean-Denis Vauguet",
8 | "homepage": "https://github.com/SublimeText/TrailingSpaces/",
9 | "last_modified": "2013-03-08 01:00:00",
10 | "platforms": {
11 | "*": [
12 | {
13 | "version": "1.0.0",
14 | "url": "https://nodeload.github.com/SublimeText/TrailingSpaces/zip/v1.0.0"
15 | }
16 | ]
17 | }
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | from typing import Any, List
2 | import sublime
3 |
4 |
5 | class TrailingSpacesSettings:
6 | SETTINGS_FILENAME = 'trailing_spaces.sublime-settings'
7 |
8 | def __init__(self):
9 | self._settings = sublime.Settings(0)
10 |
11 | def load(self) -> None:
12 | self._settings = sublime.load_settings(self.SETTINGS_FILENAME)
13 |
14 | def save(self) -> None:
15 | sublime.save_settings(self.SETTINGS_FILENAME)
16 |
17 | def _get(self, key: str, value_type: Any) -> Any:
18 | value = self._settings.get(key)
19 | if not isinstance(value, value_type):
20 | raise Exception(f'Invalid value for setting "{key}". Expected "{value_type}", got "{type(value)}')
21 | return value
22 |
23 | def _set(self, key: str, value: Any, value_type: Any) -> None:
24 | if not isinstance(value, value_type):
25 | raise Exception(f'Invalid value when setting "{key}". Expected "{value_type}", got "{type(value)}')
26 | self._settings.set(key, value)
27 |
28 | # -- Getters and setters for supported options ---------------------------------------------------------------------
29 |
30 | @property
31 | def enabled(self) -> bool:
32 | return self._get('enabled', bool)
33 |
34 | @property
35 | def file_max_size(self) -> int:
36 | return self._get('file_max_size', int)
37 |
38 | @property
39 | def highlight_color(self) -> str:
40 | return self._get('highlight_color', str)
41 |
42 | @highlight_color.setter
43 | def highlight_color(self, value: str) -> None:
44 | self._set('highlight_color', value, str)
45 |
46 | @property
47 | def include_current_line(self) -> bool:
48 | return self._get('include_current_line', bool)
49 |
50 | @property
51 | def include_empty_lines(self) -> bool:
52 | return self._get('include_empty_lines', bool)
53 |
54 | @property
55 | def modified_lines_only(self) -> bool:
56 | return self._get('modified_lines_only', bool)
57 |
58 | @modified_lines_only.setter
59 | def modified_lines_only(self, value: bool) -> None:
60 | self._set('modified_lines_only', value, bool)
61 |
62 | @property
63 | def non_visible_highlighting(self) -> int:
64 | return self._get('non_visible_highlighting', int)
65 |
66 | @property
67 | def regexp(self) -> str:
68 | return self._get('regexp', str)
69 |
70 | @property
71 | def save_after_trim(self) -> bool:
72 | return self._get('save_after_trim', bool)
73 |
74 | @property
75 | def scope_ignore(self) -> List[str]:
76 | return self._get('scope_ignore', list)
77 |
78 | @property
79 | def syntax_ignore(self) -> List[str]:
80 | value = self._settings.get('syntax_ignore')
81 | return value if isinstance(value, list) else []
82 |
83 | @property
84 | def trim_on_save(self) -> bool:
85 | return self._get('trim_on_save', bool)
86 |
87 | @property
88 | def update_interval(self) -> int:
89 | return self._get('update_interval', int)
90 |
--------------------------------------------------------------------------------
/sublime-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "contributions": {
3 | "settings": [
4 | {
5 | "file_patterns": [
6 | "/trailing_spaces.sublime-settings"
7 | ],
8 | "schema": {
9 | "$id": "sublime://settings/TrailingSpaces",
10 | "properties": {
11 | "enabled": {
12 | "type": "boolean",
13 | "default": true,
14 | "markdownDescription": "By default, Trailing Spaces is \"live\". It means the trailing spaces regions will be matched in the background, and highlighted if a color scope is defined, when the document is opened and edited. Set to false to disable live matching and highlighting (the deletion command remains available, so-called \"lazy matching\")."
15 | },
16 | "highlight_color": {
17 | "type": "string",
18 | "default": "region.redish",
19 | "markdownDescription": "Highlight color is specified as a scope. You may define and use a custom scope to better fit your colorscheme. A value of empty string `\"\"` will make highlights invisible."
20 | },
21 | "include_empty_lines": {
22 | "type": "boolean",
23 | "default": true,
24 | "markdownDescription": "By default, empty lines are cleared as well when calling the deletion command. Set to ` to ignore empty lines upon deletion."
25 | },
26 | "include_current_line": {
27 | "type": "boolean",
28 | "default": true,
29 | "markdownDescription": "By default, the line being currently edited will have its trailing spaces highlighted. Set to `false` to ignore trailing spaces on the edited line."
30 | },
31 | "scope_ignore": {
32 | "type": "array",
33 | "default": ["text.find-in-files", "source.build_output", "source.diff", "text.html.markdown"],
34 | "items": {
35 | "type": "string"
36 | },
37 | "uniqueItems": true,
38 | "markdownDescription": "By default, any lines in the Find Results, Build output, Diff and Markdown views are ignored. Add scopes to this list if you need to ignore them."
39 | },
40 | "modified_lines_only": {
41 | "type": "boolean",
42 | "default": false,
43 | "markdownDescription": "By default, trailing spaces are deleted within the whole document. Set to `true` to affect only the lines you edited since last save. Trailing spaces will still be searched for and highlighted in the whole document."
44 | },
45 | "trim_on_save": {
46 | "type": "boolean",
47 | "default": false,
48 | "markdownDescription": "By default, nothing happens on save. Set to `true` to trim trailing spaces before saving, with respect to the other settings."
49 | },
50 | "save_after_trim": {
51 | "type": "boolean",
52 | "default": false,
53 | "markdownDescription": "By default, deleting trailing spaces does not cause the document to be saved. Set to `true` to force saving after trailing spaces have been deleted. This setting is irrelevant and will be ignored if `trim_on_save` is `true`."
54 | },
55 | "non_visible_highlighting": {
56 | "type": "number",
57 | "default": 500,
58 | "markdownDescription": "The number of characters before and after the visible region of text to include in the highlighting. This is useful to also show the highlighting immediately for text that just became visible through scrolling. Adjust the value (in the number of characters) to whatever fits your needs and performance."
59 | },
60 | "update_interval": {
61 | "type": "number",
62 | "default": 250,
63 | "markdownDescription": "This is the interval at which the active view is tested for changes (due to scrolling) to update the highlighting of the currently visible region of text. Adjust the value (in milliseconds) to whatever fits your needs and performance."
64 | },
65 | "file_max_size": {
66 | "type": "number",
67 | "default": 1048576,
68 | "markdownDescription": "Highlighting will be disabled if the edited file's size is larger than this. Adjust the value (in number of chars) to whatever fits your performance."
69 | },
70 | "regexp": {
71 | "type": "string",
72 | "default": "[ \\t]+",
73 | "markdownDescription": "By default, only simple spaces and tabs are matched as \"trailing spaces\"."
74 | },
75 | },
76 | "additionalProperties": false
77 | }
78 | }
79 | ]
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py3
3 | skipsdist = True
4 |
5 | [pycodestyle]
6 | max-line-length = 120
7 |
8 | [flake8]
9 | max-line-length = 120
10 |
--------------------------------------------------------------------------------
/trailing_spaces.py:
--------------------------------------------------------------------------------
1 | '''
2 | Provides both a trailing spaces highlighter and a deletion command.
3 |
4 | See README.md for details.
5 |
6 | @author: Jean-Denis Vauguet , Oktay Acikalin
7 | @license: MIT (http://www.opensource.org/licenses/mit-license.php)
8 | @since: 2011-02-25
9 | '''
10 |
11 | from .settings import TrailingSpacesSettings
12 | from os.path import isfile
13 | from typing import Dict, List, Literal, Tuple, Union, cast
14 | import codecs
15 | import difflib
16 | import re
17 | import sublime
18 | import sublime_plugin
19 |
20 | # dictionary of currently active view ids and last visible regions
21 | active_views: Dict[int, sublime.Region] = {}
22 | current_highlight_color = ''
23 | on_disk = None
24 | # Highlight color as defined in settings. Plugin mutates that setting when disabled so
25 | # that has to be stored.
26 | INITIAL_HIGHLIGHT_COLOR = ''
27 | HIGHLIGHT_REGION_KEY = 'TrailingSpacesHighlightedRegions'
28 | settings = TrailingSpacesSettings()
29 |
30 |
31 | def plugin_loaded() -> None:
32 | global current_highlight_color, INITIAL_HIGHLIGHT_COLOR
33 |
34 | settings.load()
35 |
36 | current_highlight_color = settings.highlight_color
37 | INITIAL_HIGHLIGHT_COLOR = current_highlight_color
38 |
39 | if not settings.enabled:
40 | current_highlight_color = ""
41 | if settings.highlight_color != current_highlight_color:
42 | settings.save()
43 |
44 |
45 | # Private: Makes sure all timers are stopped.
46 | #
47 | # Returns nothing.
48 | def plugin_unloaded() -> None:
49 | global on_disk
50 |
51 | # clear all active views to kill all timeouts
52 | active_views.clear()
53 | on_disk = None
54 |
55 |
56 | # Private: Returns all regions within region that match regex.
57 | #
58 | # view - the view, you know
59 | # regions - a list of regions to search
60 | # regex - the regex pattern to search for
61 | #
62 | # Returns all matching trailing regions within regions.
63 | def view_find_all_in_regions(view: sublime.View, regions: List[sublime.Region], regex: str) -> List[sublime.Region]:
64 | found: List[sublime.Region] = []
65 |
66 | # find all matches in the region's text
67 | for region in regions:
68 | text = view.substr(region)
69 | # translate positions to the region's starting position
70 | matches = re.finditer(regex, text, re.MULTILINE)
71 | found.extend(sublime.Region(m.start() + region.begin(), m.end() + region.begin()) for m in matches)
72 |
73 | return found
74 |
75 |
76 | # Private: Get the regions matching trailing spaces.
77 | #
78 | # As the core regexp matches lines, the regions are, well, "per lines".
79 | #
80 | # view - the view, you know
81 | # scan_only_visible - whether to limit scanning to only visible region
82 | #
83 | # Returns both the list of regions which map to trailing spaces and the list of
84 | # regions which are to be highlighted, as a list [matched, highlightable].
85 | def find_trailing_spaces(
86 | view: sublime.View, scan_only_visible: bool = True
87 | ) -> Tuple[List[sublime.Region], List[sublime.Region]]:
88 | include_empty_lines = settings.include_empty_lines
89 | include_current_line = settings.include_current_line
90 | regexp = settings.regexp + "$"
91 |
92 | if not include_empty_lines:
93 | regexp = "(?<=\\S)%s$" % regexp
94 |
95 | trailing_regions: List[sublime.Region] = []
96 |
97 | non_visible_highlighting = settings.non_visible_highlighting
98 |
99 | if scan_only_visible:
100 | # find all matches in the currently visible region plus a little before and after
101 | searched_region = view.visible_region()
102 | searched_region.a = max(searched_region.a - non_visible_highlighting, 0)
103 | searched_region.b = min(searched_region.b + non_visible_highlighting, view.size())
104 |
105 | searched_region = view.line(searched_region) # align to line start and end
106 | trailing_regions = view_find_all_in_regions(view, [searched_region], regexp)
107 | else:
108 | trailing_regions = view.find_all(regexp)
109 |
110 | ignored_scopes = ",".join(settings.scope_ignore)
111 | # filter out ignored scopes
112 | trailing_regions = [
113 | region for region in trailing_regions
114 | if not ignored_scopes or not view.match_selector(region.begin(), ignored_scopes)
115 | ]
116 |
117 | sel = view.sel()
118 |
119 | if include_current_line or len(sel) == 0:
120 | return (trailing_regions, trailing_regions)
121 | else:
122 | selection_lines = [view.line(region.b) for region in sel]
123 | # find all matches in the current line and exclude them from highlighting
124 | selection_offenders = view_find_all_in_regions(view, selection_lines, regexp)
125 | highlightable = [r for r in trailing_regions if r not in selection_offenders]
126 | return (trailing_regions, highlightable)
127 |
128 |
129 | # Private: Find the freaking trailing spaces in the view and flags them as such!
130 | #
131 | # It will refresh highlighted regions as well. Does not execute if the
132 | # document's size exceeds the file_max_size setting, or if the fired in a view
133 | # which is not a legacy document (helper/build views and so on).
134 | #
135 | # view - the view, you know
136 | #
137 | # Returns nothing.
138 | def match_trailing_spaces(view: sublime.View) -> None:
139 | # Silently pass ignored views.
140 | if ignore_view(view):
141 | return
142 |
143 | # Silently pass if file is too big.
144 | if max_size_exceeded(view):
145 | return
146 |
147 | (matched, highlightable) = find_trailing_spaces(view)
148 | highlight_trailing_spaces_regions(view, highlightable)
149 |
150 |
151 | # Private: Checks if the view should be ignored.
152 | #
153 | # view - the view to check.
154 | #
155 | # Returns True if the view should be ignored, False otherwise.
156 | def ignore_view(view: sublime.View) -> bool:
157 | if view.is_scratch():
158 | return True
159 |
160 | view_settings = view.settings()
161 | view_syntax = view_settings.get('syntax')
162 |
163 | if not isinstance(view_syntax, str) or view_settings.get('is_widget'):
164 | return False
165 |
166 | for syntax_ignore in settings.syntax_ignore:
167 | if syntax_ignore in view_syntax:
168 | return True
169 |
170 | return False
171 |
172 |
173 | # Private: Checks whether the document is bigger than the max_size setting.
174 | #
175 | # view - the view, you know
176 | #
177 | # Returns True or False.
178 | def max_size_exceeded(view: sublime.View) -> bool:
179 | return view.size() > settings.file_max_size
180 |
181 |
182 | # Private: Highlights specified regions as trailing spaces.
183 | #
184 | # It will use the scope enforced by the state of the toggable highlighting.
185 | #
186 | # view - the view, you know
187 | # regions - regions qualified as trailing spaces
188 | #
189 | # Returns nothing.
190 | def highlight_trailing_spaces_regions(view: sublime.View, regions: List[sublime.Region]) -> None:
191 | view.erase_regions(HIGHLIGHT_REGION_KEY)
192 | if regions:
193 | view.add_regions(HIGHLIGHT_REGION_KEY, regions, current_highlight_color or "", "", sublime.HIDE_ON_MINIMAP)
194 |
195 |
196 | # Private: Toggles highlighting of all trailing spaces in the view.
197 | #
198 | # It has no effect is the plugin is disabled.
199 | #
200 | # view - the view, you know
201 | #
202 | # Returns True (highlighting was turned on) or False (turned off).
203 | def toggle_highlighting(view: sublime.View) -> Literal['disabled!', 'off', 'on']:
204 | global current_highlight_color
205 |
206 | # If the scope is that of an invisible, there is nothing to toggle.
207 | if INITIAL_HIGHLIGHT_COLOR == "":
208 | return "disabled!"
209 |
210 | # If performing live, highlighted trailing regions must be updated
211 | # internally.
212 | if not settings.enabled:
213 | (matched, highlightable) = find_trailing_spaces(view)
214 | highlight_trailing_spaces_regions(view, highlightable)
215 |
216 | scope = INITIAL_HIGHLIGHT_COLOR if current_highlight_color == "" else ""
217 | current_highlight_color = scope
218 | highlight_trailing_spaces_regions(view, view.get_regions(HIGHLIGHT_REGION_KEY))
219 | return "off" if current_highlight_color == "" else "on"
220 |
221 |
222 | # Clear all the highlighted regions in all views.
223 | #
224 | # FIXME: this is not used! Delete?
225 | #
226 | # window - the window, you know
227 | #
228 | # Returns nothing.
229 | def clear_trailing_spaces_highlight(window: sublime.Window) -> None:
230 | for view in window.views():
231 | view.erase_regions('TrailingSpacesMatchedRegions')
232 |
233 |
234 | # Find edited lines since last save, as line numbers, based on diff.
235 | #
236 | # It uses a Differ object to compute the diff between the file as red on the
237 | # disk, and the current buffer (which may differ from the disk's state). See
238 | # http://docs.python.org/2/library/difflib.html for details about diff codes.
239 | #
240 | # It relies on a full diff, so it may be expensive computation for very large
241 | # files (diff generation + looping through all lines).
242 | #
243 | # old - a buffer of lines, as in "old version"
244 | # new - a buffer of lines, as in "new version"
245 | #
246 | # Returns the list of edited line numbers.
247 | def modified_lines_as_numbers(old: List[str], new: List[str]) -> Union[Literal[False], List[int]]:
248 | d = difflib.Differ()
249 | diffs = d.compare(old, new)
250 |
251 | # Pretty Naive Algorithm (tm):
252 | # - split off the "Differ code", to check whether:
253 | # - the line is in either in both files or just b: increment the line number
254 | # - the line is only in b: it qualifies as an edited line!
255 | # Starting from -1 as ST2 is internally 0-based for lines.
256 | lineNum = -1
257 | edited_lines: List[int] = []
258 | for line in diffs:
259 | code = line[:2]
260 | # those lines with "? " are not real! watch out!
261 | if code in (" ", "+ "):
262 | lineNum += 1
263 | if code == "+ ":
264 | edited_lines.append(lineNum)
265 |
266 | return False if not edited_lines else edited_lines
267 |
268 |
269 | # Private: Find the dirty lines.
270 | #
271 | # view - the view, you know
272 | #
273 | # Returns the list of regions matching dirty lines.
274 | def get_modified_lines(view: sublime.View) -> List[sublime.Region]:
275 | on_buffer = view.substr(sublime.Region(0, view.size())).splitlines()
276 | lines = []
277 | line_numbers = modified_lines_as_numbers(on_disk or [], on_buffer)
278 | if line_numbers:
279 | lines = [view.full_line(view.text_point(number, 0)) for number in line_numbers]
280 | return lines
281 |
282 |
283 | # Private: Finds the trailing spaces regions to be deleted.
284 | #
285 | # It abides by the user settings: while in mode "Only Modified Lines", it returns
286 | # the subset of trailing spaces regions which are within dirty lines; otherwise, it
287 | # returns all trailing spaces regions for the document.
288 | #
289 | # view - the view, you know
290 | #
291 | # Returns a list of regions to be deleted.
292 | def find_regions_to_delete(view: sublime.View) -> List[sublime.Region]:
293 | (regions, highlightable) = find_trailing_spaces(view, scan_only_visible=False)
294 |
295 | # Filtering is required in case triming is restricted to dirty regions only.
296 | if settings.modified_lines_only:
297 | modified_lines = get_modified_lines(view)
298 |
299 | # If there are no dirty lines, don't do nothing.
300 | if not modified_lines:
301 | return []
302 |
303 | # Super-private: filters trailing spaces regions to dirty lines only.
304 | #
305 | # As one cannot perform a smart find_all within arbitrary boundaries, we must do some
306 | # extra work:
307 | # - we want to loop through the modified lines set, not the whole trailing regions
308 | # - but we need a way to match modified lines with trailings to those very regions
309 | #
310 | # Hence the reversed dict on regions: keys are the text_point of the begining of
311 | # each region, values are the region's actual boundaries. As a Region is unhashable,
312 | # trailing regions are being recreated later on from those two values.
313 | #
314 | # We loop then loop through the modified lines: for each line, we get its begining
315 | # text_point, and check whether it matches a line with trailing spaces in the
316 | # reversed dict. If so, this is a match (a modified line with trailing spaces), so
317 | # we can re-create and store a Region for the relevant trailing spaces boundaries.
318 | #
319 | # Returns the filtered list of trailing spaces regions for the modified lines set.
320 | def only_those_with_trailing_spaces() -> List[sublime.Region]:
321 | regions_by_begin: Dict[sublime.Point, Tuple[sublime.Point, sublime.Point]] = {}
322 | matches: List[sublime.Region] = []
323 | for region in regions:
324 | begin = view.line(region).begin()
325 | regions_by_begin[begin] = (region.begin(), region.end())
326 |
327 | for line in modified_lines:
328 | text_point = line.begin()
329 | if text_point in regions_by_begin:
330 | matches.append(sublime.Region(regions_by_begin[text_point][0], regions_by_begin[text_point][1]))
331 |
332 | return matches
333 |
334 | regions = only_those_with_trailing_spaces()
335 |
336 | return regions
337 |
338 |
339 | # Private: Deletes the trailing spaces regions.
340 | #
341 | # view - the view, you know
342 | # edit - the Edit object spawned by the deletion command
343 | #
344 | # Returns the number of deleted regions.
345 | def delete_trailing_regions(view: sublime.View, edit: sublime.Edit) -> int:
346 | regions = find_regions_to_delete(view)
347 |
348 | if regions:
349 | # Trick: reversing the regions takes care of the growing offset while
350 | # deleting the successive regions.
351 | regions.reverse()
352 | for r in regions:
353 | view.erase(edit, r)
354 | return len(regions)
355 | else:
356 | return 0
357 |
358 |
359 | # Public: Toggles the highlighting on or off.
360 | class ToggleTrailingSpacesCommand(sublime_plugin.WindowCommand):
361 | def run(self) -> None:
362 | view = self.window.active_view()
363 | if not view:
364 | return
365 |
366 | if max_size_exceeded(view):
367 | sublime.status_message("File is too big, trailing spaces handling disabled.")
368 | return
369 |
370 | state = toggle_highlighting(view)
371 | settings.highlight_color = current_highlight_color
372 | settings.save()
373 | sublime.status_message('Highlighting of trailing spaces is %s' % state)
374 |
375 | def is_checked(self) -> bool:
376 | return current_highlight_color != ""
377 |
378 |
379 | # Public: Toggles "Modified Lines Only" mode on or off.
380 | class ToggleTrailingSpacesModifiedLinesOnlyCommand(sublime_plugin.WindowCommand):
381 | def run(self) -> None:
382 | was_on = settings.modified_lines_only
383 | settings.modified_lines_only = not was_on
384 | settings.save()
385 |
386 | message = "Let's trim trailing spaces everywhere" if was_on \
387 | else "Let's trim trailing spaces only on modified lines"
388 | sublime.status_message(message)
389 |
390 | def is_checked(self) -> bool:
391 | return settings.modified_lines_only
392 |
393 |
394 | # Public: Matches and highlights trailing spaces on key events, according to the
395 | # current settings.
396 | class TrailingSpacesListener(sublime_plugin.EventListener):
397 | def on_modified_async(self, view: sublime.View) -> None:
398 | if settings.enabled:
399 | match_trailing_spaces(view)
400 |
401 | def on_selection_modified_async(self, view: sublime.View) -> None:
402 | if settings.enabled:
403 | match_trailing_spaces(view)
404 |
405 | def on_activated_async(self, view: sublime.View) -> None:
406 | if settings.modified_lines_only:
407 | self.freeze_last_version(view)
408 |
409 | if settings.enabled:
410 | match_trailing_spaces(view)
411 |
412 | # continuously watch view for changes to the visible region
413 | if view.id() not in active_views:
414 | # track
415 | active_views[view.id()] = view.visible_region()
416 | self.update_on_region_change(view)
417 |
418 | def on_pre_save(self, view: sublime.View) -> None:
419 | if settings.modified_lines_only:
420 | self.freeze_last_version(view)
421 |
422 | if settings.trim_on_save:
423 | view.run_command("delete_trailing_spaces")
424 |
425 | def on_close(self, view: sublime.View) -> None:
426 | # untrack
427 | active_views.pop(view.id(), None)
428 |
429 | def update_on_region_change(self, view: sublime.View) -> None:
430 | # remove views not currently visible
431 | if not self.is_view_visible(view):
432 | active_views.pop(view.id(), None)
433 | return
434 |
435 | # compare the currently visible region to the previous (if any) and
436 | # update if there were changes
437 | if view.visible_region() != active_views.get(view.id(), view.visible_region()):
438 | match_trailing_spaces(view)
439 | active_views[view.id()] = view.visible_region()
440 |
441 | # continue only if the view is still active
442 | if settings.enabled and view.id() in active_views:
443 | sublime.set_timeout_async(lambda: self.update_on_region_change(view), settings.update_interval)
444 |
445 | # Toggling messes with what is red from the disk, and it breaks the diff
446 | # used when modified_lines_only is true. Honestly, I don't know why (yet).
447 | # Anyway, let's cache the persisted version of the document's buffer for
448 | # later use on specific event, so that we always have a decent version of
449 | # "what's on the disk" to work with.
450 | def freeze_last_version(self, view: sublime.View) -> None:
451 | global on_disk
452 |
453 | file_name = view.file_name()
454 | # For some reasons, the on_activated hook gets fired on a ghost document
455 | # from time to time.
456 | if file_name and not view.is_scratch() and isfile(file_name):
457 | encoding = view.encoding()
458 |
459 | if encoding == "Undefined":
460 | encoding = cast(str, view.settings().get("default_encoding", "UTF-8"))
461 |
462 | if encoding == "Hexadecimal": # not supported?
463 | on_disk = None
464 | return
465 |
466 | match = re.match(r'.+\(([^)]+)\)$', encoding)
467 | encoding = match.group(1) if match else encoding
468 |
469 | with codecs.open(file_name, "r", encoding) as f:
470 | on_disk = f.read().splitlines()
471 |
472 | def is_view_visible(self, view: sublime.View) -> bool:
473 | window = view.window()
474 | if not window:
475 | return False
476 |
477 | # panel views don't trigger on_close but are also not valid anymore
478 | # after being hidden, so try to detect these cases here
479 | if view.size() == 0 and not view.file_name():
480 | return False
481 |
482 | # see if this view is visible in its group
483 | group = window.get_view_index(view)[0]
484 | if group != -1:
485 | active_view_in_group = window.active_view_in_group(group)
486 | # won't be present if a html sheet is active
487 | if active_view_in_group:
488 | return view.id() == active_view_in_group.id()
489 |
490 | # check if this view is the active panel
491 | active_panel = window.active_panel() or ""
492 |
493 | # find_output_panel only works without the "output."" prefix
494 | if active_panel.startswith("output."):
495 | active_panel = active_panel[len("output."):]
496 |
497 | panel_view = window.find_output_panel(active_panel)
498 | if panel_view and view.id() == panel_view.id():
499 | return True
500 |
501 | return False
502 |
503 |
504 | # Public: Deletes the trailing spaces.
505 | class DeleteTrailingSpacesCommand(sublime_plugin.TextCommand):
506 | def run(self, edit: sublime.Edit) -> None:
507 | if max_size_exceeded(self.view):
508 | sublime.status_message("File is too big, trailing spaces handling disabled.")
509 | return
510 |
511 | deleted = delete_trailing_regions(self.view, edit)
512 |
513 | if deleted:
514 | if settings.save_after_trim and not settings.trim_on_save:
515 | sublime.set_timeout(lambda: self.save(self.view), 10)
516 |
517 | msg_parts = {"nbRegions": deleted,
518 | "plural": 's' if deleted > 1 else ''}
519 | message = "Deleted %(nbRegions)s trailing spaces region%(plural)s" % msg_parts
520 | else:
521 | message = "No trailing spaces to delete!"
522 |
523 | sublime.status_message(message)
524 |
525 | def save(self, view: sublime.View) -> None:
526 | if view.file_name() is None:
527 | view.run_command('prompt_save_as')
528 | else:
529 | view.run_command('save')
530 |
--------------------------------------------------------------------------------
/trailing_spaces.sublime-settings:
--------------------------------------------------------------------------------
1 | // Trailing Spaces' default settings.
2 | //
3 | // See Trailing Spaces' README for detailed instructions.
4 | {
5 | // By default, Trailing Spaces is "live". It means the trailing spaces
6 | // regions will be matched in the background, and highlighted if a color
7 | // scope is defined, when the document is opened and edited.
8 | // Set to false to disable live matching and highlighting (the deletion
9 | // command remains available, so-called "lazy matching").
10 | "enabled" : true,
11 |
12 | // Highlight color is specified as a scope. You may define and use a custom
13 | // scope to better fit your colorscheme. A value of empty string "" will
14 | // make highlights invisible.
15 | "highlight_color" : "region.redish",
16 |
17 | // By default, empty lines are cleared as well when calling the deletion
18 | // command.
19 | // Set to false to ignore empty lines upon deletion.
20 | "include_empty_lines" : true,
21 |
22 | // By default, the line being currently edited will have its trailing
23 | // spaces highlighted.
24 | // Set to false to ignore trailing spaces on the edited line.
25 | "include_current_line" : true,
26 |
27 | // By default, any lines in the Find Results, Build output, Diff and Markdown views are ignored
28 | // Add scopes to this list if you need to ignore them.
29 | "scope_ignore": ["text.find-in-files", "source.build_output", "source.diff", "text.html.markdown"],
30 |
31 | // By default, trailing spaces are deleted within the whole document.
32 | // Set to true to affect only the lines you edited since last save.
33 | // Trailing spaces will still be searched for and highlighted in the whole
34 | // document.
35 | "modified_lines_only": false,
36 |
37 | // By default, nothing happens on save.
38 | // Set to true to trim trailing spaces before saving, with respect to the
39 | // other settings.
40 | "trim_on_save": false,
41 |
42 | // By default, deleting trailing spaces does not cause the document to be
43 | // saved.
44 | // Set to true to force saving after trailing spaces have been deleted.
45 | // This setting is irrelevant and will be ignored if trim_on_save is true.
46 | "save_after_trim": false,
47 |
48 | // ---- NEXT SETTINGS ARE FOR POWER USERS ONLY! ----
49 |
50 | // The number of characters before and after the visible region of text to
51 | // include in the highlighting. This is useful to also show the highlighting
52 | // immediately for text that just became visible through scrolling.
53 | // Adjust the value (in the number of characters) to whatever fits your
54 | // needs and performance.
55 | "non_visible_highlighting" : 500,
56 |
57 | // This is the interval at which the active view is tested for changes
58 | // (due to scrolling) to update the highlighting of the currently visible
59 | // region of text.
60 | // Adjust the value (in milliseconds) to whatever fits your needs and
61 | // performance.
62 | "update_interval" : 250,
63 |
64 | // Highlighting will be disabled if the edited file's size is larger than
65 | // this.
66 | // Adjust the value (in number of chars) to whatever fits your performance.
67 | "file_max_size" : 1048576,
68 |
69 | // By default, only simple spaces and tabs are matched as "trailing spaces".
70 | "regexp": "[ \t]+"
71 | }
72 |
--------------------------------------------------------------------------------