{"id":3382,"date":"2014-06-19T19:14:25","date_gmt":"2014-06-19T19:14:25","guid":{"rendered":"http:\/\/really.zonky.org\/?p=3382"},"modified":"2014-06-21T06:18:23","modified_gmt":"2014-06-21T06:18:23","slug":"zsh-adding-a-green-%e2%9c%93-to-the-prompt","status":"publish","type":"post","link":"https:\/\/really.zonky.org\/?p=3382","title":{"rendered":"ZSH: Adding A Green \u2713 To The Prompt"},"content":{"rendered":"<p>\u2026 or a red \u2717. Incidentally, if your browser doesn&#8217;t show ticks (\u2713), crosses (\u2717), and a right pointing double arrow (\u00bb) properly, this posting may look a bit odd. <\/p>\n<p>As in :-<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/really.zonky.org\/wp-content\/uploads\/2014-06-19_1934.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3383\" src=\"https:\/\/i0.wp.com\/really.zonky.org\/wp-content\/uploads\/2014-06-19_1934.png?resize=695%2C434\" alt=\"2014-06-19_1934\" width=\"695\" height=\"434\" srcset=\"https:\/\/i0.wp.com\/really.zonky.org\/wp-content\/uploads\/2014-06-19_1934.png?w=898&amp;ssl=1 898w, https:\/\/i0.wp.com\/really.zonky.org\/wp-content\/uploads\/2014-06-19_1934.png?resize=300%2C187&amp;ssl=1 300w\" sizes=\"auto, (max-width: 695px) 100vw, 695px\" \/><\/a><\/p>\n<p>The aim here is to make the\u00a0<a href=\"http:\/\/www.zsh.org\/\"><em>zsh<\/em><\/a> prompt (a Unix shell) start with a green \u2713 (tick) if the previous command&#8217;s exit status was zero, and a red \u2717 (cross) if the previous command&#8217;s exit status was non-zero. A tiny thing, but both useful and fun.<\/p>\n<p>The first thing I need is a set of variables containing terminal sequences for setting colours. Fortunately\u00a0<em>zsh<\/em> comes with a set of suitable functions; even if they&#8217;re poorly named :-<\/p>\n<pre>\r\nautoload -U colors && colors\r\n<\/pre>\n<p>The next thing is to perform a test to see if the current terminal type is worth setting a fancy prompt for. In some cases &#8211; such as when using the plain Linux console, or when things are broken enough that the terminal type isn&#8217;t set properly &#8211; it is worth avoiding setting a prompt. I do this by setting up an array containing a list of terminal types that I think it is worth setting a fancy prompt for :-<\/p>\n<pre>\r\nfancyterms=()\r\nfancyterms=(xterm xterms dtterm iris-ansi xterm-256color)\r\n<\/pre>\n<p>(Some of that list is <em>very<\/em> historical!)<\/p>\n<p>The test for whether to set a fancy prompt is somewhat tricky \u2026 it uses a &#8216;reverse subscripting&#8217; flag in the array lookup to search the array for the string :-<\/p>\n<pre>\r\nif [[ ${fancyterms[(r)$TERM]} == \"$TERM\" ]] \r\nthen\r\n  echo Fancy prompt\r\nelse\r\n  echo Plain prompt\r\nfi\r\n<\/pre>\n<p>And lastly, I actually set the prompt :-<\/p>\n<pre>\r\nexport PROMPT=\"%(?.%{$fg[green]%}\u2713 %{$reset_color%}.%{$fg[red]%}\u2717 %{$reset_color%})%B%n@%m\u00bb%b \"\r\n<\/pre>\n<p>Which is not exactly the easiest string to understand, but breaking it up :-<\/p>\n<ol>\n<li>The <em>%{$fg[green]%}<\/em> sequence sets the colour to green, the \u2713 is fairly self-explanatory, and the <em>%{$reset_color%}<\/em> sets the colours back to normal.\n<li>Similarly the <em>%{$fg[red]%}<\/em> sets the colour to red, the \u2717 should also be self-explanatory, and the <em>%{reset_color%}<\/em> does as before.\n<li>The sequence <em>%{ \u2026 %}<\/em> is <em>very<\/em> important as any output that does not advance the cursor should be contained within these. This allows <em>zsh<\/em> to count the number of visible characters within the prompt so that various screen operations happen in the right location. Judging by how often this is emphasised (and the fact that I made a mistake with it myself), it looks to be a very common problem.\n<li>The sequence <em>%{?.True.False%}<\/em> tests the exit status of the previous command and if true outputs the first string and if false outputs the second string.\n<li>The sequence at the end &#8211; <em>%B%n@%m\u00bb%b <\/em> &#8211; turns bold on (<em>%B<\/em>), outputs the username (<em>%n<\/em>), outputs an &#8220;@&#8221;, outputs the short machine name (<em>%m<\/em>), outputs a literal &#8220;\u00bb&#8221;, turns off cold (<em>%b<\/em>), and finally adds a space to the prompt.\n<\/ol>\n<p>\nPutting it all together, I get :-<\/p>\n<pre>\r\n# Now the prompt\r\nautoload -U colors && colors\r\n#       Enable colour variables (used in prompt)\r\nfancyterms=()\r\nfancyterms=(xterm xterms dtterm iris-ansi xterm-256color)\r\n#       An array of 'fancy' terminal types that we do more for \u2026 as in a funky PROMPT.\r\n\r\nif [[ ${fancyterms[(r)$TERM]} == \"$TERM\" ]] \r\nthen\r\n        precmd () { print -Pn '\\e]2;%n@%m - %~^G' }\r\n        # Put the hostname in the Window title\/Tab title\r\n        export PROMPT=\"%(?.%{$fg[green]%}\u2713 %{$reset_color%}.%{$fg[red]%}\u2717 %{$reset_color%})%B%n@%m\u00bb%b \"\r\n        # And set a really fancy prompt.\r\nelse\r\n        # If we don't recognise the terminal type, don't attempt to be quite so ambitious\r\n        # with the prompt.\r\n        export PROMPT=$'%B%n@%m - %~\\n%#%b '\r\nfi\r\n<\/pre>\n<p>This is still a little bit plain compared with what some people do with their prompts, but it is right for <em>me<\/em> (at least for now).<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u2026 or a red \u2717. Incidentally, if your browser doesn&#8217;t show ticks (\u2713), crosses (\u2717), and a right pointing double arrow (\u00bb) properly, this posting may look a bit odd. As in :- The aim here is to make the\u00a0zsh prompt (a Unix shell) start with a green \u2713 (tick) if the previous command&#8217;s exit <a href='https:\/\/really.zonky.org\/?p=3382' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false,"_share_on_mastodon":"0"},"categories":[4,226],"tags":[1214,1213,1212],"class_list":["post-3382","post","type-post","status-publish","format-standard","hentry","category-it","category-working-notes","tag-configuration","tag-prompt","tag-zsh","category-4-id","category-226-id","post-seq-1","post-parity-odd","meta-position-corners","fix"],"share_on_mastodon":{"url":"","error":""},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1f2KI-Sy","_links":{"self":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/3382","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3382"}],"version-history":[{"count":7,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/3382\/revisions"}],"predecessor-version":[{"id":3390,"href":"https:\/\/really.zonky.org\/index.php?rest_route=\/wp\/v2\/posts\/3382\/revisions\/3390"}],"wp:attachment":[{"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3382"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3382"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/really.zonky.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3382"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}