├── 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 |
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 |
--------------------------------------------------------------------------------