<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/vim/</id>
  <link href="https://www.endpointdev.com/blog/tags/vim/"/>
  <link href="https://www.endpointdev.com/blog/tags/vim/" rel="self"/>
  <updated>2022-05-30T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Aligning monospace font text columns with an old Unix tool</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/05/aligning-fixed-width-font-text-columns/"/>
      <id>https://www.endpointdev.com/blog/2022/05/aligning-fixed-width-font-text-columns/</id>
      <published>2022-05-30T00:00:00+00:00</published>
      <author>
        <name>Jon Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/05/aligning-fixed-width-font-text-columns/20220316_183928.webp&#34; alt=&#34;Photo of old wooden bridge with moss on it&#34;&gt;
Photo by Garrett Skinner&lt;/p&gt;
&lt;h3 id=&#34;a-blast-from-1990-column&#34;&gt;A blast from 1990: column&lt;/h3&gt;
&lt;p&gt;A while back I learned of a nice old Unix command-line tool called &lt;code&gt;column&lt;/code&gt;. It first appeared in 4.3BSD-Reno, released in July 1990. (This is not to be confused with the different, even older Unix tool &lt;code&gt;col&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;column&lt;/code&gt; formats plain text into nice columns based on the width of the input separated by tabs or groups of spaces.&lt;/p&gt;
&lt;p&gt;For example, take this mess found in a server&amp;rsquo;s &lt;code&gt;/etc/fstab&lt;/code&gt; file defining filesystem mount points. It is a real example lightly redacted to remove business details. You may need to scroll right to see the end of the fairly long lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/customer_uploads   /home/interch/htdocs/shared/customer_uploads none    rw,bind 0   0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/customer_images    /home/interch/htdocs/shared/customer_images  none    rw,bind 0   0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/images/items       home/interch/htdocs/images/items     none    rw,bind 0       0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/images/thumb       home/interch/htdocs/images/thumb     none    rw,bind 0       0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/upload_images       /home/interch/upload_images     none    rw,bind 0       0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/design    /home/interch/htdocs/shared/design  none    rw,bind 0   0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/design_temp   /home/interch/htdocs/shared/design_temp none    rw,bind 0   0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat1       /home/interch/htdocs/cat-numero-uno/images/reports     none    rw,bind 0       0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat2       /home/interch/htdocs/cat-zahl-zwei/images/reports     none    rw,bind 0       0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat3	/home/interch/htdocs/cat-number-three/images/reports	none	rw,bind	0	0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat4    /home/interch/htdocs/cat-quatre/images/reports     none    rw,bind 0       0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat5    /home/interch/htdocs/cat-pět/images/reports     none    rw,bind 0       0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/shared_var /home/interch/catalogs/shared/var none    rw,bind 0 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That is really unsightly and includes a mix of spaces and tabs.&lt;/p&gt;
&lt;p&gt;If we feed it to &lt;code&gt;column -t&lt;/code&gt; we get the same data aligned much nicer:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% column -t /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/customer_uploads  /home/interch/htdocs/shared/customer_uploads          none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/customer_images   /home/interch/htdocs/shared/customer_images           none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/images/items      home/interch/htdocs/images/items                      none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/images/thumb      home/interch/htdocs/images/thumb                      none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/upload_images     /home/interch/upload_images                           none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/design            /home/interch/htdocs/shared/design                    none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/design_temp       /home/interch/htdocs/shared/design_temp               none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat1      /home/interch/htdocs/cat-numero-uno/images/reports    none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat2      /home/interch/htdocs/cat-zahl-zwei/images/reports     none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat3      /home/interch/htdocs/cat-number-three/images/reports  none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat4      /home/interch/htdocs/cat-quatre/images/reports        none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/reports/cat5      /home/interch/htdocs/cat-pět/images/reports           none  rw,bind  0  0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/data3/shared_var        /home/interch/catalogs/shared/var                     none  rw,bind  0  0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That isn&amp;rsquo;t just prettier! It also makes some things stand out prominently at a glance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the second column there are two mount points not starting with &lt;code&gt;/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s easy to see that most of the paths in the second column start with &lt;code&gt;/home/interch/htdocs/&lt;/code&gt; and the few that don&amp;rsquo;t, stand out.&lt;/li&gt;
&lt;li&gt;The final 4 columns are all identical, which was unclear in the unaligned original.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;text-tables-to-json&#34;&gt;Text tables to JSON&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Util-linux&#34;&gt;util-linux&lt;/a&gt; version of &lt;code&gt;column&lt;/code&gt; includes extra options beyond the original. One very useful one is &lt;code&gt;-J&lt;/code&gt; or &lt;code&gt;--json&lt;/code&gt; which produces a JSON object for each row based on column names you define in the argument &lt;code&gt;-N&lt;/code&gt; or &lt;code&gt;--table-columns&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Reviewing &lt;a href=&#34;https://www.man7.org/linux/man-pages/man5/fstab.5.html&#34;&gt;&lt;code&gt;man fstab&lt;/code&gt;&lt;/a&gt; for details on what each column is used for in the sample above, we can instruct &lt;code&gt;column&lt;/code&gt; to produce JSON output like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% column -J -n fstab -N spec,file,vfstype,mntops,freq,passno /etc/fstab&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which gives us this result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;fstab&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/customer_uploads&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/shared/customer_uploads&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/customer_images&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/shared/customer_images&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/images/items&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;home/interch/htdocs/images/items&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/images/thumb&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;home/interch/htdocs/images/thumb&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/upload_images&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/upload_images&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/design&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/shared/design&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/design_temp&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/shared/design_temp&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/reports/cat1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/cat-numero-uno/images/reports&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/reports/cat2&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/cat-zahl-zwei/images/reports&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/reports/cat3&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/cat-number-three/images/reports&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/reports/cat4&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/cat-quatre/images/reports&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/reports/cat5&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/htdocs/cat-pět/images/reports&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;spec&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/data3/shared_var&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/interch/catalogs/shared/var&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;vfstype&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;mntops&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;rw,bind&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;freq&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         &lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;passno&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;JSON takes a lot more room, and of course is not the format Linux expects for this particular file, but transforming tabular data to JSON format in other situations can be more readable for exchange across different systems since each field is labeled, and unused fields can be omitted. Plus JSON syntax is rigorously defined, nested data structures are possible, etc.&lt;/p&gt;
&lt;h3 id=&#34;columnizing-lists&#34;&gt;Columnizing lists&lt;/h3&gt;
&lt;p&gt;All versions of &lt;code&gt;column&lt;/code&gt; can also columnize lists, either horizontally (across) or vertically (down). Take this list of people&amp;rsquo;s names:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Cameron
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Doug
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Emily
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Frank
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Jane
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Jill
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Jim
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Joe
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;John
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Karen
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Kate
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Liz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Mary
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Mike
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Steve
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Victoria&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Put that in file &lt;code&gt;/tmp/names&lt;/code&gt; and &lt;code&gt;column&lt;/code&gt; will format it in columns fitting the width of your terminal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% column /tmp/names
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy		Cameron		Jane		John		Mary		Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna		Doug		Jill		Karen		Mike
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob		Emily		Jim		Kate		Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda		Frank		Joe		Liz		Steve&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It uses 2 or more tab characters to separate the columns, based on standard terminal 8-space tab stops, so the above doesn&amp;rsquo;t look right here on the web.&lt;/p&gt;
&lt;p&gt;What appears in my terminal looks like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% column /tmp/names
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy             Cameron         Jane            John            Mary            Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna            Doug            Jill            Karen           Mike
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob             Emily           Jim             Kate            Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda          Frank           Joe             Liz             Steve&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or you can use &lt;code&gt;column -t&lt;/code&gt; that we discussed earlier to format the columns more compactly with spaces:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% column /tmp/names | column -t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy     Cameron  Jane  John   Mary   Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna    Doug     Jill  Karen  Mike   
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob     Emily    Jim   Kate   Sarah  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda  Frank    Joe   Liz    Steve  &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also ask for the list to be delivered horizontally, rather than vertically, with &lt;code&gt;column -x&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% column -x /tmp/names | column -t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy    Anna   Bob       Brenda  Cameron  Doug
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Emily  Frank  Jane      Jill    Jim      Joe
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;John   Karen  Kate      Liz     Mary     Mike
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sarah  Steve  Victoria                   &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that it isn&amp;rsquo;t doing anything to affect your ordering. You can order the lines in your original file however you want and it will preserve them. But other tools can help you here: Use &lt;code&gt;sort -u&lt;/code&gt; to sort alphabetically and remove duplicates.&lt;/p&gt;
&lt;p&gt;For more options and details see the &lt;code&gt;column&lt;/code&gt; man page for the &lt;a href=&#34;https://man7.org/linux/man-pages/man1/column.1.html&#34;&gt;util-linux column&lt;/a&gt; version or &lt;a href=&#34;https://www.freebsd.org/cgi/man.cgi?query=column&amp;amp;apropos=0&amp;amp;sektion=0&amp;amp;manpath=FreeBSD+13.1-RELEASE+and+Ports&amp;amp;arch=default&amp;amp;format=html&#34;&gt;FreeBSD column&lt;/a&gt; version (same as macOS).&lt;/p&gt;
&lt;h3 id=&#34;a-blast-from-1974-pr&#34;&gt;A blast from 1974: pr&lt;/h3&gt;
&lt;p&gt;There is an even older Unix tool for columnizing lists in the same way. It is called &lt;code&gt;pr&lt;/code&gt; and dates to First Edition Unix in 1971, but did not gain the options we are using here until Fifth Edition Unix in 1974 as seen in the &lt;a href=&#34;https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/man/man1/pr.1&#34;&gt;V6 pr man page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We need to tell it how many columns to produce, so we will ask for 6 columns as &lt;code&gt;column&lt;/code&gt; was doing above. Note that &lt;code&gt;pr&lt;/code&gt; emits a curious mix of tabs and spaces, which &lt;code&gt;cat -t&lt;/code&gt; reveals here as &lt;code&gt;^I&lt;/code&gt; (since a tab is the same thing as Control+I):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% pr -t -6 /tmp/names | cat -t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy^I    Cameron^IJane^I    John^ILiz^I    Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna^I    Doug^IJill^I    Karen^IMary^I    Steve
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob^I    Emily^IJim^I    Kate^IMike^I    Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda^I    Frank^IJoe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But in a terminal it looks fine:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% pr -t -6 /tmp/names
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy         Cameron     Jane        John        Liz         Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna        Doug        Jill        Karen       Mary        Steve
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob         Emily       Jim         Kate        Mike        Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda      Frank       Joe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;See the many more options of pr in the &lt;a href=&#34;https://man7.org/linux/man-pages/man1/pr.1.html&#34;&gt;GNU coreutils pr man page&lt;/a&gt; and &lt;a href=&#34;https://www.freebsd.org/cgi/man.cgi?query=pr&amp;amp;apropos=0&amp;amp;sektion=0&amp;amp;manpath=FreeBSD+13.1-RELEASE+and+Ports&amp;amp;arch=default&amp;amp;format=html&#34;&gt;FreeBSD pr man page&lt;/a&gt; (same as macOS).&lt;/p&gt;
&lt;h3 id=&#34;a-blast-from-1979-expand&#34;&gt;A blast from 1979: expand&lt;/h3&gt;
&lt;p&gt;A useful tool for dealing with tabs is &lt;code&gt;expand&lt;/code&gt;, which &lt;a href=&#34;https://github.com/dank101/3BSD/blob/master/cmd/expand.c&#34;&gt;first appeared in 3BSD&lt;/a&gt; in 1979. (Despite the FreeBSD and macOS man pages saying it appeared in 1BSD, I don&amp;rsquo;t see it there or in 2BSD.)&lt;/p&gt;
&lt;p&gt;We can use it to convert tabs to spaces just like a terminal would:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% pr -t -6 /tmp/names | expand | cat -t    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy         Cameron     Jane        John        Liz         Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna        Doug        Jill        Karen       Mary        Steve
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob         Emily       Jim         Kate        Mike        Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda      Frank       Joe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;expand&lt;/code&gt; accepts the optional &lt;code&gt;-t&lt;/code&gt; argument with a number to use as tabstop width instead of the default 8.&lt;/p&gt;
&lt;h3 id=&#34;and-unexpand&#34;&gt;And unexpand&lt;/h3&gt;
&lt;p&gt;I have used &lt;code&gt;expand&lt;/code&gt; for years, but only recently learned of &lt;code&gt;unexpand&lt;/code&gt; which goes the other way, converting runs of spaces into tabs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% pr -t -6 /tmp/names | expand | unexpand -a         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy         Cameron     Jane        John        Liz         Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna        Doug        Jill        Karen       Mary        Steve
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob         Emily       Jim         Kate        Mike        Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda      Frank       Joe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It looks fine in the terminal, but let&amp;rsquo;s see if it actually used tabs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% pr -t -6 /tmp/names | expand | unexpand -a | cat -t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy^I    Cameron^IJane^I    John^ILiz^I    Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna^I    Doug^IJill^I    Karen^IMary^I    Steve
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob^I    Emily^IJim^I    Kate^IMike^I    Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda^I    Frank^IJoe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Interesting… For some reason &lt;code&gt;unexpand&lt;/code&gt; doesn&amp;rsquo;t actually convert all the spaces to tabs, but just one initial tab per gutter between columns. Running the output through &lt;code&gt;unexpand -a&lt;/code&gt; again has no further effect. Strange.&lt;/p&gt;
&lt;p&gt;The GNU coreutils version of &lt;code&gt;unexpand&lt;/code&gt; that lives in most Linux systems is what I would call bug-compatible with the BSD version in this regard.&lt;/p&gt;
&lt;p&gt;Oh, well. There&amp;rsquo;s probably a reason.&lt;/p&gt;
&lt;p&gt;Since it has handled turning the initial tabstop&amp;rsquo;s varying number of spaces into a tab, we can easily remove the remaining fixed multiples of spaces on our own for a more compact list:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% pr -t -6 /tmp/names | expand | unexpand -a | sed &amp;#39;s/    //g&amp;#39;         
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Amy     Cameron Jane    John    Liz     Sarah
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Anna    Doug    Jill    Karen   Mary    Steve
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bob     Emily   Jim     Kate    Mike    Victoria
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Brenda  Frank   Joe&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;ready-at-hand&#34;&gt;Ready at hand&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;column&lt;/code&gt;, &lt;code&gt;pr&lt;/code&gt;, &lt;code&gt;expand&lt;/code&gt;, and &lt;code&gt;unexpand&lt;/code&gt; all come with most Linux and BSD systems, including macOS. It is amazing what great old tools are on many of our computers all the time, waiting to be used!&lt;/p&gt;
&lt;p&gt;You can use these programs as filters inside your favorite text editor or IDE. For example, to achieve the same list columnization as above you can select a block of text and send it to external commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Vim, visually select text with &lt;code&gt;v&lt;/code&gt; or &lt;code&gt;V&lt;/code&gt; and then type &lt;code&gt;!column | expand&lt;/code&gt; and press Enter.&lt;/li&gt;
&lt;li&gt;In VS Code you can install an extension called Filter Text (by yhirose). Once installed, type Control+K Control+F (⌘K ⌘F on macOS) and then &lt;code&gt;column | expand&lt;/code&gt; and Enter.&lt;/li&gt;
&lt;li&gt;In IntelliJ IDEA you can install a plugin called Shell Filter (by Dennis Plöger). Once installed, select your text, then choose menu item Edit &amp;gt; Custom Shell Filter and then type &lt;code&gt;column -c 80 | expand&lt;/code&gt; and Enter.&lt;/li&gt;
&lt;li&gt;Most other editors have a way to do this too. Search for &amp;ldquo;filter&amp;rdquo;, &amp;ldquo;pipe&amp;rdquo;, and/or &amp;ldquo;command&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your selection will be replaced by the output.&lt;/p&gt;
&lt;h3 id=&#34;unicode&#34;&gt;Unicode&lt;/h3&gt;
&lt;p&gt;These tools come from an era when one byte of input resulted in one visual character, so for any UTF-8 characters outside the limited classic ASCII character set, we could expect old tools may miscalculate the needed space between columns.&lt;/p&gt;
&lt;p&gt;Originally in my testing they appeared not to be aware of some Unicode characters’ width, perhaps due to combining characters or alternate forms. But surprisingly they have been modernized and seem to work fine with most Unicode characters such as Latin letters with diacritics, letters in other alphabets, Chinese characters, and even emoji! 😊&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>EditorConfig: Ending the Spaces vs. Tabs Confusion</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/04/editorconfig-ending-spaces-vs-tabs-confusion/"/>
      <id>https://www.endpointdev.com/blog/2022/04/editorconfig-ending-spaces-vs-tabs-confusion/</id>
      <published>2022-04-30T00:00:00+00:00</published>
      <author>
        <name>Jon Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/04/editorconfig-ending-spaces-vs-tabs-confusion/20220316_184133.webp&#34; alt=&#34;&#34;&gt;
Photo by Garrett Skinner&lt;/p&gt;
&lt;h3 id=&#34;varieties-of-text-formatting&#34;&gt;Varieties of text formatting&lt;/h3&gt;
&lt;p&gt;Most everyone who has worked on a software development project with a group of other people has encountered the problem of source code being formatted in different ways by different text editors, IDEs, and operating systems.&lt;/p&gt;
&lt;p&gt;The main variations go back to the 1970s or earlier, and include the questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Will indentation be done by tabs (an ASCII control character) or spaces?
&lt;ul&gt;
&lt;li&gt;If indentation is done by spaces, how many spaces are used for each indentation level?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What will indicate the end of each line (EOL)? The choices are:
&lt;ul&gt;
&lt;li&gt;a line feed (LF), used by the Unix family including Linux and modern macOS&lt;/li&gt;
&lt;li&gt;a carriage return (CR), used by old pre-Unix Macintosh and some now-obscure operating systems&lt;/li&gt;
&lt;li&gt;both together (CRLF) used by Windows and most Internet protocols&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Which character set encoding will be used? Common choices are:
&lt;ul&gt;
&lt;li&gt;Unicode UTF-8 encoding, used by Linux, macOS, and most other Unixes, and standard on the Internet&lt;/li&gt;
&lt;li&gt;Unicode UTF-16 encoding (with either little-endian or big-endian encoding), used by modern Windows&lt;/li&gt;
&lt;li&gt;legacy ISO-8859 and Windows &amp;ldquo;code page&amp;rdquo; encodings in older documents and codebases&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;editor-configurations-in-conflict&#34;&gt;Editor configurations in conflict&lt;/h3&gt;
&lt;p&gt;Causing widespread frustration, by default, text editors and IDEs generally are each configured differently, and once set, the choices apply broadly from then on. But each developer can simply configure their editor to follow their team&amp;rsquo;s standards, right? Well, maybe.&lt;/p&gt;
&lt;p&gt;First, getting that to happen for every developer and every different editor being used isn&amp;rsquo;t straightforward. It typically requires a document showing instructions and/or screenshots of how to configure each editor. It may have to be redone after a major upgrade or move to a new computer.&lt;/p&gt;
&lt;p&gt;Second, and often a more persistent problem, standards may vary across different projects and even for different types of files within a given project. Ruby code is typically indented with 2 spaces, while perhaps in your project JavaScript uses 4 spaces and HTML uses tabs.&lt;/p&gt;
&lt;p&gt;If you start a new project from scratch you can probably settle on a single standard, but in existing large codebases, it can make a lot of version control change &amp;ldquo;noise&amp;rdquo; to mess with that.&lt;/p&gt;
&lt;p&gt;Computers are good at keeping track of lots of little details, so isn&amp;rsquo;t there some way to have the computer deal with this?&lt;/p&gt;
&lt;h3 id=&#34;storing-configuration-in-the-project&#34;&gt;Storing configuration in the project&lt;/h3&gt;
&lt;p&gt;What if we store the text editor&amp;rsquo;s or IDE&amp;rsquo;s configuration in the project instead of per user, so it can go with the project to each new developer and tell their editor how to behave?&lt;/p&gt;
&lt;p&gt;For many years that has been possible with some editors, but the configuration had to be set up separately for each editor, and often the feature is disabled by default.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s consider the two most popular terminal-based editors on Unix, partisans in a long-running editor war:&lt;/p&gt;
&lt;h4 id=&#34;vim&#34;&gt;Vim&lt;/h4&gt;
&lt;p&gt;Vim has a feature called a &amp;ldquo;modeline&amp;rdquo; that allows for configuration settings to appear within the top or bottom 5 lines of the file.&lt;/p&gt;
&lt;p&gt;For example, to instruct Vim to use spaces instead of tabs and 4-space tab stops, we can add to the top or bottom of our C source code file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* vim: tabstop=4 shiftwidth=4 expandtab
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since it gets tedious putting those special configuration comments in each file, Vim has an option to read a &lt;code&gt;.vimrc&lt;/code&gt; file from the current directory, which applies to all files there and can be committed to version control.&lt;/p&gt;
&lt;p&gt;This feature is disabled by default because Vim has in the past been vulnerable to files with malicious settings running arbitrary code.&lt;/p&gt;
&lt;p&gt;You can &lt;code&gt;:set exrc secure&lt;/code&gt; to enable the modeline feature in a code base you trust, and also to restrict what it can do.&lt;/p&gt;
&lt;h4 id=&#34;emacs&#34;&gt;Emacs&lt;/h4&gt;
&lt;p&gt;In Emacs the same thing can be done on the first or second line of the file. (Of course its setting names differ from Vim&amp;rsquo;s.) For example consider this configuration in C source code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* -*- mode: c; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alternately you can use &amp;ldquo;Local Variables&amp;rdquo; set at the end of the file in as many lines as needed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* Local Variables:      */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* mode: c               */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* indent-tabs-mode: nil */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* c-basic-offset: 4     */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* tab-width: 4          */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;/* End:                  */&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Emacs also has &amp;ldquo;Directory Variables&amp;rdquo; that can be set in the file &lt;code&gt;.dir-locals.el&lt;/code&gt; for a directory and its subdirectories.&lt;/p&gt;
&lt;h4 id=&#34;others&#34;&gt;Others&lt;/h4&gt;
&lt;p&gt;Even if someone has gone to the trouble to set up such editor configuration files and add them to the project code repository, how often has that been done for your editor or IDE?&lt;/p&gt;
&lt;p&gt;And how often is one out of sync with the others?&lt;/p&gt;
&lt;p&gt;This is not the way to success.&lt;/p&gt;
&lt;h3 id=&#34;editorconfig-to-the-rescue&#34;&gt;EditorConfig to the rescue&lt;/h3&gt;
&lt;p&gt;About 10 years ago Trey Hunner and Hong Xu shared with the world EditorConfig, their creation to solve this problem across ideally all editors.&lt;/p&gt;
&lt;p&gt;They intentionally kept EditorConfig fairly limited in scope. It covers a limited number of the most important editor options so that the standard would be simple enough to be implemented for every editor either internally or as a plugin, and there would be no arbitrary code execution possible to cause security problems.&lt;/p&gt;
&lt;p&gt;In EditorConfig the configuration for our examples and hypotheticals above lives in a &lt;code&gt;.editorconfig&lt;/code&gt; file in the root of the project that looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# top-most EditorConfig file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;root&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# basics for all files in our project&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;[*]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;charset&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;utf-8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;end_of_line&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;lf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# C and JavaScript source get 4-space indents&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;[*.{c,js}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;indent_style&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;space&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;indent_size&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# Ruby gets 2-space indents&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;[*.rb]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;indent_style&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;space&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;indent_size&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# HTML gets tab indents&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;[*.html]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;indent_style&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;tab&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In a big project you may want to have separate, smaller &lt;code&gt;.editorconfig&lt;/code&gt; files in different directories. You can omit the &lt;code&gt;root = true&lt;/code&gt; setting in subdirectories to inherit settings from the top-level &lt;code&gt;.editorconfig&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;There are a couple of other options that are nice to specify.&lt;/p&gt;
&lt;p&gt;This one removes any tabs or spaces from the end of lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;trim_trailing_whitespace&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Those are rarely needed or semantically meaningful, so it&amp;rsquo;s nice to remove them. But there are a few cases where they can matter such as in Markdown.&lt;/p&gt;
&lt;p&gt;This one determines whether the last line in the file will end with a newline:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;insert_final_newline&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By default some editors add to the last line a newline (such as Vim) and some don&amp;rsquo;t (such as Emacs), leading to needless changes as various developers change files.&lt;/p&gt;
&lt;p&gt;Typically every line should end with a newline, so that&amp;rsquo;s a good editor feature to enable. But you could have some text template that should &lt;em&gt;not&lt;/em&gt; end with a newline, so might need to specify &lt;code&gt;false&lt;/code&gt; for that type of file.&lt;/p&gt;
&lt;p&gt;And those are most of the features of EditorConfig! &lt;a href=&#34;https://editorconfig.org/#file-format-details&#34;&gt;The file format details&lt;/a&gt; are easy to digest.&lt;/p&gt;
&lt;h3 id=&#34;editor--ide-support&#34;&gt;Editor &amp;amp; IDE support&lt;/h3&gt;
&lt;p&gt;EditorConfig is now widely supported. These popular editors &amp;amp; IDEs recognize &lt;code&gt;.editorconfig&lt;/code&gt; files with no extra work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IntelliJ IDEA and most of its language-specific variants&lt;/li&gt;
&lt;li&gt;GitHub&lt;/li&gt;
&lt;li&gt;GitLab&lt;/li&gt;
&lt;li&gt;Visual Studio&lt;/li&gt;
&lt;li&gt;BBEdit&lt;/li&gt;
&lt;li&gt;and others&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And these support it with a plugin:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VS Code&lt;/li&gt;
&lt;li&gt;Vim&lt;/li&gt;
&lt;li&gt;Emacs&lt;/li&gt;
&lt;li&gt;Sublime Text&lt;/li&gt;
&lt;li&gt;TextMate&lt;/li&gt;
&lt;li&gt;Eclipse&lt;/li&gt;
&lt;li&gt;Atom&lt;/li&gt;
&lt;li&gt;Notepad++&lt;/li&gt;
&lt;li&gt;Geany&lt;/li&gt;
&lt;li&gt;and others&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The plugins are typically easy to install system-wide from your operating system&amp;rsquo;s package manager, or else locally for your user only.&lt;/p&gt;
&lt;h3 id=&#34;do-you-need-it&#34;&gt;Do you need it?&lt;/h3&gt;
&lt;p&gt;Yes, I think you do.&lt;/p&gt;
&lt;p&gt;I know of no reason for any developer not to use EditorConfig, in every editor, for every project. It&amp;rsquo;s simple and at long last solves this small set of problems well.&lt;/p&gt;
&lt;p&gt;One possible counterargument: If, before every version control commit, you run an automatic code formatter such as Prettier (in Node.js, for many languages) or a language-specific one such as &lt;code&gt;gofmt&lt;/code&gt;, &lt;code&gt;rustfmt&lt;/code&gt;, etc., you could perhaps live without your editor knowing how your files should be saved.&lt;/p&gt;
&lt;p&gt;But isn&amp;rsquo;t it better if your editor knows what kind of line endings and indents to use, rather than waiting for a code formatter to correct such fundamental things after you save? It is easy to start with a single &lt;code&gt;.editorconfig&lt;/code&gt; file long before you have a continuous integration set up for the project.&lt;/p&gt;
&lt;p&gt;And many projects don&amp;rsquo;t format code automatically, and instead just &amp;ldquo;lint&amp;rdquo; it to report on deviations from the project standards. But that requires work to correct, and can be ignored if not enforced.&lt;/p&gt;
&lt;p&gt;Many &lt;a href=&#34;https://github.com/editorconfig/editorconfig/wiki/Projects-Using-EditorConfig&#34;&gt;open source projects large and small use EditorConfig&lt;/a&gt;, including this blog itself. But in recent months I have found several developers who had not yet heard of EditorConfig, so I want to spread awareness of it. I hope you&amp;rsquo;ll &lt;a href=&#34;https://editorconfig.org/&#34;&gt;use EditorConfig&lt;/a&gt; too!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Formatting SQL code with pgFormatter within Vim</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/04/formatting-sql-vim-pgformat/"/>
      <id>https://www.endpointdev.com/blog/2022/04/formatting-sql-vim-pgformat/</id>
      <published>2022-04-26T00:00:00+00:00</published>
      <author>
        <name>Josh Tolley</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/04/formatting-sql-vim-pgformat/20220411_091408.webp&#34; alt=&#34;Outdoor view of a creek bank with dry trees and old wooden buildings against a blue sky&#34;&gt;
Photo by Garrett Skinner&lt;/p&gt;
&lt;p&gt;Sometimes a little, seemingly simple tip can make a world of difference. I&amp;rsquo;ve got enough gray hair these days that it would be pretty easy for me to start thinking I&amp;rsquo;d seen an awful lot, yet quite frequently when I watch a colleague working in a meeting or a &lt;a href=&#34;https://github.com/tmux/tmux&#34;&gt;tmux&lt;/a&gt; session or somewhere, I learn some new and simple thing that makes my life demonstrably easier.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://fluca1978.github.io/2022/04/13/EmacsPgFormatter.html&#34;&gt;Luca Ferrari recently authored a post&lt;/a&gt; about using pgFormatter in Emacs; essentially the same thing works in Vim, my editor of choice, and it&amp;rsquo;s one of my favorite quick tips when working with complicated queries. I don&amp;rsquo;t especially want to get involved an editor war, and offer the following only in the spirit of friendly cooperation for the Vim users out there.&lt;/p&gt;
&lt;p&gt;As Luca mentioned, &lt;a href=&#34;https://github.com/darold/pgFormatter&#34;&gt;pgFormatter&lt;/a&gt; is a convenient way to make SQL queries readable, automatically. It&amp;rsquo;s easy enough to feed it some SQL, and get a nice-looking result as output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;$&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;pg_format&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;create_outbreaks.&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;sql&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;INSERT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;INTO&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;outbreak&lt;span style=&#34;color:#bbb&#34;&gt;                      
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;SELECT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                              
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;nextval(&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;outbreak_id&amp;#39;&lt;/span&gt;::regclass),&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;extract&lt;/span&gt;(&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;year&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;now())::&lt;span style=&#34;color:#038&#34;&gt;text&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;nextval(&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;outbreak_number_seq&amp;#39;&lt;/span&gt;)::&lt;span style=&#34;color:#038&#34;&gt;text&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;--number
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;                        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;SELECT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;first_name&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;person&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TABLESAMPLE&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BERNOULLI&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;10&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;LIMIT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#888&#34;&gt;-- name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;NOW()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#038&#34;&gt;interval&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;1 day&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;random()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;100&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;SELECT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;id&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TABLESAMPLE&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BERNOULLI&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;10&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In my perfect world I might quibble with some of its formatting decisions, such as the lack of indent on the &lt;code&gt;LIMIT 1&lt;/code&gt; line above. But in practice the results are good enough for my tastes that I haven&amp;rsquo;t bothered to investigate whether I can improve them. I just use it, and it&amp;rsquo;s good enough for me.&lt;/p&gt;
&lt;p&gt;And because Vim lets me highlight a region, pipe it through an external program, and replace the region with that program&amp;rsquo;s output, it&amp;rsquo;s easy to use it simply by selecting a section of code and typing &lt;code&gt;:!pg_format&lt;/code&gt; like this:&lt;/p&gt;
&lt;img src=&#34;/blog/2022/04/formatting-sql-vim-pgformat/sample.gif&#34; width=250 height=492 alt=&#34;pgformatter example animation of terminal&#34; /&gt;

      </content>
    </entry>
  
    <entry>
      <title>Linting Ruby In Your Editor</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2019/06/linting-ruby-in-your-editor/"/>
      <id>https://www.endpointdev.com/blog/2019/06/linting-ruby-in-your-editor/</id>
      <published>2019-06-27T00:00:00+00:00</published>
      <author>
        <name>Patrick Lewis</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2019/06/linting-ruby-in-your-editor/banner.jpg&#34; alt=&#34;Cotton&#34; /&gt; &lt;a href=&#34;https://flic.kr/p/azENYB&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/people/kimberlykv/&#34;&gt;Kimberly Vardeman&lt;/a&gt;, used under &lt;a href=&#34;https://creativecommons.org/licenses/by/2.0/&#34;&gt;CC BY 2.0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ruby developers have access to a variety of &lt;a href=&#34;https://en.wikipedia.org/wiki/Lint_(software)&#34;&gt;linters&lt;/a&gt; and &lt;a href=&#34;https://en.wikipedia.org/wiki/Static_program_analysis&#34;&gt;static program analysis&lt;/a&gt; tools that can greatly improve developer efficiency and code quality by catching syntax errors, detecting &lt;a href=&#34;https://en.wikipedia.org/wiki/Code_smell&#34;&gt;code smells&lt;/a&gt;, and making coding style suggestions based on popular style guides.&lt;/p&gt;
&lt;p&gt;I have been a long-time advocate of configuring development environments with automatic code linting and will use this post to highlight some of the available tools for Ruby and methods for integrating them with popular code editors (Vim, Emacs, and Visual Studio Code).&lt;/p&gt;
&lt;p&gt;Configuring your editor for automatic linting makes it much easier to identify and fix issues with your code at development time, and in-editor integration is very convenient for highlighting problems as you type (or save), making it easy to evaluate and improve the quality of your code as it is written.&lt;/p&gt;
&lt;p&gt;Three popular linting plugins/extensions for Vim, Visual Studio Code, and Emacs are:&lt;/p&gt;
&lt;h3 id=&#34;asynchronous-lint-engine-ale-plugin-for-vim&#34;&gt;&lt;a href=&#34;https://github.com/w0rp/ale&#34;&gt;Asynchronous Lint Engine (ALE)&lt;/a&gt; Plugin for Vim&lt;/h3&gt;
&lt;p&gt;Provides asynchronous linting in Vim while you edit, and displays warnings/error messages in the editor. Supports the following tools for Ruby development and runs them automatically if they are found in your PATH:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://brakemanscanner.org&#34;&gt;brakeman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/flyerhzm/rails_best_practices&#34;&gt;rails_best_practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/troessner/reek&#34;&gt;reek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rubocop-hq/rubocop&#34;&gt;rubocop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.ruby-lang.org/en/&#34;&gt;ruby -wc&lt;/a&gt; (verbose syntax check)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ruby-formatter/rufo&#34;&gt;rufo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://solargraph.org&#34;&gt;solargraph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/testdouble/standard&#34;&gt;standardrb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ruby-extension-for-visual-studio-code&#34;&gt;&lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby#linters&#34;&gt;Ruby&lt;/a&gt; Extension for Visual Studio Code&lt;/h3&gt;
&lt;p&gt;Requires configuring the settings JSON file to enable each tool on an individual basis:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;// Basic settings: turn linter(s) on
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;ruby.lint&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;reek&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;rubocop&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;ruby&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;true&lt;/span&gt;, &lt;span style=&#34;color:#888&#34;&gt;//Runs ruby -wc
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;fasterer&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;debride&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#b06;font-weight:bold&#34;&gt;&amp;#34;ruby-lint&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/seattlerb/debride&#34;&gt;debride&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/DamirSvrtan/fasterer&#34;&gt;fasterer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/troessner/reek&#34;&gt;reek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rubocop-hq/rubocop&#34;&gt;rubocop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.ruby-lang.org/en/&#34;&gt;ruby -wc&lt;/a&gt; (verbose syntax check)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/yorickpeterse/ruby-lint&#34;&gt;ruby-lint&lt;/a&gt; (unmaintained)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;flycheck-extension-for-emacs&#34;&gt;&lt;a href=&#34;https://www.flycheck.org/en/latest/&#34;&gt;Flycheck&lt;/a&gt; Extension for Emacs&lt;/h3&gt;
&lt;p&gt;Detects and uses the following tools when editing Ruby code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/troessner/reek&#34;&gt;reek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rubocop-hq/rubocop&#34;&gt;rubocop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.ruby-lang.org/en/&#34;&gt;ruby -wc&lt;/a&gt; (verbose syntax check)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/yorickpeterse/ruby-lint&#34;&gt;ruby-lint&lt;/a&gt; (unmaintained)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;linter-selection&#34;&gt;Linter Selection&lt;/h3&gt;
&lt;p&gt;I suggest starting small and only installing one or two linters to begin with; some choices provide similar features and will display conflicting or redundant warnings/errors if used at the same time. I think that &lt;a href=&#34;https://github.com/rubocop-hq/rubocop&#34;&gt;RuboCop&lt;/a&gt; is a great first choice, and I have spent years using it as my primary linter, though recently I have started supplementing it with &lt;a href=&#34;https://github.com/troessner/reek&#34;&gt;Reek&lt;/a&gt; and &lt;a href=&#34;https://github.com/DamirSvrtan/fasterer&#34;&gt;Fasterer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I highly recommend the use of these tools and consider them essential for any Ruby developer that is interested in improving the quality, reliability, and maintainability of their code.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Vim Golf: Learning New Skills for Code Editors</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2016/11/vim-golf-learning-new-skills-for-code/"/>
      <id>https://www.endpointdev.com/blog/2016/11/vim-golf-learning-new-skills-for-code/</id>
      <published>2016-11-28T00:00:00+00:00</published>
      <author>
        <name>Josh Lavin</name>
      </author>
      <content type="html">
        &lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/File:Vimlogo.svg&#34; imageanchor=&#34;1&#34; style=&#34;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;&lt;img border=&#34;0&#34; height=&#34;240&#34; src=&#34;/blog/2016/11/vim-golf-learning-new-skills-for-code/image-0.png&#34; width=&#34;240&#34;/&gt;&lt;br/&gt;&lt;small&gt;Vim logo freely licensed from Wikimedia Commons&lt;/small&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&#34;http://www.vim.org/about.php&#34;&gt;Vim&lt;/a&gt; is a text-based editor that has been around for 25 years. It comes pre-installed on Linux distributions, so it is a great tool for developing on servers. One of the advantages of Vim is that oft-used keystrokes can be performed without moving your hands from the keyboard (there is no mouse in Vim).&lt;/p&gt;
&lt;p&gt;Many of the engineers here at End Point use Vim for our daily development work, and recently, a few of us got together online to try to learn some new tricks and tips from each other. Being efficient with Vim not only improves productivity, it’s a lot of fun.&lt;/p&gt;
&lt;p&gt;Similar to playing a round of golf, we tested each other with various editing tasks, to see who could perform the task in the fewest number of keystrokes. This is known as “Vim Golf.” There is even an &lt;a href=&#34;http://vimgolf.com/&#34;&gt;entire website&lt;/a&gt; devoted to this.&lt;/p&gt;
&lt;p&gt;In this post, we share some of the interesting tricks that were shown, and also some links to further learning about Vim.&lt;/p&gt;
&lt;h3 id=&#34;tips--tricks&#34;&gt;Tips &amp;amp; Tricks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Indenting text: there are multiple ways to do this, but a few are:
&lt;ul&gt;
&lt;li&gt;Visually-select the lines of text to indent (Ctrl v or Shift v), then &amp;gt; to indent, or &amp;lt; to outdent. Press . to perform this action again and again.&lt;/li&gt;
&lt;li&gt;Locate the line numbers for the lines you wish to change (:set number to turn on line numbering), then :17,36&amp;raquo; to indent lines 17-36 two indentation levels.&lt;/li&gt;
&lt;li&gt;Define width of a tab :set tabstop=4 would for example set a tab to 4 spaces.&lt;/li&gt;
&lt;li&gt;Use spaces defined in tabstop instead of an actual tab character (^I) when the Tab key is pressed :set expandtab or :set et&lt;/li&gt;
&lt;li&gt;Replace tab settings for current line :retab&lt;/li&gt;
&lt;li&gt;Replace tab settings for current document :retab!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Visually-selecting text: Ctrl v will perform a visual column selection, while Shift v will do a row selection.&lt;/li&gt;
&lt;li&gt;:set will show all the currently-set options.&lt;/li&gt;
&lt;li&gt;For paging up or down, use Ctrl b and Ctrl f. You can also use PgUp and PgDn keys if you want to move your hands a bit :-)&lt;/li&gt;
&lt;li&gt;Moving the cursor around the page:
&lt;ul&gt;
&lt;li&gt;Type M  to move the cursor to the &lt;strong&gt;middle&lt;/strong&gt; of the screen&lt;/li&gt;
&lt;li&gt;Type H  to move the cursor to the &lt;strong&gt;top&lt;/strong&gt; of the screen&lt;/li&gt;
&lt;li&gt;Type L  to move the cursor to the &lt;strong&gt;bottom&lt;/strong&gt; of the screen&lt;/li&gt;
&lt;li&gt;Type gg to move the cursor to the &lt;strong&gt;top&lt;/strong&gt; of the document&lt;/li&gt;
&lt;li&gt;Type G  to move the cursor to the &lt;strong&gt;bottom&lt;/strong&gt; of the document&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Moving the &lt;em&gt;page&lt;/em&gt; around the cursor:
&lt;ul&gt;
&lt;li&gt;Type zz to make the current position float to the &lt;strong&gt;middle&lt;/strong&gt; of the screen&lt;/li&gt;
&lt;li&gt;Type zt to make the current position float to the &lt;strong&gt;top&lt;/strong&gt; of the screen&lt;/li&gt;
&lt;li&gt;Type zb to make the current position float to the &lt;strong&gt;bottom&lt;/strong&gt; of the screen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Search and replace:
&lt;ul&gt;
&lt;li&gt;Find and replace all instances of a string: %s/find_this/replace_with_this/g&lt;/li&gt;
&lt;li&gt;Case-insensitive find and replace all instances of a string: %s/find_this/replace_with_this/gi&lt;/li&gt;
&lt;li&gt;Find then ask confirmation before replacing: %s/find_this/replace_with_this/c&lt;/li&gt;
&lt;li&gt;Search history: Vim maintains search history which is easy to access using / or ? then navigation through the list using the up and down arrows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Deleting from the current position to the bottom of the file: dG&lt;/li&gt;
&lt;li&gt;Jumping to the first position in the current line: 0&lt;/li&gt;
&lt;li&gt;Find the next occurrence of a character in the current line: f then the character. To search backwards, use F&lt;/li&gt;
&lt;li&gt;Undo a command: u (run this multiple times for additional undo steps)&lt;/li&gt;
&lt;li&gt;Redo your undo: Ctrl r&lt;/li&gt;
&lt;li&gt;Travel back in time to see the document as it was 30 mins ago :earlier 30m then revert with :later 30m&lt;/li&gt;
&lt;li&gt;Reselect the last visual selection gv&lt;/li&gt;
&lt;li&gt;Run a system command from within Vim :! [command]&lt;/li&gt;
&lt;li&gt;Review your previous vim command history q:&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;for-further-learning&#34;&gt;For Further Learning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Built-in Vim help: use :h name_of_command_or_setting (e.g. :h f)&lt;/li&gt;
&lt;li&gt;View manpage for the word under the cursor: K&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html&#34;&gt;Cheat sheets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.briefs.fm/vim-tips-with-ben&#34;&gt;Vim Tips with Ben&lt;/a&gt; podcast&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://vimcasts.org/&#34;&gt;Vimcasts&lt;/a&gt; — free screencasts&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/MasteringVim/&#34;&gt;Tweets from Mastering Vim&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;With contributions from &lt;a href=&#34;/blog/authors/sam-batschelet/&#34;&gt;Sam Batschelet&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Report on The Perl Conference 2016</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2016/07/report-on-perl-conference-2016/"/>
      <id>https://www.endpointdev.com/blog/2016/07/report-on-perl-conference-2016/</id>
      <published>2016-07-27T00:00:00+00:00</published>
      <author>
        <name>Josh Lavin</name>
      </author>
      <content type="html">
        &lt;p&gt;In June, I traveled to Orlando, Florida to attend the event formerly known as &lt;em&gt;Yet Another Perl Conference&lt;/em&gt; (or YAPC::NA), now known as &lt;a href=&#34;http://www.yapcna.org/yn2016/&#34;&gt;The Perl Conference&lt;/a&gt;. This was my second time in a row to attend this conference (after my first attendance back in 2007).&lt;/p&gt;
&lt;p&gt;Conferences are a great place to learn how others are using various tools, hear about new features, and interact with the community. If you are speaking, it’s a great opportunity to brush up on your subject, which was true for me in the extreme, as I was able to give a talk on the PostgreSQL database, which I hadn’t used in a long time (more on that later).&lt;/p&gt;
&lt;h3 id=&#34;the-conference-name&#34;&gt;The conference name&lt;/h3&gt;
&lt;p&gt;The event organizers were able to license the name &lt;em&gt;The Perl Conference&lt;/em&gt; from O’Reilly Media, as O’Reilly doesn’t hold conferences by this name anymore. This name is now preferred over “YAPC” as it is more friendly to newcomers and more accurately describes the conference. &lt;a href=&#34;http://www.yapcna.org/yn2016/news/1397&#34;&gt;More on the name change.&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;notes-from-the-conference&#34;&gt;Notes from the conference&lt;/h3&gt;
&lt;p&gt;Over the three days of the conference, I was able to take in many talks. Here are some of my more interesting notes from various sessions:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both;&#34;&gt;
&lt;blockquote class=&#34;twitter-tweet&#34; data-lang=&#34;en&#34; style=&#34;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;
    &lt;p dir=&#34;ltr&#34; lang=&#34;en&#34;&gt;
        Yes, this is happening &lt;a href=&#34;https://twitter.com/YAPCNA&#34;&gt;@YAPCNA&lt;/a&gt;
        &lt;br/&gt;
        &lt;a href=&#34;https://twitter.com/JayceHall/status/745616157768482816&#34;&gt;&lt;img border=&#34;0&#34; height=&#34;256&#34; src=&#34;/blog/2016/07/report-on-perl-conference-2016/image-0.jpeg&#34; width=&#34;320&#34;/&gt;&lt;/a&gt;
    &lt;/p&gt;
    &lt;cite style=&#34;float:right&#34;&gt;— Jason Hall (@JayceHall) &lt;a href=&#34;https://twitter.com/JayceHall/status/745616157768482816&#34;&gt;June 22, 2016&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/&#34;&gt;MetaCPAN&lt;/a&gt; is the best way to browse and search for Perl modules. Anyone can help with development of this fine project, via &lt;a href=&#34;https://github.com/metacpan/metacpan-web&#34;&gt;their GitHub&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://metacpan.org/author/RJBS&#34;&gt;Ricardo Signes&lt;/a&gt; says “use &lt;a href=&#34;http://perldoc.perl.org/perlsub.html#Signatures&#34;&gt;subroutine signatures&lt;/a&gt;!” They are “experimental”, but are around to stay.&lt;/li&gt;
&lt;li&gt;Perl6 is written in Perl6 (and something called “&lt;a href=&#34;https://github.com/perl6/nqp&#34;&gt;Not Quite Perl&lt;/a&gt;”). This allows one to read the source to figure out how something is done. &lt;em&gt;(There were many talks on Perl6, which is viewed as a different programming language, not a replacement for Perl5.)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://stedolan.github.io/jq/&#34;&gt;jq&lt;/a&gt; is a command-line utility that can pretty-print JSON (non Perl, but nice!)&lt;/li&gt;
&lt;li&gt;Ricardo Signes gave a &lt;a href=&#34;https://www.youtube.com/watch?v=TmTeXcEixEg&#34;&gt;talk on encoding&lt;/a&gt; that was over my head, but very interesting.&lt;/li&gt;
&lt;li&gt;The presenter of &lt;em&gt;Emacs as Perl IDE&lt;/em&gt; couldn’t attend, so Damian Conway spoke on &lt;a href=&#34;https://www.youtube.com/watch?v=9u6O0dLuqhI&#34;&gt;VIM as Perl IDE&lt;/a&gt; (photo above)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From &lt;a href=&#34;http://www.yapcna.org/yn2016/talk/6599&#34;&gt;John Anderson’s talk&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Just say “no” to system Perl. Use &lt;a href=&#34;https://github.com/tokuhirom/plenv&#34;&gt;plenv&lt;/a&gt; or the like.&lt;/li&gt;
&lt;li&gt;There’s a DuckDuckGo &lt;a href=&#34;https://duckduckgo.com/bang&#34;&gt;bang command&lt;/a&gt; for searching MetaCPAN: !cpan [module]&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&#34;https://metacpan.org/pod/JSON::MaybeXS&#34;&gt;JSON::MaybeXS&lt;/a&gt; over the plain JSON module.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&#34;https://metacpan.org/pod/Moo&#34;&gt;Moo&lt;/a&gt; for object-oriented programming in Perl, or Moose if you must.&lt;/li&gt;
&lt;li&gt;Subscribe to &lt;a href=&#34;http://perlweekly.com/&#34;&gt;Perl Weekly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Submit your module on &lt;a href=&#34;http://prepan.org/&#34;&gt;PrePAN&lt;/a&gt; first, to receive feedback before posting to CPAN.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lee Johnson gave a talk called &lt;a href=&#34;http://www.yapcna.org/yn2016/talk/6545&#34;&gt;Battling a legacy schema with DBIx::Class&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=ltckzIJYwHg&#34;&gt;video&lt;/a&gt;). Key takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://programmers.stackexchange.com/questions/304520/when-should-i-use-perls-dbixclass/304557#304557&#34;&gt;When should I use DBIC?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Something that has grown organically could be considered “legacy,” as it accumulates &lt;a href=&#34;https://en.wikipedia.org/wiki/Technical_debt&#34;&gt;technical debt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;With &lt;a href=&#34;https://metacpan.org/pod/DBIx::Class&#34;&gt;DBIC&lt;/a&gt;, you can start to manage that debt by adding relationships to your model, even if they aren’t in your database&lt;/li&gt;
&lt;li&gt;RapidApp’s &lt;a href=&#34;https://metacpan.org/pod/Plack::App::RapidApp::rDbic&#34;&gt;rdbic&lt;/a&gt; can help you visualize an existing database&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=EXPElOT2fRE&#34;&gt;D. Ruth Bavousett spoke&lt;/a&gt; on &lt;a href=&#34;https://metacpan.org/pod/Perl::Critic&#34;&gt;Perl::Critic&lt;/a&gt;, which is a tool for encouraging consistency. Basically, Perl::Critic looks at your source code, and makes suggestions for improvement, etc. These suggestions are known as “policies” and can be configured to enable or disable any of them, or to even write new policies. One suggestion was to create a &lt;a href=&#34;https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks&#34;&gt;Git hook&lt;/a&gt; to run the perlcritic command at the time code is committed to the source code repository (possibly using &lt;a href=&#34;https://metacpan.org/pod/App::GitHooks&#34;&gt;App::GitHooks&lt;/a&gt;). End Point has its own perlcritic configuration, which I have started trying to use more.&lt;/p&gt;
&lt;p&gt;Logan Bell shared &lt;a href=&#34;https://www.youtube.com/watch?v=uW4UX8UBAjg&#34;&gt;Strategies for leading a remote team&lt;/a&gt;. Some of the tools and techniques he uses include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://tmate.io/&#34;&gt;tmate&lt;/a&gt; for terminal sharing&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.hipchat.com/&#34;&gt;HipChat&lt;/a&gt;, with a chat room just for complaining called “head to desk”&lt;/li&gt;
&lt;li&gt;Holds one-on-one meetings every Monday for those he works with and directs&lt;/li&gt;
&lt;li&gt;Has new team members work on-site with another team member their first week or so, to help understand personalities that don’t often come across well over chat&lt;/li&gt;
&lt;li&gt;Tries to have in-person meetings every quarter or at least twice a year, to bring the team together&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;my-talk&#34;&gt;My talk&lt;/h3&gt;
&lt;p&gt;Finally, my own talk was titled &lt;a href=&#34;http://www.yapcna.org/yn2016/talk/6631&#34;&gt;Stranger in a Strange Land: PostgreSQL for MySQL users&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=sH41r_MOSH0&#34;&gt;video&lt;/a&gt;). I hadn’t used Postgres in about seven years, and I wanted to get re-acquainted with it, so naturally, I submitted a talk on it to spur myself into action!&lt;/p&gt;
&lt;p&gt;In my talk, I covered:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the history of MySQL and Postgres&lt;/li&gt;
&lt;li&gt;how to pronounce “PostgreSQL”&lt;/li&gt;
&lt;li&gt;why one might be preferred over the other&lt;/li&gt;
&lt;li&gt;how to convert an existing database to Postgres&lt;/li&gt;
&lt;li&gt;and some tools and tips.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I enjoyed giving this talk, and hope others found it helpful. All in all, The Perl Conference was a great experience, and I hope to continue attending in the future!&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/user/yapcna/search?query=2016&#34;&gt;All videos from this year’s conference&lt;/a&gt;&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Vim Plugin Spotlight: CtrlP</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2015/02/vim-plugin-spotlight-ctrlp/"/>
      <id>https://www.endpointdev.com/blog/2015/02/vim-plugin-spotlight-ctrlp/</id>
      <published>2015-02-06T00:00:00+00:00</published>
      <author>
        <name>Patrick Lewis</name>
      </author>
      <content type="html">
        &lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;&lt;a href=&#34;/blog/2015/02/vim-plugin-spotlight-ctrlp/image-0.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/02/vim-plugin-spotlight-ctrlp/image-0.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;When I started using Vim I relied on tree-based file browsers like netrw and NerdTree for navigating a project’s files within the editor. After discovering and trying the &lt;a href=&#34;https://github.com/ctrlpvim/ctrlp.vim&#34;&gt;CtrlP&lt;/a&gt; plugin for Vim I found that jumping directly to a file based on its path and/or filename could be faster than drilling down through a project’s directories one at a time before locating the one containing the file I was looking for.&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;&lt;a href=&#34;/blog/2015/02/vim-plugin-spotlight-ctrlp/image-1.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/02/vim-plugin-spotlight-ctrlp/image-1.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;After it’s invoked (usually by a keyboard shortcut) CtrlP will display a list of files in your current project and will filter that list on the fly based on your text input, matching it against both directory names and file names. Pressing &lt;control-f&gt; with CtrlP open toggles through two other modes: most recently used files, and current buffers. This is useful when you want to narrow down the list of potential matches to only files you have worked with recently or currently have open in other buffers. I use CtrlP’s buffer mode to jump between open files so often that I added a custom mapping to invoke it in my .vimrc file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;map &amp;lt;leader&amp;gt;b :CtrlPBuffer&amp;lt;cr&amp;gt;&amp;lt;/cr&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;CtrlP has many configuration options that can affect its performance and behavior, and installing additional plugins can provide different matcher engines that search through a directory more quickly and return more relevant results than the default matcher. Alternate matchers I’ve found include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/burke/matcher&#34;&gt;https://github.com/burke/matcher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/JazzCore/ctrlp-cmatcher&#34;&gt;https://github.com/JazzCore/ctrlp-cmatcher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/FelikZ/ctrlp-py-matcher&#34;&gt;https://github.com/FelikZ/ctrlp-py-matcher&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of these, I’ve had the best luck with FelixZ’s &lt;a href=&#34;https://github.com/FelikZ/ctrlp-py-matcher&#34;&gt;ctrlp-py-matcher&lt;/a&gt;. It’s easy to install, works on most systems without requiring additional dependencies, and manages to be both faster and return more relevant results than the built-in CtrlP matcher.&lt;/p&gt;
&lt;p&gt;CtrlP is well documented in both its README (available on its &lt;a href=&#34;https://github.com/ctrlpvim/ctrlp.vim&#34;&gt;GitHub project page&lt;/a&gt;) and its Vim documentation (available with &lt;strong&gt;:help ctrlp&lt;/strong&gt; within Vim). The documentation covers the different commands and configuration options provided by CtrlP but simply installing the plugin and hitting &lt;control-p&gt; on your keyboard is enough to get you started with a faster way to navigate between files in any codebase.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>vim-airline: A lightweight status/tabline for Vim</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2014/06/vim-airline-lightweight-statustabline/"/>
      <id>https://www.endpointdev.com/blog/2014/06/vim-airline-lightweight-statustabline/</id>
      <published>2014-06-02T00:00:00+00:00</published>
      <author>
        <name>Patrick Lewis</name>
      </author>
      <content type="html">
        &lt;p&gt;My standard Vim configuration makes use of around 30 different plugins and I consider &lt;a href=&#34;https://github.com/bling/vim-airline&#34;&gt;vim-airline&lt;/a&gt; to be one of the most indispensable because of its built-in functionality and superb integration with a variety of other Vim plugins. It’s a great starting point for anyone looking to extend their Vim setup with additional plugins.&lt;/p&gt;
&lt;p&gt;I became interested in vim-airline the first time I saw screenshots of it; the color schemes, custom glyphs&lt;a href=&#34;#footnote1&#34;&gt;[1]&lt;/a&gt; and indicators immediately revealed value beyond the basic status bar that a stock Vim installation provides. After installing and spending some time using vim-airline I discovered additional benefits due to its integration with other plugins such as &lt;a href=&#34;https://github.com/tpope/vim-fugitive&#34;&gt;Fugitive&lt;/a&gt;, &lt;a href=&#34;https://github.com/scrooloose/syntastic&#34;&gt;Syntastic&lt;/a&gt; and &lt;a href=&#34;https://github.com/kien/ctrlp.vim&#34;&gt;CtrlP&lt;/a&gt;. vim-airline provides a common platform for integrating the display indicators of plugins from various authors into one view and presents them all with consistent a consistent style.&lt;/p&gt;
&lt;p&gt;A quick comparison of Vim with vim-airline installed:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;&lt;a href=&#34;/blog/2014/06/vim-airline-lightweight-statustabline/image-0.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2014/06/vim-airline-lightweight-statustabline/image-0.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;vs. a standard Vim installation:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;&lt;a href=&#34;/blog/2014/06/vim-airline-lightweight-statustabline/image-1.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2014/06/vim-airline-lightweight-statustabline/image-1.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;reveals new indicators for the current Vim mode, git branch, open buffers, and line endings. Integrating other plugins can add additional indicators for syntax errors, trailing whitespace, and more.&lt;/p&gt;
&lt;p&gt;Using vim-airline also helped me adopt the usage of built-in Vim functionality that I had previously overlooked. I had not used Vim’s tab features, favoring a single split window, but after enabling vim-airline’s tabline feature I am now in the habit of using a combination of tabs and split windows to organize my workspace and have found that I am more easily able to keep track of multiple files at a time.&lt;/p&gt;
&lt;p&gt;I recommend reading through the documentation for vim-airline, trying it out and then installing some of the &lt;a href=&#34;https://github.com/bling/vim-airline#seamless-integration&#34;&gt;other plugins&lt;/a&gt; that it integrates with in order to develop your own preferred set of Vim plugins. I spend most of my workday in a Vim session and consider it a good investment to research different plugins and features that can increase productivity and developer happiness.&lt;/p&gt;
&lt;p&gt;&lt;a id=&#34;footnote1&#34;&gt;[1]&lt;/a&gt; Note that some of the nice-looking but non-standard characters available in vim-airline require the use of a patched font; pre-patched versions of many popular monospaced fonts are available in the &lt;a href=&#34;https://github.com/Lokaltog/powerline-fonts&#34;&gt;powerline-fonts&lt;/a&gt; repository on GitHub and are easy to install (I’m a fan of Adobe’s Source Code Pro font).&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Highlighting Search Pattern Matches in Vim</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2013/12/highlighting-search-pattern-matches-in/"/>
      <id>https://www.endpointdev.com/blog/2013/12/highlighting-search-pattern-matches-in/</id>
      <published>2013-12-30T00:00:00+00:00</published>
      <author>
        <name>Patrick Lewis</name>
      </author>
      <content type="html">
        &lt;p&gt;Vim’s &lt;strong&gt;hlsearch&lt;/strong&gt; option is a commonly-used way to enable visual feedback when searching for patterns in a Vim buffer. When highlighting of search matches is enabled (via &lt;strong&gt;:set hlsearch&lt;/strong&gt;), Vim will add a colored background to all text matching the current search.&lt;/p&gt;
&lt;p&gt;Search highlighting is useful but it’s not obvious how to turn off the highlighting when you’re no longer concerned with the results of your last search. This is particularly true if you didn’t enable the &lt;strong&gt;hlsearch&lt;/strong&gt; setting yourself but inherited it from a prebuilt package like &lt;a href=&#34;https://github.com/carlhuda/janus&#34;&gt;Janus&lt;/a&gt; or copied someone else’s .vimrc file.&lt;/p&gt;
&lt;p&gt;One commonly-used way to clear the highlighting is to search for a garbage string by doing something like &lt;strong&gt;/asdfkj&lt;/strong&gt; in normal mode. This method will clear the search highlights but has the undesired side effect of altering your search history.&lt;/p&gt;
&lt;p&gt;A better way to disable search highlighting temporarily is with the &lt;strong&gt;:nohlsearch&lt;/strong&gt; command (which can be abbreviated to &lt;strong&gt;:noh&lt;/strong&gt;). This will clear the highlights temporarily, but they’ll be turned back on the next time you perform a search. Also, you can use the n/N keys to resume your previous search, which isn’t possible if you use the above method of searching for a garbage string.&lt;/p&gt;
&lt;p&gt;For more information on highlighting search matches in Vim, check out the &lt;a href=&#34;http://vim.wikia.com/wiki/VimTip14&#34;&gt;Highlight all search pattern matches&lt;/a&gt; entry on the Vim Tips Wiki.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Vim tabs and splits</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2013/07/vim-tabs-and-splits/"/>
      <id>https://www.endpointdev.com/blog/2013/07/vim-tabs-and-splits/</id>
      <published>2013-07-15T00:00:00+00:00</published>
      <author>
        <name>Mike Farmer</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;a href=&#34;http://www.vim.org/&#34;&gt;Vim&lt;/a&gt; is my go-to code editor these days. After many years of using different editors, I’ve settled on Vim as my editor of choice. There are some things I’ve done to make using Vim more enjoyable and usable and this blog post is dedicated to some of those things that I use everyday.&lt;/p&gt;
&lt;h3 id=&#34;tabs&#34;&gt;Tabs&lt;/h3&gt;
&lt;p&gt;I love using tabs in Vim. I know there are some who are opposed to tabs, but I find them invaluable. The default shortcuts for manipulating tabs are a little cumbersome, which I believe deters many users. Here are some modifications that I added to my &lt;a href=&#34;https://github.com/mikefarmer/dotfiles/blob/master/vimrc&#34;&gt;vimrc&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmap &amp;lt;silent&amp;gt; tt :tabnew&amp;lt;CR&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmap &amp;lt;silent&amp;gt; [g :tabprevious&amp;lt;CR&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmap &amp;lt;silent&amp;gt; ]g :tabnext&amp;lt;CR&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmap &amp;lt;silent&amp;gt; [G :tabrewind&amp;lt;CR&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmap &amp;lt;silent&amp;gt; ]G :tablast&amp;lt;CR&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First, I’m using nmap here which says to only map these keys in normal mode. Next, I use &lt;silent&gt; which keeps my editor clean of any distractions while performing the task. I find that the double tap short-cuts (see more below) &lt;code&gt;tt&lt;/code&gt; work really well for normal mode and I love their simplicity. Double-tap t and you have a new tab. Using the bracket navigation is something that I’ve stolen from &lt;a href=&#34;https://github.com/tpope&#34;&gt;Tim Pope’s&lt;/a&gt; &lt;a href=&#34;https://github.com/tpope/vim-unimpaired&#34;&gt;vim-unimpaired&lt;/a&gt; plugin. Using g and G work for me, but you can use whatever you like.&lt;/p&gt;
&lt;h3 id=&#34;splits&#34;&gt;Splits&lt;/h3&gt;
&lt;p&gt;I believe most Vim users use splits often. At first, I found that splitting my current buffer was also cumbersome using the default method in Vim (:split and :vsplit). So utilizing the double-tap method I used for tabs, I created my own shortcuts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmap &amp;lt;silent&amp;gt; vv :vsp&amp;lt;CR&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nmap &amp;lt;silent&amp;gt; ss :sp&amp;lt;CR&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you have a split, navigating between them can be a little bit of a pain as well. Here’s my optimization:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;map &amp;lt;C-h&amp;gt; &amp;lt;C-w&amp;gt;h
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;map &amp;lt;C-j&amp;gt; &amp;lt;C-w&amp;gt;j
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;map &amp;lt;C-k&amp;gt; &amp;lt;C-w&amp;gt;k
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;map &amp;lt;C-l&amp;gt; &amp;lt;C-w&amp;gt;l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After using Vim’s splitting capability for a while, I noticed I didn’t always like where the split occurred. Sometimes above, sometimes to the left. To ensure that you have consistency, try these settings:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set splitright &amp;#34; When splitting vertically, split to the right
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set splitbelow &amp;#34; When splitting horizontally, split below&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using splits and tabs give you a lot of flexibility in managing the code you are currently working. Adding just a few shortcuts and optimizations to your vimrc can really speed up your workflow and help you navigate your code more quickly.&lt;/p&gt;
&lt;h3 id=&#34;one-more-thing&#34;&gt;One more thing&lt;/h3&gt;
&lt;p&gt;Want a quick way to get to your vimrc?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:e $MYVIMRC&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


      </content>
    </entry>
  
    <entry>
      <title>Vim — working with encryption</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2012/05/vim-working-with-encryption/"/>
      <id>https://www.endpointdev.com/blog/2012/05/vim-working-with-encryption/</id>
      <published>2012-05-16T00:00:00+00:00</published>
      <author>
        <name>Terry Grant</name>
      </author>
      <content type="html">
        &lt;p&gt;On occasion I have to work with encrypted files for work or personal use. I am partial to a Linux environment and I prefer Vim as my text editor, even when I am only reading a file. Vim supports quite a few different ways of interfacing with external encryption packages. I only use two of those variations as described below.&lt;/p&gt;
&lt;p&gt;Vim comes packaged with a default encryption mechanism referred to as VimCrypt in the documentation. I typically use this functionality as a temporary solution in a situation where my GPG is not immediately available, like a remote system that is not mine.&lt;/p&gt;
&lt;h3 id=&#34;using-vims-default-vimcrypt-feature&#34;&gt;Using Vim’s default VimCrypt feature&lt;/h3&gt;
&lt;p&gt;Creating a new encrypted file or open a plain text file you wish to encrypt:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim -x &amp;lt;filename&amp;gt;&amp;lt;/filename&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will create a new file if it does not exist or open an existing file and then prompt you for a password. This password is then used as the key to encrypt and decrypt the specified file. Upon saving and exiting this file, it will be saved in this encrypted format using your crypt key.&lt;/p&gt;
&lt;p&gt;You can also save and encrypt an open file you are currently working on like so. Please note this is a &lt;strong&gt;capital X&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:X &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will also ask you for a password to encrypt the file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reasons I usually don’t use this option:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vim uses a weak encryption method by default. Vim encrypts the file using an encryption method ‘zip’, the same encryption algorithm that is used by Pkzip (known to be flawed). You can set the default encryption to use the more secure ‘blowfish’ cipher. For more information see the documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Set the cryptmethod to use the blowfish cipher
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:setlocal cm=blowfish 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Documentation on Vim Encryption
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:h :X&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Typically uses swap files that can compromise the security of the encrypted file. You can turn this off by using the &amp;rsquo;n&amp;rsquo; flag.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim -xn &amp;lt;filename&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;integrating-with-gpg&#34;&gt;Integrating with GPG&lt;/h3&gt;
&lt;p&gt;In order to seamlessly integrate with GPG encrypted files you will need to add the following to your .vimrc file&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;#34; Transparent editing of gpg encrypted files.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;#34; By Wouter Hanegraaff
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;augroup encrypted
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  au!
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; First make sure nothing is written to ~/.viminfo while editing
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; an encrypted file.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPre,FileReadPre *.gpg set viminfo=
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; We don&amp;#39;t want a swap file, as it writes unencrypted data to disk
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPre,FileReadPre *.gpg set noswapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; Switch to binary mode to read the encrypted file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPre,FileReadPre *.gpg set bin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPre,FileReadPre *.gpg let ch_save = &amp;amp;ch|set ch=2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; (If you use tcsh, you may need to alter this line.)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPost,FileReadPost *.gpg &amp;#39;[,&amp;#39;]!gpg --decrypt 2&amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; Switch to normal mode for editing
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPost,FileReadPost *.gpg set nobin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPost,FileReadPost *.gpg let &amp;amp;ch = ch_save|unlet ch_save
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufReadPost,FileReadPost *.gpg execute &amp;#34;:doautocmd BufReadPost &amp;#34; . expand(&amp;#34;%:r&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; Convert all text to encrypted text before writing
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; (If you use tcsh, you may need to alter this line.)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufWritePre,FileWritePre *.gpg &amp;#39;[,&amp;#39;]!gpg --default-recipient-self -ae 2&amp;gt;/dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; Undo the encryption so we are back in the normal text, directly
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34; after the file has been written.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autocmd BufWritePost,FileWritePost *.gpg u
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;augroup END&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Source: &lt;a href=&#34;http://vim.wikia.com/wiki/Encryption&#34;&gt;Vim Wiki—​Encryption&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This works by detecting the extension on the files you are opening with Vim. This allows you to open, edit, and save files as if they were plain text in a seamless fashion.&lt;/p&gt;
&lt;p&gt;Now you can create a new GPG encrypted file or edit an existing GPG encrypted doing this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim &amp;lt;filename&amp;gt;.gpg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This should prompt you for GPG password either with a GUI window or command line depending on your environment’s configuration. If the file did not exist Vim creates one and when you save it will encrypt when you write and quit.&lt;/p&gt;
&lt;p&gt;Another thing I like to do is save a file that I have already decrypted, but want to save in plain text. This can be done by simply opening the encrypted GPG file as seen above and change the extension when saving. Simply save like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;:w &amp;lt;newfilename&amp;gt;.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Any extension other than .gpg will save your file as plain text.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reason to use GPG&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Much safer encryption as it uses GPG&lt;/li&gt;
&lt;li&gt;No swap files thanks to this line in .vimrc autocmd BufReadPre,FileReadPre *.gpg set noswapfile&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course when using Vim there are many features and many different ways of doing this. This is simply how I use Vim to easily work with encrypted files in my daily life.&lt;/p&gt;
&lt;p&gt;For more information on Vim and external encryption programs please see and making use of GPG:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://vim.wikia.com/wiki/Encryption&#34;&gt;Vim Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cyberciti.biz/tips/linux-how-to-encrypt-and-decrypt-files-with-a-password.html&#34;&gt;Working with GPG — Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </content>
    </entry>
  
    <entry>
      <title>Points of Interest</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2012/05/points-of-interest/"/>
      <id>https://www.endpointdev.com/blog/2012/05/points-of-interest/</id>
      <published>2012-05-15T00:00:00+00:00</published>
      <author>
        <name>Brian Buchalter</name>
      </author>
      <content type="html">
        &lt;p&gt;It’s been a fairly straight forward week at work, but I have stumbled a few interesting finds along the way this week.&lt;/p&gt;
&lt;h3 id=&#34;vim-adventures&#34;&gt;&lt;a href=&#34;https://vim-adventures.com/&#34;&gt;Vim Adventures&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally! A game based approach to learning Vim keyboard commands. I was hoping someone would do this. It’s just getting started (only two levels) and sadly, it looks like it’ll be charging money to unlock higher levels. However, some things are worth paying for. I’ve found just playing the first two levels a few times have helped retrain my brain to not take my fingers off the home row. It’s still quite buggy and seems to only work in Chrome. I found several times I needed to close all my Chrome windows after playing. Also, incognito mode seems to help with the bugs, as it disables all extensions you may have installed.&lt;/p&gt;
&lt;h3 id=&#34;mysql-query-comments-in-rails&#34;&gt;&lt;a href=&#34;https://signalvnoise.com/posts/3130-mini-tech-note-mysql-query-comments-in-rails&#34;&gt;MySQL query comments in Rails&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ever wanted to know where that slow query was being called from? Well, if you’re using MySQL with your Rails 2.3.x or 3.x.x app, you can get debug information about what controller’s action made the call. Check out 37Signals new &lt;a href=&#34;https://github.com/37signals/marginalia&#34;&gt;marginalia&lt;/a&gt; gem.&lt;/p&gt;
&lt;h3 id=&#34;how-to-use-ec2-as-a-web-proxy&#34;&gt;&lt;a href=&#34;https://kev.inburke.com/kevin/how-to-use-ec2-as-a-web-proxy/&#34;&gt;How to use EC2 as a web proxy&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Kevin Burke provides a very detailed HOWTO article for working around restrictions you may experience in the course of an Internet based life. Pretty amazing what Amazon’s &lt;a href=&#34;https://aws.amazon.com/free&#34;&gt;free usage tier&lt;/a&gt; puts out there; of course it’s only free for 12 months.&lt;/p&gt;
&lt;h3 id=&#34;include-pids-in-your-logs&#34;&gt;&lt;a href=&#34;https://web.archive.org/web/20121005121328/http://help.papertrailapp.com/discussions/suggestions/18-include-pids-in-rails-productionlog&#34;&gt;Include PIDs in your Logs&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For many Rails developers we get comfortable looking at development log files. Sometimes when I have to investigate a customer issue on a production server using logs, I wished I had the level of detail the development logger had. While that’s a wish, I’m finding it mandatory to include PID numbers in my production logs. In production systems with multiple requests being handled simultaneously, Rails logs start to become unusable. It’s not clear which log lines are from which requests. Adding a PID in front of the time stamp can help untangle the mess. Here are some example approaches to this for &lt;a href=&#34;https://andre.arko.net/2011/08/18/pid-numbers-for-rails-3-logs/&#34;&gt;Rails 3.x.x&lt;/a&gt; and &lt;a href=&#34;http://nhw.pl/wp/2009/09/15/logger-simple-yet-powerful-rails-debugging-tool&#34;&gt;Rails 2.3.x&lt;/a&gt;. Also, if you’re really a log-lover and manage a lot of servers, check out &lt;a href=&#34;https://papertrailapp.com/&#34;&gt;Papertrail&lt;/a&gt;, it looks very impressive for $7/mo.&lt;/p&gt;
&lt;h3 id=&#34;spectrum-shortages---why-its-happening-and-what-can-be-done&#34;&gt;&lt;a href=&#34;http://s4gru.com/entry/160-spectrum-shortages-why-its-happening-and-what-can-be-done/&#34;&gt;Spectrum Shortages - Why it’s happening and what can be done&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Telecom is not an area I have much familiarity with, but I found this article to be an interesting read. For example did you know that that largest owner of spectrum licenses are “under-capitalized or unwilling to build out networks” to use the spectrum? So while AT&amp;amp;T and Verizon struggle to meet the iPhone 4S’s data demands (twice as much as iPhone 4!), “there are some companies that have spectrum, but they’re struggling financially. Or they aren’t quite sure what to do with the spectrum. And others that have the money and business model, but need the spectrum.” It seems the way out of the mess is 4G, offering to improve the efficiency of spectrum use by 700 percent.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Editing large files in place</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2009/12/editing-large-files-in-place/"/>
      <id>https://www.endpointdev.com/blog/2009/12/editing-large-files-in-place/</id>
      <published>2009-12-13T00:00:00+00:00</published>
      <author>
        <name>Greg Sabino Mullane</name>
      </author>
      <content type="html">
        &lt;p&gt;Running out of disk space seems to be an all too common problem lately, especially when dealing with large databases. One situation that came up recently was a client who needed to import a large Postgres dump file into a new database. Unfortunately, they were very low on disk space and the file needed to be modified. Without going into all the reasons, we needed the databases to use template1 as the template database, and not template0. This was a very large, multi-gigabyte file, and the amount of space left on the disk was measured in megabytes. It would have taken too long to copy the file somewhere else to edit it, so I did a low-level edit using the Unix utility &lt;strong&gt;dd&lt;/strong&gt;. The rest of this post gives the details.&lt;/p&gt;
&lt;p&gt;To demonstrate the problem and the solution, we’ll need a disk partition that has little-to-no free space available. In Linux, it’s easy enough to create such a thing by using a RAM disk. Most Linux distributions already have these ready to go. We’ll check it out with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ls -l /dev/ram*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brw-rw---- &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; root disk 1,  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0&lt;/span&gt; 2009-12-14 13:04 /dev/ram0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brw-rw---- &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; root disk 1,  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; 2009-12-14 22:27 /dev/ram1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From the above, we see that there are some RAM disks available (there are actually 16 of them available on my box, but I only showed two). Here’s the steps to create a usable partition from /dev/ram1, and to then check the size:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ mkdir /home/greg/ramtest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo mke2fs /dev/ram1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mke2fs 1.41.4 (27-Jan-2009)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Filesystem &lt;span style=&#34;color:#369&#34;&gt;label&lt;/span&gt;=
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OS type: Linux
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Block &lt;span style=&#34;color:#369&#34;&gt;size&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1024&lt;/span&gt; (&lt;span style=&#34;color:#369&#34;&gt;log&lt;/span&gt;=0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Fragment &lt;span style=&#34;color:#369&#34;&gt;size&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1024&lt;/span&gt; (&lt;span style=&#34;color:#369&#34;&gt;log&lt;/span&gt;=0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;4096&lt;/span&gt; inodes, &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;16384&lt;/span&gt; blocks
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;819&lt;/span&gt; blocks (5.00%) reserved &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;for&lt;/span&gt; the super user
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;First data &lt;span style=&#34;color:#369&#34;&gt;block&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Maximum filesystem &lt;span style=&#34;color:#369&#34;&gt;blocks&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;16777216&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;2&lt;/span&gt; block groups
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;8192&lt;/span&gt; blocks per group, &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;8192&lt;/span&gt; fragments per group
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;2048&lt;/span&gt; inodes per group
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Superblock backups stored on blocks:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;8193&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Writing inode tables: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Writing superblocks and filesystem accounting information: &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;This filesystem will be automatically checked every &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;29&lt;/span&gt; mounts or
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;180&lt;/span&gt; days, whichever comes first.  Use tune2fs -c or -i to override.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo mount /dev/ram1 /home/greg/ramtest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo chown greg:greg /home/greg/ramtest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ df -h /dev/ram1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Filesystem            Size  Used Avail Use% Mounted on
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/dev/ram1              16M  140K   15M   1% /home/greg/ramtest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First we created a new directory to server as the mount point, then we used the &lt;strong&gt;mke2fs&lt;/strong&gt; utility to create a new file system (ext2) on the RAM disk at /dev/ram1. It’s a fairly verbose program by default, but there is nothing in the output that’s really important for this example. Then we mounted our new filesystem to the directory we just created. Finally, we reset the permissions on the directory such that an ordinary user (e.g. &amp;lsquo;greg’) can read and write to it. At this point, we’ve got a directory/filesystem that is just under 16 MB large (we could have made it much closer to 16 MB by specifying a -m 0 to mke2fs, but the actual size doesn’t matter).&lt;/p&gt;
&lt;p&gt;To simulate what happened, let’s create a database dump and then bloat it until there it takes up all available space:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#038&#34;&gt;cd&lt;/span&gt; /home/greg/ramtest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ pg_dumpall &amp;gt; data.20091215.pg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ls -l data.20091215.pg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-r--r-- &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; greg greg &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;3685&lt;/span&gt; 2009-12-15 10:42 data.20091215.pg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ dd &lt;span style=&#34;color:#369&#34;&gt;seek&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;3685&lt;/span&gt; &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt;=/dev/zero &lt;span style=&#34;color:#369&#34;&gt;of&lt;/span&gt;=data.20091215.pg &lt;span style=&#34;color:#369&#34;&gt;bs&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1024&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;count&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;99999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dd: writing &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;data.20091215.pg&amp;#39;&lt;/span&gt;: No space left on device
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13897+0 records in
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13896+0 records out
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;14229504&lt;/span&gt; bytes (&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;14&lt;/span&gt; MB) copied, 0.0814188 s, &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;175&lt;/span&gt; MB/s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ df -h .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Filesystem            Size  Used Avail Use% Mounted on
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/dev/ram1              16M   15M     &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0&lt;/span&gt; 100% /home/greg/ramtest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First we created the dump, then we found the size of it, and told dd via the &lt;strong&gt;‘seek’&lt;/strong&gt; argument to start adding data to it at the 3685 byte mark (in other words, we appended to the file). We used the special file &lt;strong&gt;/dev/zero&lt;/strong&gt; as the &lt;strong&gt;‘if’&lt;/strong&gt; (input file), and our existing dump as the &lt;strong&gt;‘of’&lt;/strong&gt; (output file). Finally, we told it to chunk the inserts into 1024 bytes at a time, and to attempt to add 999,999 of those chunks.  Since this is approximately 100MB, we ran out of disk space quickly, as we intended. The filesystem is now at 100% usage, and will refuse any further writes to it.&lt;/p&gt;
&lt;p&gt;To recap, we need to change the first three instances of template0 with template1. Let’s use grep to view the lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grep --text --max-count=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;3&lt;/span&gt; template data.20091215.pg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CREATE DATABASE greg WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CREATE DATABASE rand WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CREATE DATABASE sales WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We need the &lt;strong&gt;&amp;ndash;text&lt;/strong&gt; argument here because grep correctly surmises that we’ve changed the file from text-based to binary with the addition of all those zeroes on the end. We also used the handy &lt;strong&gt;&amp;ndash;max-count&lt;/strong&gt; argument to stop processing once we’ve found the lines we want. Very handy argument when the actual file is gigabytes in size!&lt;/p&gt;
&lt;p&gt;There are two major problems with using a normal text editor to change the file. First, the file (in the real situation, not this example!) was very, very large. We only needed to edit something at the very top of the file, so loading the entire thing into an editor is very inefficient. Second, editors need to save their changes somewhere, and there just was not enough room to do so.&lt;/p&gt;
&lt;p&gt;Attempting to edit with emacs gives us: emacs: IO error writing /home/greg/ramtest/data.20091215.pg: No space left on device&lt;/p&gt;
&lt;p&gt;An attempt with vi gives us: vi: Write error in swap file on startup. &amp;ldquo;data.20091215.pg&amp;rdquo; E514: write error (file system full?)&lt;/p&gt;
&lt;p&gt;Although emacs gives the better error message (why is vim making a guess and outputting some weird E514 error?), the advantage always goes to vi in cases like this as emacs has a &lt;a href=&#34;https://www.emacswiki.org/emacs/EmacsFileSizeLimit&#34;&gt;major bug&lt;/a&gt; in that it cannot even open very large files.&lt;/p&gt;
&lt;p&gt;What about something more low-level like &lt;strong&gt;sed&lt;/strong&gt;? Unfortunately, while sed is more efficient than emacs or vim, it still needs to read the old file and write the new one. We can’t do that writing as we have no disk space! More importantly, in sed there is no way (that I could find anyway) to tell it stop processing after a certain number of matches.&lt;/p&gt;
&lt;p&gt;What we need is something &lt;em&gt;really&lt;/em&gt; low-level. The utility &lt;strong&gt;dd&lt;/strong&gt; comes to the rescue again. We can use dd to truly edit the file in place. Basically, we’re going to overwrite some of the bytes on disk, without needing to change anything else. First though, we have to figure out exactly which bytes to change. The grep program has a nice option called &lt;strong&gt;&amp;ndash;byte-offset&lt;/strong&gt; that can help us out:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grep --text --byte-offset --max-count=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;3&lt;/span&gt; template data.20091215.pg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;301:CREATE DATABASE greg WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;380:CREATE DATABASE rand WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;459:CREATE DATABASE sales WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This tells us the offset for each line, but we want to replace the number ‘0’ in ‘template0’ with the number ‘1’. Rather than count it out manually, let’s just use another Unix utility, &lt;strong&gt;hexdump&lt;/strong&gt;, to help us find the number:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grep --text --byte-offset --max-count=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;3&lt;/span&gt; template data.20091215.pg | hexdump -C
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;00000000&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;33&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;30&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;31&lt;/span&gt; 3a &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;43&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;52&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;45&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;41&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;54&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;45&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;44&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;41&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;54&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;41&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;42&lt;/span&gt;  |301:CREATE DATAB|
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;00000010&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;41&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;53&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;45&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;67&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;72&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;65&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;67&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;57&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;49&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;54&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;48&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;54&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;45&lt;/span&gt;  |ASE greg WITH TE|
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;00000020&lt;/span&gt;  4d &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;50&lt;/span&gt; 4c &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;41&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;54&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;45&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; 3d  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;74&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;65&lt;/span&gt; 6d &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;70&lt;/span&gt; 6c &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;61&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;74&lt;/span&gt;  |&lt;span style=&#34;color:#369&#34;&gt;MPLATE&lt;/span&gt; = templat|
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;00000030&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;65&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;30&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; 4f &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;57&lt;/span&gt; 4e &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;45&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;52&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; 3d &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;67&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;72&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;65&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;67&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt;  |e0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;00000040&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;45&lt;/span&gt; 4e &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;43&lt;/span&gt; 4f &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;44&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;49&lt;/span&gt; 4e &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;47&lt;/span&gt;  &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; 3d &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;27&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;55&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;54&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;46&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;38&lt;/span&gt;  |&lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;&amp;#39;&lt;/span&gt;UTF8|
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Each line is 16 characters, so the first three lines comes to 48 characters, then we add two for the ‘e0’, subtract four for the ‘301:’, and get 301+48+2-4=347. We subtract one more as we want to seek to the point just before that character, and we can now use our dd command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; | dd &lt;span style=&#34;color:#369&#34;&gt;of&lt;/span&gt;=data.20091215.pg &lt;span style=&#34;color:#369&#34;&gt;seek&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;346&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;bs&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;count&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;conv&lt;/span&gt;=notrunc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1+0 records in
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1+0 records out
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; byte (&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; B) copied, 0.00012425 s, 8.0 kB/s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Instead of an input file (the ‘if’ argument), we simply pass the number ‘1’ via stdin to the dd command. We use our calculated seek, tell it to copy a single byte (bs=1), one time (count=1), and (this is very important!) tell dd NOT to truncate the file when it is done (conv=notrunc). Technically, we are sending two characters to the dd program, the number one and a newline, but the bs=1 argument ensures only the first character is being copied. We can now verify that the change was made as we expected:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grep --text --byte-offset --max-count=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;3&lt;/span&gt; TEMPLATE data.20091215.pg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;301:CREATE DATABASE greg WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template1 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;380:CREATE DATABASE rand WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;459:CREATE DATABASE sales WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template0 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now for the other two entries. From before, the magic number is 45, so we now add 380 to 45 to get 425. For the third line, the name of the database is 1 character longer so we add 459+45+1 = 505:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; | dd &lt;span style=&#34;color:#369&#34;&gt;of&lt;/span&gt;=data.20091215.pg &lt;span style=&#34;color:#369&#34;&gt;seek&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;425&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;bs&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;count&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;conv&lt;/span&gt;=notrunc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1+0 records in
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1+0 records out
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; byte (&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; B) copied, 0.000109234 s, 9.2 kB/s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; | dd &lt;span style=&#34;color:#369&#34;&gt;of&lt;/span&gt;=data.20091215.pg &lt;span style=&#34;color:#369&#34;&gt;seek&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;505&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;bs&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;count&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;conv&lt;/span&gt;=notrunc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1+0 records in
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1+0 records out
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; byte (&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;1&lt;/span&gt; B) copied, 0.000109932 s, 9.1 kB/s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grep --text --byte-offset --max-count=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;3&lt;/span&gt; TEMPLATE data.20091215.pg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;301:CREATE DATABASE greg WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template1 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;380:CREATE DATABASE rand WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template1 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;459:CREATE DATABASE sales WITH &lt;span style=&#34;color:#369&#34;&gt;TEMPLATE&lt;/span&gt; = template1 &lt;span style=&#34;color:#369&#34;&gt;OWNER&lt;/span&gt; = greg &lt;span style=&#34;color:#369&#34;&gt;ENCODING&lt;/span&gt; = &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;UTF8&amp;#39;&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Success! On the real system, the database was loaded with no errors, and the large file was removed. If you’ve been following along and need to cleanup:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ &lt;span style=&#34;color:#038&#34;&gt;cd&lt;/span&gt; ~
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo umount /home/greg/ramtest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ rmdir ramtest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Keep in mind that dd is a very powerful and thus very dangerous utility, so treat it with care. It can be invaluable for times like this however!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Vim tip of the day: tabbed editing</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2009/03/vim-tip-of-day-tabbed-editing/"/>
      <id>https://www.endpointdev.com/blog/2009/03/vim-tip-of-day-tabbed-editing/</id>
      <published>2009-03-11T00:00:00+00:00</published>
      <author>
        <name>Christopher Nehren</name>
      </author>
      <content type="html">
        &lt;p&gt;How many tabs does your browser have open? I have 17 tabs open in Firefox presently (and opened / closed about 12 while writing this post). Most users will agree that tabs have changed the way they use the Web. Even IE, which has spawned a collection of shells for tabbed browsing, now supports it natively. Tabs allow for a great saving in screen real-estate, and in many cases, better interaction among the various open documents. Considering how much time programmers spend in their text editors, it therefore seems logical that the editor should provide the same functionality.&lt;/p&gt;
&lt;p&gt;And the Vim developers agree. Although Vim calls them “tab-pages”, the functionality is there, waiting to be used. Before reading any further, ensure that your Vim supports tabs. You can do this by running this command, on anything resembling Unix:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim --version | fgrep +windows&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you don’t see any output, check your vendor’s packaging system for something like &lt;code&gt;vim-full&lt;/code&gt;. If you don’t have a Vim available with the windows feature, go get one and come back.&lt;/p&gt;
&lt;p&gt;Now that you can use tabs, let’s get started. One way to open tabs is via the command line. Vim uses the &lt;code&gt;-p&lt;/code&gt; option to determine how many tab-pages to open. This functions like the &lt;code&gt;-[oO]&lt;/code&gt; options for windows in that it accepts a numeric argument, but defaults to one for each specified file.&lt;/p&gt;
&lt;p&gt;Let’s propose a hypothetical situation: I want to compare the implementation of &lt;code&gt;has()&lt;/code&gt; in both Moose and Mouse. Therefore, it might be convenient to have the two files open in two tab-pages in Vim. Presuming I’m in the same directory as both files, I would open Vim with a tab-page for each file like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim -p Moose.pm Mouse.pm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There will be a bar at the top of the terminal: That’s the tab bar. It has every open tab, plus an X at the far right. That’s great, and all, but how does one use this? There are a number of ways, depending upon your configuration. First, there’s the basic tab page commands. These are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gt&lt;/code&gt; Advance to the next rightmost tab, cycling back to the first.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gT&lt;/code&gt; Advance to the next leftmost tab, cycling back to the last.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{count}gt&lt;/code&gt; Go to the {count} tab.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These commands work in both command-line Vim (for those of you working on remote machines) and in gvim (for those of you writing new code). Additionally, gvim and Vims that recognize mouse input on a terminal (&lt;code&gt;:help mouse-using&lt;/code&gt;) recognize clicks on the tabs or the X in the upper right.&lt;/p&gt;
&lt;p&gt;This tip has touched on the very basics of tab-pages, but the information covered here is enough to be useful (and is all I use on a regular basis). However, the curious should definitely read the Vim reference manual for more info, with &lt;code&gt;:help&lt;/code&gt; tabpage.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Vim Tip of the Day: running external commands in a shell</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2009/03/vim-tip-of-day-running-external/"/>
      <id>https://www.endpointdev.com/blog/2009/03/vim-tip-of-day-running-external/</id>
      <published>2009-03-10T00:00:00+00:00</published>
      <author>
        <name>Selena Deckelmann</name>
      </author>
      <content type="html">
        &lt;p&gt;A common sequence of events when editing files is to make a change and then need to test by executing the file you edited in a shell. If you’re using Vim, you could suspend your session (ctrl-Z), and then run the command in your shell.&lt;/p&gt;
&lt;p&gt;That’s a lot of keystrokes, though.&lt;/p&gt;
&lt;p&gt;So, instead, you can use Vim’s built-in “run a shell command”!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;:!{cmd}&lt;/code&gt; Run a shell command, shows you the output and prompts you before returning to your current buffer.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Even sweeter, is to use the Vim special character for current filename: &lt;code&gt;%&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here’s &lt;code&gt;:! %&lt;/code&gt; in action!&lt;/p&gt;
&lt;img alt=&#34;&#34; border=&#34;0&#34; src=&#34;/blog/2009/03/vim-tip-of-day-running-external/image-0.png&#34; style=&#34;margin:0px auto 10px; text-align:center;&#34;/&gt;
&lt;img alt=&#34;&#34; border=&#34;0&#34; src=&#34;/blog/2009/03/vim-tip-of-day-running-external/image-1.png&#34; style=&#34;margin:0px auto 10px; text-align:center;&#34;/&gt;
&lt;p&gt;A few more helpful shortcuts related to executing things in the shell:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:!&lt;/code&gt; By itself, runs the last external command (from your shell history)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:!!&lt;/code&gt; Repeats the last command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:silent !{cmd}&lt;/code&gt; Eliminates the need to hit enter after the command is done&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:r !{cmd}&lt;/code&gt; Puts the output of $cmd into the current buffer.&lt;/li&gt;
&lt;/ul&gt;

      </content>
    </entry>
  
</feed>
