├── messages.json ├── messages ├── 1.1.0.txt ├── 1.0.0.txt └── 2.0.0.txt ├── highlighttrailingwhitespace.sublime-commands ├── Main.sublime-menu ├── HighlightTrailingWhitespace.sublime-settings ├── LICENSE.txt ├── README.md └── highlight-trailing-whitespace.py /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.0.0": "messages/1.0.0.txt", 3 | "1.1.0": "messages/1.1.0.txt", 4 | "2.0.0": "messages/2.0.0.txt" 5 | } 6 | -------------------------------------------------------------------------------- /messages/1.1.0.txt: -------------------------------------------------------------------------------- 1 | 1.1.0: 2 | 3 | - Added color customization options 4 | - Added option to fill instead of outline 5 | 6 | https://packagecontrol.io/packages/Highlight%20Trailing%20Whitespace 7 | -------------------------------------------------------------------------------- /messages/1.0.0.txt: -------------------------------------------------------------------------------- 1 | This plugin will highlight any trailing whitespace. 2 | 3 | You can enable this through the preferences (or syntax-specific) like so: 4 | 5 | { 6 | "highlight_trailing_whitespace": true, 7 | } 8 | 9 | -------------------------------------------------------------------------------- /highlighttrailingwhitespace.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Preferences: Highlight Trailing Whitespace settings", 4 | "command": "edit_settings", 5 | "args": { 6 | "base_file": "${packages}/Highlight Trailing Whitespace/HighlightTrailingWhitespace.sublime-settings", 7 | "default": "// Any settings in this file overrides the default ones\n{\n\t$0\n}\n" 8 | } 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /messages/2.0.0.txt: -------------------------------------------------------------------------------- 1 | Highlight Trailing Whitespace 2.0.0 changes: 2 | 3 | - Changed to use a package-specific settings file 4 | - You'll need to migrate your old settings to the new format to apply them, sorry about this 5 | - Added refreshing of all views when any setting is changed 6 | - Added default settings with in-line documentation of each setting 7 | - Added shorthands for the settings (try looking for it with the command palette!) 8 | 9 | https://packagecontrol.io/packages/Highlight%20Trailing%20Whitespace 10 | -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "preferences", 4 | "children": [ 5 | { 6 | "id": "package-settings", 7 | "children": [ 8 | { 9 | "caption": "Highlight Trailing Whitespace", 10 | "children": [ 11 | { 12 | "caption": "Settings", 13 | "command": "edit_settings", 14 | "args": { 15 | "base_file": "${packages}/Highlight Trailing Whitespace/HighlightTrailingWhitespace.sublime-settings", 16 | "default": "// Any settings in this file overrides the default ones\n{\n\t$0\n}\n" 17 | } 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /HighlightTrailingWhitespace.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | /* 3 | Change this to `false` to disable highlighting. 4 | */ 5 | "enabled": true, 6 | 7 | /* 8 | Change this to `false` to also highlight whitespace where the cursor is. 9 | */ 10 | "never_on_cursor": true, 11 | 12 | /* 13 | Change this to `true` to fill the highlight instead of only outlining it. 14 | */ 15 | "fill": false, 16 | 17 | /* 18 | Set the highlight color. 19 | Supported color formats: 20 | - Hex RGB (`#RRGGBB`) 21 | - Hex RGBA (`#RRGGBBAA`) 22 | - RGB (`rgb(255, 0, 0)`) 23 | - RGBA (`rgba(255, 255, 255, 0.5)`) 24 | - HSL (`hsl(0, 100%, 100%)`) 25 | - HSLA (`hsl(0, 100%, 100%, 0.5)`) 26 | - Named (`cyan`) 27 | - 28 | */ 29 | "color": "#FF0000" 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Adrian L Lange 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Highlight Trailing Whitespace](//packagecontrol.io/packages/Highlight%20Trailing%20Whitespace) 2 | 3 | This plugin will highlight any trailing whitespace. 4 | 5 | ## Options 6 | 7 | Users can override the options in `Packages/User/HighlightTrailingWhitespace.sublime-settings`. 8 | 9 | This file can be opened either through the menus (_Preferences_ > _Package Settings_ > _Highlight Trailing Whitespace_ > _Settings_) or through the command palette (Ctrl+Shift+P) and enter `Preferences: Highlight Trailing Whitespace settings`. 10 | 11 | ## Installation 12 | 13 | ##### Using the package manager 14 | 15 | 1. Install the [Sublime Text Package Control](//packagecontrol.io/installation) plugin if you haven't already. 16 | - _Preferences_ > _Package Control_ 17 | 2. Open up the command palette (Ctrl+Shift+P) and enter `Package Control: Install Package` 18 | 3. Search for `Highlight Trailing Whitespace` and hit Enter to install. 19 | 20 | ##### Manual installation with Git 21 | 22 | 1. Click the `Preferences > Browse Packages` menu. 23 | 2. Open up a terminal and execute the following: 24 | - `git clone https://github.com/p3lim/sublime-highlight-trailing-whitespace Highlight\ Trailing\ Whitespace` 25 | 3. Restart Sublime Text. 26 | -------------------------------------------------------------------------------- /highlight-trailing-whitespace.py: -------------------------------------------------------------------------------- 1 | import sublime 2 | import sublime_plugin 3 | 4 | import os 5 | import json 6 | 7 | NAMESPACE = 'HighlightTrailingWhitespace' 8 | DEFAULT_COLOR_SCHEME = 'Monokai.sublime-color-scheme' 9 | WHITESPACE_PATTERN = '[\t ]+$' 10 | 11 | settings = None 12 | 13 | def plugin_loaded(): 14 | ''' 15 | Called when the plugin is loaded, used to: 16 | - Load the settings for the package 17 | - Add callbacks for settings changes 18 | - Updates color scheme 19 | ''' 20 | global settings 21 | settings = sublime.load_settings(NAMESPACE + '.sublime-settings') 22 | 23 | # refresh all views when a setting is changed 24 | settings.add_on_change('enabled', lambda: refresh_views()) 25 | settings.add_on_change('never_on_cursor', lambda: refresh_views()) 26 | settings.add_on_change('fill', lambda: refresh_views()) 27 | 28 | # update color scheme when the color setting is changed 29 | settings.add_on_change('color', lambda: update_color_scheme()) 30 | 31 | # update color scheme on load 32 | update_color_scheme() 33 | 34 | def refresh_views(): 35 | ''' 36 | Iterates through all available views and updates the whitespace highlight. 37 | ''' 38 | for window in sublime.windows(): 39 | for view in window.views(): 40 | highlight_whitespace(view) 41 | 42 | def highlight_whitespace(view): 43 | ''' 44 | Highlights any trailing whitespace in the given view. 45 | 46 | :param sublime.View view: The view of the file being highlighted. 47 | ''' 48 | if view.size() > 1e5: 49 | # avoid crashing on large files 50 | return 51 | 52 | if view.settings().get('is_widget', False): 53 | # don't render in widget views 54 | return 55 | 56 | if settings.get('enabled'): 57 | regions = view.find_all(WHITESPACE_PATTERN) 58 | if regions: 59 | # whitespace was found, time to shine! 60 | if settings.get('never_on_cursor'): 61 | # check if the cursor is on one of the matched regions and remove it from the list 62 | selection = view.sel()[0] 63 | for region in regions: 64 | if region.contains(selection): 65 | regions.remove(region) 66 | break 67 | 68 | # determine if we should fill the region or just draw an outline 69 | draw_flag = sublime.DRAW_NO_FILL 70 | if settings.get('fill'): 71 | draw_flag = 0 72 | 73 | # draw on the region(s) 74 | view.add_regions( 75 | NAMESPACE, 76 | regions, 77 | NAMESPACE, 78 | '', 79 | sublime.DRAW_EMPTY | sublime.HIDE_ON_MINIMAP | draw_flag 80 | ) 81 | else: 82 | # no whitespace, clear out 83 | view.erase_regions(NAMESPACE) 84 | else: 85 | # we're disabled, clean up 86 | view.erase_regions(NAMESPACE) 87 | 88 | def update_color_scheme(): 89 | ''' 90 | Creates/updates a copy of the active color scheme with overloads for coloring 91 | the highlight regions. 92 | ''' 93 | 94 | # get the first available view, as the color scheme is applied globally 95 | view = sublime.active_window().active_view() 96 | if not view: 97 | # there's no views open, bail out 98 | return 99 | 100 | # get the name of the current color scheme 101 | path = view.settings().get('color_scheme') or DEFAULT_COLOR_SCHEME 102 | if not path.startswith('Packages/'): 103 | path = 'Packages/Color Scheme - Default/' + path 104 | name = path.split('/')[-1].split('.')[0] 105 | 106 | # create directory we'll save our own color schemes 107 | scheme_path = os.path.join(sublime.packages_path(), 'User', NAMESPACE) 108 | if not os.path.exists(scheme_path): 109 | os.makedirs(scheme_path) 110 | 111 | # create our override color scheme 112 | style = { 113 | 'name': 'Highlight Trailing Whitespace', 114 | 'rules': [{ 115 | 'name': 'Outline', 116 | 'scope': NAMESPACE, 117 | 'foreground': settings.get('color'), 118 | }] 119 | } 120 | 121 | # attempt to create the color scheme, warning the user if it failed 122 | try: 123 | scheme_file = os.path.join(scheme_path, '{}.sublime-color-scheme'.format(name)) 124 | with open(scheme_file, 'wb', buffering=0) as file: 125 | file.write(json.dumps(style, indent=4).encode('utf-8')) 126 | except PermissionError as e: 127 | sublime.ok_cancel_dialog('{} could not access file:\n{}'.format(NAMESPACE, e)) 128 | raise e 129 | except OSError as e: 130 | sublime.ok_cancel_dialog('{} encountered an OS error:\n{}'.format(NAMESPACE, e)) 131 | raise e 132 | 133 | # since the color was changed, also refresh all views 134 | refresh_views() 135 | 136 | class HighlightTrailingWhitespaceListener(sublime_plugin.EventListener): 137 | def on_modified_async(self, view): 138 | ''' 139 | Called when a view is modified, updating the highlight. 140 | ''' 141 | highlight_whitespace(view) 142 | 143 | def on_activated_async(self, view): 144 | ''' 145 | Called when a view is activated (selected), updating the highlight. 146 | ''' 147 | highlight_whitespace(view) 148 | 149 | def on_load_async(self, view): 150 | ''' 151 | Called when the view is loaded, updating the highlight. 152 | ''' 153 | highlight_whitespace(view) 154 | 155 | def on_selection_modified_async(self, view): 156 | ''' 157 | Called when the cursor has been moved in the view, updating the highlight. 158 | ''' 159 | highlight_whitespace(view) 160 | --------------------------------------------------------------------------------