├── screen-shot.png ├── HighlightDodgyChars.sublime-settings ├── examples.txt ├── readme.md ├── Main.sublime-menu └── HighlightDodgyChars.py /screen-shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TuureKaunisto/highlight-dodgy-chars/HEAD/screen-shot.png -------------------------------------------------------------------------------- /HighlightDodgyChars.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "whitelist_chars": [ 3 | // currencies 4 | "€£", 5 | // European characters ( http://fasforward.com/list-of-european-special-characters/ ) 6 | "¡¿äàáâãåǎąăæçćĉčđďðèéêëěęĝģğĥìíîïıĵķĺļłľñńňöòóôõőøœŕřẞßśŝşšșťţþțüùúûűũųůŵýÿŷźžż" 7 | // you'll most likely need to restart sublime after editing these settings 8 | ] 9 | } -------------------------------------------------------------------------------- /examples.txt: -------------------------------------------------------------------------------- 1 | Some of the things this plugin highlights: 2 | 3 | Zero width space: ​ 4 | Zero width joiner: ‍ 5 | Zero width non-joiner: ‌ 6 | Zero width no-break space:  7 | Soft hyphen: ­ 8 | Word joiner: ⁠ 9 | Tripple dot: … 10 | Fake comma: ‚ vs. normal: , 11 | Full width semicolon: ; vs. normal: ; 12 | Full width colon: : vs. normal: : 13 | Weird double quotes: ¨ vs. normal: " 14 | High carat: ˆ vs. normal: ^ 15 | Forward single quote: ‘ vs. normal: ´ or ' 16 | Reverse single quote: ’ vs. normal: ` or ' 17 | Forward double quote: “ vs. normal: " 18 | Reverse double quote: ” vs. normal: " 19 | Weird dash: – vs. normal: - 20 | Trade mark: ™ 21 | 22 | 23 | Things this plugin doesn't highlight: 24 | 25 | - Scandinavian special characters: åäöæøÄÖÅÆØ 26 | - Sharp s: ẞß 27 | - Inverted punctuation: ¡¿ 28 | - Characters with accents: 29 | ÄäÀàÁáÂâÃãÅåǍǎĄąĂăÆæÇçĆćĈĉČčĎđĐďðÈèÉéÊêËëĚěĘęĜĝĢģĞğĤĥÌìÍíÎîÏïıĴĵĶķĹĺĻļŁłĽľÑñŃńŇňÖöÒòÓóÔôÕõŐőØøŒœŔŕŘřẞߌśŜŝŞşŠšȘșŤťŢţÞþȚțÜüÙùÚúÛûŰűŨũŲųŮůŴŵÝýŸÿŶŷŹźŽžŻż 30 | 31 | You can whitelist characters you don't wish to highlight in the settings -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Highlight non-ascii characters in Sublime Text 3 2 | 3 | This plugin highlights non-ascii characters excluding whitelisted characters. It makes control characters, zero width spaces, full width colons and other dangerous characters that might break your code visible. 4 | 5 | The plugin highlights bad characters in the editor 6 | 7 | By default the European special characters are whitelisted. The whitelisted characters can be edited in the settings. 8 | 9 | `Sublime Text > Preferences > Package Settings > Highlight Dodgy Chars > Settings - User` 10 | 11 | ## Installing 12 | 13 | The easiest way to install this plugin is with the **Package Control plugin** If you don't have Package Control installed, you can find instructions here: [https://packagecontrol.io/installation](https://packagecontrol.io/installation) 14 | 15 | Once you've installed Package Control, restart Sublime and open the Command Palette (Command+Shift+p on OS X, Control+Shift+p on Linux/Windows). Type/select "Package Control: Install Package", wait while Package Control fetches the latest package list, then type/select `Highlight Dodgy Chars` when the list appears. -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "preferences", 4 | "children": 5 | [ 6 | { 7 | "caption": "Package Settings", 8 | "mnemonic": "P", 9 | "id": "package-settings", 10 | "children": 11 | [ 12 | { 13 | "caption": "Highlight Dodgy Chars", 14 | "children": 15 | [ 16 | { 17 | "command": "open_file", 18 | "args": {"file": "${packages}/Highlight Dodgy Chars/HighlightDodgyChars.sublime-settings"}, 19 | "caption": "Settings - Default" 20 | }, 21 | { 22 | "command": "open_file", 23 | "args": {"file": "${packages}/User/HighlightDodgyChars.sublime-settings"}, 24 | "caption": "Settings - User" 25 | }, 26 | { "caption": "-" } 27 | ] 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | ] -------------------------------------------------------------------------------- /HighlightDodgyChars.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import sublime, sublime_plugin 4 | 5 | class HighlightDodgyChars(sublime_plugin.EventListener): 6 | def on_activated(self, view): 7 | self.get_settings() 8 | self.view = view 9 | self.has_been_modified = False 10 | self.delay_update = False 11 | 12 | self.phantom_set = sublime.PhantomSet(view) 13 | # highlight dodgy characters when the file is opened 14 | self.highlight() 15 | 16 | def get_settings(self): 17 | settings = sublime.load_settings('HighlightDodgyChars.sublime-settings') 18 | 19 | self.whitelist = settings.get('whitelist_chars') 20 | 21 | if isinstance(self.whitelist, list): 22 | self.whitelist = ''.join(self.whitelist) 23 | 24 | if self.whitelist is None: 25 | self.whitelist = '' 26 | 27 | # for some reason the sublime.IGNORECASE -flag did not work so lets 28 | # duplicate the chars as lower and upper :( 29 | self.whitelist += self.whitelist.upper() 30 | 31 | def on_modified_async(self, view): 32 | # call highlight max 4 times a second 33 | if self.delay_update: 34 | # if a modification happens during cooldown, an update is needed afterwards 35 | self.has_been_modified = True 36 | else: 37 | self.highlight() 38 | # 250 ms cooldown 39 | self.delay_update = True 40 | sublime.set_timeout(self.end_cooldown, 250) 41 | 42 | def end_cooldown(self): 43 | self.delay_update = False; 44 | if self.has_been_modified: 45 | self.has_been_modified = False; 46 | self.highlight() 47 | 48 | def highlight(self): 49 | if self.view.settings().get('terminus_view'): 50 | return 51 | 52 | phantoms = [] 53 | # allow newline, forward-tick and tabulator 54 | default_whitelist = u'\n´\u0009' 55 | # search for non-ascii characters that are not on the whitelist 56 | needle = '[^\x00-\x7F' + default_whitelist + self.whitelist + ']' 57 | 58 | # search the view 59 | for pos in self.view.find_all(needle): 60 | phantoms.append(sublime.Phantom(pos, '!', sublime.LAYOUT_INLINE)) 61 | 62 | # if something dodgy was found, highlight the dodgy parts 63 | self.phantom_set.update(phantoms); 64 | --------------------------------------------------------------------------------