-
Notifications
You must be signed in to change notification settings - Fork 99
Expand file tree
/
Copy pathindex.html
More file actions
233 lines (189 loc) · 13.1 KB
/
index.html
File metadata and controls
233 lines (189 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>MagicPython by MagicStack</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
</head>
<body>
<section class="page-header">
<h1 class="project-name">MagicPython</h1>
<h2 class="project-tagline">Syntax highlighter for cutting edge Python for Sublime Text and Atom.</h2>
<a href="https://github.com/MagicStack/MagicPython" class="btn">View on GitHub</a>
<a href="https://github.com/MagicStack/MagicPython/zipball/master" class="btn">Download .zip</a>
<a href="https://github.com/MagicStack/MagicPython/tarball/master" class="btn">Download .tar.gz</a>
</section>
<section class="main-content">
<p>This is a package with preferences and syntax highlighter for cutting edge
Python 3 (although Python 2 is well supported too). The syntax is compatible
with <a href="http://www.sublimetext.com">Sublime Text</a> and <a href="http://atom.io">Atom</a>.
It is meant to be a drop-in replacement for the default Python package.</p>
<p>The main motivation behind this package was the difficulty of using modern
Python with other common syntax highlighters. They do a good job of the 90% of
the language, but then fail on the nuances of some very useful, but often
overlooked features. Function annotations tend to freak out the highlighters in
various ways. Newly introduced keywords and magic methods are slow to be
integrated. Another issue is string highlighting, where all raw strings are
often assumed to be regular expressions or special markup used by <code>.format</code> is
completely ignored. Bumping into all of these issues on daily basis eventually
led to the creation of this package.</p>
<h2>
<a id="installation-instructions" class="anchor" href="#installation-instructions" aria-hidden="true"><span class="octicon octicon-link"></span></a>Installation Instructions</h2>
<p>This is meant to be a drop-in replacement for the default Python package.</p>
<p>In <strong>Atom</strong>, install the <code>MagicPython</code> package and disable the built-in
<code>language-python</code> package.</p>
<p>In <strong>Sublime Text</strong>, install <code>MagicPython</code> package via "Package Control" and
disable the built-in <code>Python</code> package (using
<code>Package Control -> Disable Package</code>, or directly by adding <code>"Python"</code> to
<code>"ignored_packages"</code> in the settings file).</p>
<p>Alternatively, the package can be installed manually in both editors:</p>
<ul>
<li>copy the MagicPython package into the Sublime/Atom user packages directory;</li>
<li>disable Python package;</li>
<li>enjoy.</li>
</ul>
<h2>
<a id="changes-and-improvements" class="anchor" href="#changes-and-improvements" aria-hidden="true"><span class="octicon octicon-link"></span></a>Changes and Improvements</h2>
<p>Overall, the central idea is that it should be easy to notice something odd or
special about the code. Odd or special doesn't necessarily mean incorrect, but
certainly worth the explicit attention.</p>
<h3>
<a id="annotations" class="anchor" href="#annotations" aria-hidden="true"><span class="octicon octicon-link"></span></a>Annotations</h3>
<p>Annotations should not break the highlighting. They should be no more difficult
to read at a glance than other code or comments.</p>
<p>A typical case is having a string annotation that spans several lines by using
implicit string concatenation. Multi-line strings are suboptimal for use in
annotations as it may be highly undesirable to have odd indentation and extra
whitespace in the annotation string. Of course, there is no problem using line
continuation or even having comments mixed in with implicit string
concatenation. All of these will be highlighted as you'd expect in any other
place in the code.</p>
<div class="highlight highlight-source-python"><pre><span class="pl-k">def</span> <span class="pl-en">some_func</span>(<span class="pl-smi">a</span>, <span class="pl-c"># nothing fancy here, yet</span>
b: 'Annotation: ' <span class="pl-c"># implicitly</span>
'"foo" for <span class="pl-smi">Foo</span>, ' <span class="pl-c"># concatenated</span>
'"bar" for <span class="pl-smi">Bar</span>, ' <span class="pl-c"># annotation</span>
'"other" otherwise'='otherwise'):</pre></div>
<p>A more advanced use case for annotations is to actually have complex expressions
in them, such as lambda functions, tuples, lists, dicts, sets, comprehensions.
Admittedly, all of these might be less frequently used, but when they are, you
can rely on them being highlighted normally in all their glorious details.</p>
<div class="highlight highlight-source-python"><pre><span class="pl-c"># no reason why this should cause the highlighter to break</span>
<span class="pl-c">#</span>
<span class="pl-k">def</span> <span class="pl-en">some_func</span>(a:
<span class="pl-c"># annotation starts here</span>
lambda <span class="pl-smi">x</span><span class="pl-k">=</span><span class="pl-c1">None</span>:
{key: <span class="pl-smi">val</span>
for <span class="pl-smi">key</span>, val <span class="pl-smi">in</span>
(x if x is not None else [])
}
<span class="pl-c"># annotation ends here and below is the default for 'a'</span>
=42):</pre></div>
<p>Result annotations are handled as any other expression would be. No reason to
worry that the body of the function would look messed up.</p>
<div class="highlight highlight-source-python"><pre><span class="pl-c"># no reason why this should cause the highlighter to break</span>
<span class="pl-c">#</span>
<span class="pl-k">def</span> <span class="pl-en">some_func</span>() -> {
'Some', <span class="pl-c"># comments</span>
'valid', <span class="pl-c"># are</span>
'expression' <span class="pl-c"># good</span>
}:</pre></div>
<h3>
<a id="strings" class="anchor" href="#strings" aria-hidden="true"><span class="octicon octicon-link"></span></a>Strings</h3>
<p>Strings are used in many different ways for processing and presenting data.
Making the highlighter more friendly towards these uses can help you concentrate
your efforts on what matters rather than visual parsing.</p>
<p>Raw strings are often interpreted as regular expressions. This is a bit of a
problem, because depending on the application this may actually not be the most
common case. Raw strings can simply be the input to some other processor, in
which case regexp-specific highlighting is really hindering the overall
readability. MagicPython follows a convention that a lower-case <code>r</code> prefix means
a regexp string, but an upper-case <code>R</code> prefix means just a raw string with no
special regexp semantics. This convention holds true for all of the legal
combinations of prefixes. As always the syntax is biased towards Python 3, thus
it will mark Pyhton-2-only prefixes (i.e. variations of <code>ur</code>) as deprecated.</p>
<p>String formatting is often only supported for '%-style formatting', however, the
recommended and more readable syntax used by <code>.format</code> is ignored. The benefits
of using simple and readable <code>{key}</code> replacement fields are hindered by the fact
that in a complex or long string expression it may not be easily apparent what
parameters will actually be needed by <code>.format</code>. This is why MagicPyhton
highlights both kinds of string formatting syntax within the appropriate string
types (bytes don't have a <code>.format</code> method in Python 3, so they don't get the
special highlighting for it, raw and unicode strings do). Additionally, the
highlighter also validates that the formatting is following the correct syntax.
It can help noticing an error in complex formatting expressions early.</p>
<h3>
<a id="numeric-literals" class="anchor" href="#numeric-literals" aria-hidden="true"><span class="octicon octicon-link"></span></a>Numeric literals</h3>
<p>Most numbers are just regular decimal constants, but any time that octal,
binary, hexadecimal or complex numbers are used it's worth noting that they are
of a special type. Highlighting of Python 2 'L' integers is also supported.</p>
<h3>
<a id="python-35-features" class="anchor" href="#python-35-features" aria-hidden="true"><span class="octicon octicon-link"></span></a>Python 3.5 features</h3>
<p>New keywords <code>async</code> and <code>await</code> are properly highlighted. Currently, these
keywords are new and are not yet reserved, so the Python interpreter will allow
using them as variable names. However, <code>async</code> and <code>await</code> are not recommended
to be used as variable, class, function or module names. Introduced by
<a href="https://www.python.org/dev/peps/pep-0492/">PEP 492</a> in Python 3.5, they will
become proper keywords in Python 3.7. It is very important that the highlighter
shows their proper status when they are used as function parameter names, as
that could otherwise be unnoticed and lead to very messy debugging down the
road.</p>
<h3>
<a id="built-ins-and-magic-methods" class="anchor" href="#built-ins-and-magic-methods" aria-hidden="true"><span class="octicon octicon-link"></span></a>Built-ins and Magic Methods</h3>
<p>Various built-in types, classes, functions, as well as magic methods are all
highlighted. Specifically, they are highlighted when they appear as names in
user definitions. Although it is not an error to have classes and functions that
mask the built-ins, it is certainly worth drawing attention to, so that masking
becomes a deliberate rather than accidental act.</p>
<p>Highlighting built-ins in class inheritance list makes it slightly more obvious
where standard classes are extended. It is also easier to notice some typos
(have you ever typed <code>Excepiton</code>?) a little earlier.</p>
<h3>
<a id="parameters-and-arguments" class="anchor" href="#parameters-and-arguments" aria-hidden="true"><span class="octicon octicon-link"></span></a>Parameters and Arguments</h3>
<p>MagicPython highlights keywords when they are used as parameter/argument names.
This was mentioned for the case of <code>async</code> and <code>await</code>, but it holds true for
all other keywords. Although the Python interpreter will produce an appropriate
error message when reserved keywords are used as identifier names, it's still
worth showing them early, to spare even this small debugging effort.</p>
<h2>
<a id="development" class="anchor" href="#development" aria-hidden="true"><span class="octicon octicon-link"></span></a>Development</h2>
<p>You need <code>npm</code> and <code>node.js</code> to work on MagicPython.</p>
<ul>
<li>clone the repository</li>
<li>run <code>make</code> to build the local development environment</li>
<li>run <code>make release</code> to build the syntax packages for Sublime Text and Atom
(running <code>make test</code> also generates the "release" packages)</li>
</ul>
<p>Please note that we have some unit tests for the syntax scoping. We will be
expanding and updating our test corpus. This allows us to trust that tiny
inconsistencies will not easily creep in as we update the syntax and fix bugs.
Use <code>make test</code> to run the tests regularly while updating the syntax spec.
Currently the test files have two parts to them, separated by 3 empty newlines:
the code to be scoped and the spec that the result must match.</p>
<p>If you intend to submit a pull request, please follow the following guidelines:</p>
<ul>
<li>keep code lines under 80 characters in length, it improves readability</li>
<li>
<p>please <em>do</em> use multi-line regular expressions for any non-trivial cases like:</p>
<ul>
<li>the regexp contains a mix of escaped and unescaped braces/parentheses</li>
<li>the regexp has several <code>|</code> in it</li>
<li>the regexp has several pairs of parentheses, especially nested ones</li>
<li>or the regexp is simply longer than 35 characters</li>
</ul>
</li>
<li><p>always run <code>make test</code> to ensure that your changes didn't have unexpected side
effects</p></li>
<li>update unit tests and add new ones if needed, keeping the test cases short
whenever possible</li>
</ul>
<footer class="site-footer">
<span class="site-footer-owner"><a href="https://github.com/MagicStack/MagicPython">MagicPython</a> is maintained by <a href="https://github.com/MagicStack">MagicStack</a>.</span>
<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
</footer>
</section>
</body>
</html>