-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathshell.html
More file actions
407 lines (301 loc) · 23.1 KB
/
Copy pathshell.html
File metadata and controls
407 lines (301 loc) · 23.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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shell Customizations for Python Development — Introduction To Python 1.3 documentation</title>
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="top" title="Introduction To Python 1.3 documentation" href="../index.html"/>
<link rel="up" title="Supplemental Materials" href="index.html"/>
<link rel="next" title="git Overview" href="git_overview.html"/>
<link rel="prev" title="Turning Sublime Text Into a Lightweight Python IDE" href="sublime_as_ide.html"/>
<script src="../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../index.html" class="icon icon-home"> Introduction To Python
</a>
<div class="version">
1.3
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../session01.html">Session One: Introductions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session02.html">Session Two: gitHub, Functions, Booleans and Modules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session03.html">Session Three: Sequences, Iteration and String Formatting</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session04.html">Session Four: Dictionaries, Sets, and Files</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session05.html">Session Five: Exceptions, Testing, Comprehensions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session06.html">Session Six: Advanced Argument Passing, lambda, functions as objects</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session07.html">Object Oriented Programming</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session08.html">Session Eight: More OO: Properties, Special methods.</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session09.html">Session Nine: Iterators, Iterables, and Generators</a></li>
<li class="toctree-l1"><a class="reference internal" href="../session10.html">Session Ten: Decorators and Context Managers – Wrap Up</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../exercises/index.html">Exercises</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Supplemental Materials</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="python_learning_resources.html">Useful Python Learning Resources</a></li>
<li class="toctree-l2"><a class="reference internal" href="python_for_mac.html">Setting up your Mac for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="python_for_windows.html">Setting up Windows for Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="python_for_linux.html">Setting Up Python For Linux</a></li>
<li class="toctree-l2"><a class="reference internal" href="virtualenv.html">Working with Virtualenv</a></li>
<li class="toctree-l2"><a class="reference internal" href="sublime_as_ide.html">Turning Sublime Text Into a Lightweight Python IDE</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="">Shell Customizations for Python Development</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#what-was-that-name-again">What was that name, again?</a></li>
<li class="toctree-l3"><a class="reference internal" href="#where-am-i-what-am-i-doing">Where am I, what am I doing?</a></li>
<li class="toctree-l3"><a class="reference internal" href="#but-wait-there-s-more">But wait, there’s more.</a></li>
<li class="toctree-l3"><a class="reference internal" href="#wrap-up">Wrap-Up</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="git_overview.html">git Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="install_nano_win.html">Installing Nano on Windows</a></li>
<li class="toctree-l2"><a class="reference internal" href="unicode.html">Unicode</a></li>
<li class="toctree-l2"><a class="reference internal" href="unicode.html#mechanics">Mechanics</a></li>
<li class="toctree-l2"><a class="reference internal" href="unicode.html#basic-unicode-lab">Basic Unicode LAB</a></li>
<li class="toctree-l2"><a class="reference internal" href="packaging.html">Packages and Packaging</a></li>
<li class="toctree-l2"><a class="reference internal" href="packaging.html#distributing">Distributing</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Introduction To Python</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html">Docs</a> »</li>
<li><a href="index.html">Supplemental Materials</a> »</li>
<li>Shell Customizations for Python Development</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/supplements/shell.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="shell-customizations-for-python-development">
<span id="shell-customization"></span><h1>Shell Customizations for Python Development<a class="headerlink" href="#shell-customizations-for-python-development" title="Permalink to this headline">¶</a></h1>
<p>The command line is your home as a developer. You must be comfortable there.
In order to improve your comfort there are a number of enhancements you can
make to improve your experience, especially with non-standard software like
<code class="docutils literal"><span class="pre">git</span></code> and <code class="docutils literal"><span class="pre">virtualenv</span></code></p>
<div class="section" id="what-was-that-name-again">
<h2>What was that name, again?<a class="headerlink" href="#what-was-that-name-again" title="Permalink to this headline">¶</a></h2>
<p>For example, <code class="docutils literal"><span class="pre">bash</span></code> offers tab completion. But that doesn’t extend to
interactions with <code class="docutils literal"><span class="pre">git</span></code>. Considering how many branches, tags and remotes you
end up interacting with, and how many long-winded commands there are in
<code class="docutils literal"><span class="pre">git</span></code>, having a similar autocompletion for them would be very nice.</p>
<p>The folks who create such things have been kind enough to provide a shell
script that sets this up. And it’s not hard to install.</p>
<p><a class="reference external" href="https://github.com/git/git/tree/master/contrib/completion">The script</a> is called <code class="docutils literal"><span class="pre">git-completion</span></code> and it’s available in <code class="docutils literal"><span class="pre">bash</span></code>,
<code class="docutils literal"><span class="pre">tcsh</span></code> and <code class="docutils literal"><span class="pre">zsh</span></code> flavors.</p>
<p>To use it, download the version of the script that corresponds to your
preferred shell from the tag of the git repo that corresponds to the version of
git you are using. I’ve got git 1.8.4.2 installed on my machine, so
<a class="reference external" href="https://raw.github.com/git/git/v1.8.4.2/contrib/completion/git-completion.bash">this is the version for me</a>. Put it in your home directory:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span><span class="nb">cd</span>
<span class="nv">$ </span>curl https://raw.github.com/git/git/v1.8.4.2/contrib/completion/git-completion.bash -o .git-completion.bash
</pre></div>
</div>
<p>Then source it from your shell startup file:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nb">source</span> ~/.git-completion.bash
</pre></div>
</div>
<p>There’s even a nifty gist that <a class="reference external" href="https://gist.github.com/johngibb/972430">does this automatically</a> for OS X.</p>
<p>Once installed, you should be able to visit any repository you have on your
machine and get tab completion of branch names, remotes and all git commands.</p>
</div>
<div class="section" id="where-am-i-what-am-i-doing">
<h2>Where am I, what am I doing?<a class="headerlink" href="#where-am-i-what-am-i-doing" title="Permalink to this headline">¶</a></h2>
<p>As a working developer, you end up with a <em>lot</em> of projects. Even with tab
completion its a chore to remember which branch is checked out, how far ahead
or behind the remote you are, and so on.</p>
<p>Enter <a class="reference external" href="https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh">git-prompt</a>. Again, you place this code in your home directory, and
then source it from your shell startup file:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nb">source</span> ~/.git-prompt.sh
</pre></div>
</div>
<p>Once you do this you can use the <code class="docutils literal"><span class="pre">__git_ps1</span></code> shell command and a number of
shell variables to configure <code class="docutils literal"><span class="pre">PS1</span></code> and change your shell prompt. You can show
the name of the current branch of a repository when you are in one. You can
get information about the status of HEAD, modified files, stashes, untracked
files and more.</p>
<p>There’s two ways to do this. The first is to use <code class="docutils literal"><span class="pre">__git_ps1</span></code> as a command
directly in a <code class="docutils literal"><span class="pre">PS1</span></code> expression in your shell startup file:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nb">export </span><span class="nv">PS1</span><span class="o">=</span><span class="s1">'[\u@\h \W$(__git_ps1 " (%s)")]\$ '</span>
</pre></div>
</div>
<p>The result looks like this:</p>
<a class="reference internal image-reference" href="../_images/simple_prompt.png"><img alt="Overriding PS1 provides a customized shell prompt" src="../_images/simple_prompt.png" style="width: 600px;" /></a>
<p>That’s not bad, but a bit of color would be nice, and perhaps breaking things
onto more than one line so you can parse what you’re seeing more easily would
be helpful.</p>
<p>For that, you’ll need to change strategies. The <code class="docutils literal"><span class="pre">__git_ps1</span></code> command can be
used as a single element in the expression for <code class="docutils literal"><span class="pre">PS1</span></code>. But it can also be
used itself as the <code class="docutils literal"><span class="pre">PROMPT_COMMAND</span></code> env variable (this command is for
<code class="docutils literal"><span class="pre">bash</span></code>, there’s different one for <code class="docutils literal"><span class="pre">zsh</span></code>). If defined, this command will be
used to form <code class="docutils literal"><span class="pre">PS1</span></code> dynamically.</p>
<p>When you use <code class="docutils literal"><span class="pre">__git_ps1</span></code> in this way, a couple of things happen. First,
instead of taking only one optional argument (a format string), you can provide
two or optionally three arguments:</p>
<ul class="simple">
<li>The first will be prepended to the output of the command</li>
<li>The second will be appended after</li>
<li>The optional third argumment will be used as a format string for the output
of the command itself. If there is no output, it will not appear at all.</li>
</ul>
<p>Combining these three elements can be very expressive. For example, A standard
OS X command prompt can be expressed like so: <code class="docutils literal"><span class="pre">\h:\W</span> <span class="pre">\u\\\$</span> <span class="pre">``.</span> <span class="pre">If</span> <span class="pre">you</span> <span class="pre">use</span> <span class="pre">this</span>
<span class="pre">expression</span> <span class="pre">as</span> <span class="pre">the</span> <span class="pre">second</span> <span class="pre">argument,</span> <span class="pre">leave</span> <span class="pre">the</span> <span class="pre">first</span> <span class="pre">empty</span> <span class="pre">and</span> <span class="pre">provide</span> <span class="pre">a</span> <span class="pre">simple</span> <span class="pre">format</span>
<span class="pre">ending</span> <span class="pre">in</span> <span class="pre">a</span> <span class="pre">newline</span> <span class="pre">for</span> <span class="pre">the</span> <span class="pre">``__git_ps1</span></code> output, you get some nice results.</p>
<p>Enter this in your shell startup file:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s1">'__git_ps1 "" "\h:\W \u\\\$ " "[%s]\n"'</span>
</pre></div>
</div>
<p>That produces a nice two-line prompt that appears when you’re in a git repo, and
disappears when you’re not:</p>
<a class="reference internal image-reference" href="../_images/two_line_prompt.png"><img alt="A two-line prompt showing current git repository" src="../_images/two_line_prompt.png" style="width: 600px;" /></a>
<p>You can also play with setting a few environment variables in your shell
startup file to expand this further. For example, colorizing the output and
providing information about the state of a repo:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">GIT_PS1_SHOWDIRTYSTATE</span><span class="o">=</span>1
<span class="nv">GIT_PS1_SHOWCOLORHINTS</span><span class="o">=</span>1
<span class="nv">GIT_PS1_SHOWSTASHSTATE</span><span class="o">=</span>1
<span class="nv">GIT_PS1_SHOWUPSTREAM</span><span class="o">=</span><span class="s2">"auto"</span>
<span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s1">'__git_ps1 "" "\h:\W \u\\\$ " "[%s]\n"'</span>
</pre></div>
</div>
<a class="reference internal image-reference" href="../_images/color_git_prompt.png"><img alt="A colorized git prompt" src="../_images/color_git_prompt.png" style="width: 600px;" /></a>
<p>Not half bad at all.</p>
</div>
<div class="section" id="but-wait-there-s-more">
<h2>But wait, there’s more.<a class="headerlink" href="#but-wait-there-s-more" title="Permalink to this headline">¶</a></h2>
<p>The problem with this is that it doesn’t play well with another incredibly
useful tool, <a class="reference external" href="http://virtualenv.org">virtualenv</a>. When you activate a virtualenv, it prepends the name
of the environment you are working on to the shell prompt.</p>
<p>But it uses the standard <code class="docutils literal"><span class="pre">PS1</span></code> shell variable to do this. Since you’ve now
used the <code class="docutils literal"><span class="pre">PROMPT_COMMAND</span></code> to create your prompt, <code class="docutils literal"><span class="pre">PS1</span></code> is ignored, and
this nice feature of virtualenv is lost.</p>
<p>Luckily, there is a way out. Bash shell scripting offers <a class="reference external" href="http://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion">parameter expansion</a>
and a trick of the that syntax can help. Normally, a shell parameter is
referenced like so:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ PARAM</span><span class="o">=</span><span class="s1">'foobar'</span>
<span class="nv">$ </span><span class="nb">echo</span> <span class="nv">$PARAM</span>
foobar
</pre></div>
</div>
<p>In complicated situations, you can wrap the name of the paramter in curly
braces to avoid confusion with following characters:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span><span class="nb">echo</span> <span class="si">${</span><span class="nv">PARAM</span><span class="si">}</span>andthennotparam
foobarandthennotparam
</pre></div>
</div>
<p>What is not as well known is that this curly-brace syntax has a lot of
interesting variations. For example, you can use <code class="docutils literal"><span class="pre">PARAM</span></code> as a test and
actually print something else entirely:</p>
<div class="highlight-bash"><div class="highlight"><pre>$ echo ${PARAM:+'foo'}
foo
$ echo ${PARAM:+'bar'}
$
</pre></div>
</div>
<p>The key here is the <code class="docutils literal"><span class="pre">:<char></span></code> bit immediately after <code class="docutils literal"><span class="pre">PARAM</span></code>. If the <code class="docutils literal"><span class="pre">+</span></code>
char is present, then if <code class="docutils literal"><span class="pre">PARAM</span></code> is unset or null, what comes after is not
printed, otherwise it is.</p>
<p>If you look at the script that <a class="reference external" href="https://github.com/pypa/virtualenv/blob/develop/virtualenv_embedded/activate.sh">activates a virtualenv in bash</a> you’ll notice
that it exports <code class="docutils literal"><span class="pre">VIRTUAL_ENV</span></code>. This means that so long as a virtualenv is
active, this environmental variable will be set. And it will be unset when no
environment is active.</p>
<p>You can use that!</p>
<p>Armed with this knowledge, you can construct a shell expression that will either
print the name of the active virtualenv in square brackets, or print nothing if
no virtualenv was active:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span><span class="nb">echo</span> <span class="si">${</span><span class="nv">VIRTUAL_ENV</span><span class="p">:+[</span><span class="sb">`</span>basename <span class="nv">$VIRTUAL_ENV</span><span class="sb">`</span><span class="p">]</span><span class="si">}</span>
<span class="nv">$ </span><span class="nb">source</span> /path/to/someenv/bin/activate
<span class="nv">$ </span><span class="nb">echo</span> <span class="si">${</span><span class="nv">VIRTUAL_ENV</span><span class="p">:+[</span><span class="sb">`</span>basename <span class="nv">$VIRTUAL_ENV</span><span class="sb">`</span><span class="p">]</span><span class="si">}</span>
someenv
</pre></div>
</div>
<p>Roll that into your shell startup file. You’ll have everything you want. You
can even throw in a little more color for good measure:</p>
<div class="highlight-bash"><div class="highlight"><pre><span class="nb">source</span> ~/.git-prompt.sh
<span class="c"># PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '</span>
<span class="nv">GIT_PS1_SHOWDIRTYSTATE</span><span class="o">=</span>1
<span class="nv">GIT_PS1_SHOWCOLORHINTS</span><span class="o">=</span>1
<span class="nv">GIT_PS1_SHOWSTASHSTATE</span><span class="o">=</span>1
<span class="nv">GIT_PS1_SHOWUPSTREAM</span><span class="o">=</span><span class="s2">"auto"</span>
<span class="nv">Color_Off</span><span class="o">=</span><span class="s2">"\[\033[0m\]"</span>
<span class="nv">Yellow</span><span class="o">=</span><span class="s2">"\[\033[0;33m\]"</span>
<span class="nv">PROMPT_COMMAND</span><span class="o">=</span><span class="s1">'__git_ps1 "${VIRTUAL_ENV:+[$Yellow`basename $VIRTUAL_ENV`$Color_Off]\n}" "\h:\W \u\\\$ " "[%s]\n"'</span>
</pre></div>
</div>
<p>And voilà! You’ve got a shell prompt that informs about all the things you’ll
need to know when working on a daily basis:</p>
<a class="reference internal image-reference" href="../_images/virtualenv_prompt.png"><img alt="A shell session showing the prompt with both virtualenv and git information" src="../_images/virtualenv_prompt.png" style="width: 600px;" /></a>
</div>
<div class="section" id="wrap-up">
<h2>Wrap-Up<a class="headerlink" href="#wrap-up" title="Permalink to this headline">¶</a></h2>
<p>There is still a great deal more that you could do with your shell, but this
will suffice for now. If you are interested in reading further, there is
<a class="reference external" href="http://www.gnu.org/software/bash/manual/bash.html">a lot to learn</a>.</p>
</div>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="git_overview.html" class="btn btn-neutral float-right" title="git Overview" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="sublime_as_ide.html" class="btn btn-neutral" title="Turning Sublime Text Into a Lightweight Python IDE" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
© Copyright 2014, Christopher Barker, Cris Ewing, .
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../',
VERSION:'1.3',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
});
</script>
</body>
</html>