<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Z Space Blog - Vim</title><link href="https://zlg.space/blog/" rel="alternate"/><link href="https://zlg.space/blog/feeds/t/vim.atom.xml" rel="self"/><id>https://zlg.space/blog/</id><updated>2023-08-05T12:38:00-07:00</updated><entry><title>Vim Author Bram Moolenaar Has Died</title><link href="https://zlg.space/blog/vim-author-bram-moolenaar-has-died.html" rel="alternate"/><published>2023-08-05T12:38:00-07:00</published><updated>2023-08-05T12:38:00-07:00</updated><author><name>zlg</name></author><id>tag:zlg.space,2023-08-05:/blog/vim-author-bram-moolenaar-has-died.html</id><summary type="html">&lt;p&gt;I woke up to a &lt;a href="https://lobste.rs/s/yrlb5m/message_from_family_bram_moolenaar_he"&gt;huge&lt;/a&gt; &lt;a href="https://news.slashdot.org/story/23/08/05/1632219/vims-creator-bram-moolenaar-dies-at-age-62"&gt;gut&lt;/a&gt; &lt;a href="https://news.ycombinator.com/item?id=37011324"&gt;punch&lt;/a&gt; this
morning: &lt;a href="https://groups.google.com/g/vim_announce/c/tWahca9zkt4"&gt;Bram Moolenaar, legendary author of the Vim text editor, has passed
away&lt;/a&gt;. Given the occasion, I want to express some thoughts
regarding both Bram and his software. Without his work, I'm not sure I would be
the same person.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I woke up to a &lt;a href="https://lobste.rs/s/yrlb5m/message_from_family_bram_moolenaar_he"&gt;huge&lt;/a&gt; &lt;a href="https://news.slashdot.org/story/23/08/05/1632219/vims-creator-bram-moolenaar-dies-at-age-62"&gt;gut&lt;/a&gt; &lt;a href="https://news.ycombinator.com/item?id=37011324"&gt;punch&lt;/a&gt; this
morning: &lt;a href="https://groups.google.com/g/vim_announce/c/tWahca9zkt4"&gt;Bram Moolenaar, legendary author of the Vim text editor, has passed
away&lt;/a&gt;. Given the occasion, I want to express some thoughts
regarding both Bram and his software. Without his work, I'm not sure I would be
the same person.&lt;/p&gt;


&lt;h1&gt;How I found Vim&lt;/h1&gt;
&lt;p&gt;On a wintry Wisconsin night in 2004, I was looking for better, more customizable
software. I was a teenager, learning about alternative OSes and losing patience
with Windows every passing day. I had started getting more serious about
learning web development, and began trying different text editors, to see what
was to my taste. As we all know, Notepad on Windows is &lt;em&gt;NOT&lt;/em&gt; sufficient for 
programming.&lt;/p&gt;
&lt;p&gt;On this path of discovering text editors, I stumbled across all sorts of things,
from UltraEdit to metapad, Notepad++, gedit, AceHTML, Emacs, and eventually I
found this free software called "vim", but it came with some newbie-friendly
settings, called &lt;a href="https://cream.sourceforge.net/"&gt;Cream&lt;/a&gt;. (I was surprised to see it's still around!) One
thing that stood out to me about Vim, at the time, was the fact I didn't have
to enter some weird licensing scheme. I didn't have to pay to unlock features,
and the big thing was -- if I wanted to help, I could donate to a charity that
actually helped people! That stuck with me, morally. "Huh, all these companies
are making software for profit, but this guy from Europe just wants me to help
some less fortunate people. That's awesome."&lt;/p&gt;
&lt;p&gt;I would not realize it until years later, but discovering Vim was a key step in
my journey to libre software and GNU/Linux. Had I not been looking for a free,
customizable text editor to do what I wanted, it may have delayed or slowed my
introduction to that world.&lt;/p&gt;
&lt;h1&gt;How I Use Vim Today&lt;/h1&gt;
&lt;p&gt;These days, I keep a small group of plugins (mostly things like &lt;code&gt;fugitive&lt;/code&gt;,
&lt;code&gt;tabular&lt;/code&gt;, &lt;code&gt;sparkup&lt;/code&gt;, and some syntax stuff), a hefty &lt;code&gt;vimrc&lt;/code&gt; with keyboard
layout switching capabilities, and there's almost always a Vim process open on
my machines. It earned a place as my favorite piece of software when I learned
how easy it is to extend its behavior. No other piece of software evolves &lt;em&gt;with&lt;/em&gt;
me and my skill level like Vim does.&lt;/p&gt;
&lt;p&gt;I love Vim's documentation system the most, I think. If there's anything I don't 
know about Vim, I can consult &lt;code&gt;:help&lt;/code&gt; and get answers &lt;em&gt;immediately&lt;/em&gt;. For 
anything else, there is a broad community of fellow &lt;em&gt;text-heads&lt;/em&gt; out there, who 
might even have saved a fricken macro for the task you're trying to achieve.&lt;/p&gt;
&lt;p&gt;Each time I learn something new about Vim, I feel like I've unlocked a new 
ability, or added a new text wrangling tool to my belt. This, in turn, improves 
my ability to manipulate text and makes the editing experience that much better.&lt;/p&gt;
&lt;h1&gt;The Future of Vim&lt;/h1&gt;
&lt;p&gt;It seems that Bram had tapped a successor, in some way, before he died, but
the state of things with the Vim project seem to indicate his death was not
&lt;em&gt;expected&lt;/em&gt;, per se, though he had been ill for a few months prior to his death.
It is sad to see another one of the "original breed" of FOSS hackers pass on.
It stands as a reminder of how little time we really have on this rock, and the
importance of choosing goals that one can look back on with pride. I hope that
the new primary author and maintainer, Christian Brabandt, leads the project
with the same core values that Bram did. &lt;a href="https://groups.google.com/g/vim_dev/c/6_yWxGhB_8I/m/ibserACYBAAJ"&gt;Christian expresses his thoughts in 
the Google Groups thread.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vim is the reason I discovered the Free Software movement. It's the software
that I use most in my day-to-day computing. How strange, that a journey for a
good text editor led to me discovering an entire social movement of hackers that
I still hover around to this day, nearly 20 years later. Thank you, Bram, for
bringing joy to my computing and rewarding every new morsel of knowledge I gain
about this beautiful tool.&lt;/p&gt;
&lt;p&gt;I have nothing but condolences for the Moolenaar family in their time of 
grieving. I hope their hearts are made lighter by the worldwide celebration 
of Bram's wonderful work, and the many testimonies people are publishing today 
which show how influential he was. We are all privileged to have received his 
work.&lt;/p&gt;
&lt;p&gt;Please consider donating to &lt;a href="http://iccf.nl/news.html"&gt;ICCF Holland&lt;/a&gt; if you wish to leave a token of
appreciation for Bram. It's what he would ask for.&lt;/p&gt;</content><category term="Software"/><category term="Software"/><category term="Vim"/><category term="Libre Software"/><category term="Major Events"/></entry><entry><title>Easy diffing with Vim</title><link href="https://zlg.space/blog/easy-diffing-with-vim.html" rel="alternate"/><published>2018-10-13T00:00:00-07:00</published><updated>2018-12-06T00:00:00-08:00</updated><author><name>zlg</name></author><id>tag:zlg.space,2018-10-13:/blog/easy-diffing-with-vim.html</id><summary type="html">&lt;p&gt;Vim has good support for showing the differences between two (or three) files
with either the &lt;code&gt;vimdiff&lt;/code&gt; command or setting up a diff session manually.
This often requires opening the files in their own window panes, then using
&lt;code&gt;:diffthis&lt;/code&gt; in all the relevant files. If you're in the middle of an editing
session, stopping to set up this diff session can cause you to lose focus. I
wrote a function in my &lt;code&gt;vimrc&lt;/code&gt; that automates this process, so the user can 
focus on making decisions instead of building their UI or some other 
flow-breaking process.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Vim has good support for showing the differences between two (or three) files
with either the &lt;code&gt;vimdiff&lt;/code&gt; command or setting up a diff session manually.
This often requires opening the files in their own window panes, then using
&lt;code&gt;:diffthis&lt;/code&gt; in all the relevant files. If you're in the middle of an editing
session, stopping to set up this diff session can cause you to lose focus. I
wrote a function in my &lt;code&gt;vimrc&lt;/code&gt; that automates this process, so the user can 
focus on making decisions instead of building their UI or some other 
flow-breaking process.&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;quot; Function: BufDiff&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; Author: zlg &amp;lt;zlg+viml@zlg.space&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; Date: 2018-10-12&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; License: GNU GPL, version 3 &amp;lt;https://gnu.org/licenses/gpl-3.0.html&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; Description: Open a new tab page with two or three buffers and enter diff mode.&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; Long Description:&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; BufDiff accepts two or three buffer arguments and opens a new tab page to&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; work with them in diff mode. This ensures that your existing window and&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; buffer layout is preserved while providing an easy way to enter a diff&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; session. The arguments can be any argument that can also be passed to&lt;/span&gt;
&lt;span class="c"&gt;&amp;quot; the &amp;quot;:buffer&amp;quot; Ex-command, including partial filenames (if quoted).&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; BufDiff&lt;span class="p"&gt;(&lt;/span&gt;buf1&lt;span class="p"&gt;,&lt;/span&gt; buf2&lt;span class="p"&gt;,&lt;/span&gt; ...&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; fname &lt;span class="p"&gt;=&lt;/span&gt; substitute&lt;span class="p"&gt;(&lt;/span&gt;expand&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;sfile&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;^function &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;a&lt;/span&gt;:&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
        echohl ErrorMsg
        &lt;span class="k"&gt;echomsg&lt;/span&gt; &lt;span class="k"&gt;l&lt;/span&gt;:fname . &lt;span class="s2"&gt;&amp;quot;: This function accepts a maximum of three arguments.&amp;quot;&lt;/span&gt;
        echohl None
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="c"&gt;    &amp;quot; Check for a third buffer, which will default to zero if not present&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;a&lt;/span&gt;:buf3 &lt;span class="p"&gt;=&lt;/span&gt; get&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;:&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;bufexists&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;:buf1&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;bufexists&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;:buf2&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;:&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class="p"&gt;!&lt;/span&gt;bufexists&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;:buf3&lt;span class="p"&gt;))&lt;/span&gt;
        echohl ErrorMsg
        &lt;span class="k"&gt;echomsg&lt;/span&gt; &lt;span class="k"&gt;l&lt;/span&gt;:fname . &lt;span class="s2"&gt;&amp;quot;: One or more buffer number(s) not found!&amp;quot;&lt;/span&gt;
        echohl None
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="k"&gt;tabnew&lt;/span&gt;
        exe &lt;span class="s2"&gt;&amp;quot;:buffer &amp;quot;&lt;/span&gt; . &lt;span class="k"&gt;a&lt;/span&gt;:buf1
        &lt;span class="k"&gt;diffthis&lt;/span&gt;
        &lt;span class="k"&gt;vsplit&lt;/span&gt;
        exe &lt;span class="s2"&gt;&amp;quot;:buffer &amp;quot;&lt;/span&gt; . &lt;span class="k"&gt;a&lt;/span&gt;:buf2
        &lt;span class="k"&gt;diffthis&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;a&lt;/span&gt;:buf3
            &lt;span class="k"&gt;vsplit&lt;/span&gt;
            exe &lt;span class="s2"&gt;&amp;quot;:buffer &amp;quot;&lt;/span&gt; . &lt;span class="k"&gt;a&lt;/span&gt;:buf3
            &lt;span class="k"&gt;diffthis&lt;/span&gt;
        &lt;span class="k"&gt;endif&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;endif&lt;/span&gt;
&lt;span class="k"&gt;endfunction&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;BufDiff()&lt;/code&gt; allows me to reference two or three open buffers and put them into
a separate diff session via a tab page. When I'm done working with the diff
session, I can &lt;code&gt;:tabc&lt;/code&gt; to close the tabpage and my original session (from the
prior tabpage) is still intact, ready for me to continue work.&lt;/p&gt;
&lt;p&gt;Using it is simple. Let's say you invoke vim with &lt;code&gt;vim foo.txt bar.txt&lt;/code&gt;.
You'll end up in Vim with the contents of &lt;code&gt;foo.txt&lt;/code&gt; (or an empty buffer ready
for writing to said file), with &lt;code&gt;bar.txt&lt;/code&gt; in a second buffer. If I do &lt;code&gt;:call
BufDiff(1,2)&lt;/code&gt;, the new tabpage will come up and compare the two files. I could
also use &lt;code&gt;:call BufDiff("foo", "bar")&lt;/code&gt;, since the arguments get sent to the
&lt;code&gt;:buffer&lt;/code&gt; Ex-command.&lt;/p&gt;
&lt;p&gt;The primary limitation of &lt;code&gt;BufDiff&lt;/code&gt; is you need the files you want to compare
to be present in the buffer list already. Many people begin working on their
projects with a one-liner that opens all the relevant source files, so it's a
limitation that I think is bearable.&lt;/p&gt;
&lt;p&gt;If you use this function, let me know how it worked out for you! Improvements 
and suggestions are also welcome.&lt;/p&gt;
&lt;p&gt;Shoutout to tockitj from Freenode's &lt;code&gt;#vim&lt;/code&gt; channel for the inspiration.&lt;/p&gt;</content><category term="Software"/><category term="Vim"/><category term="Programming"/></entry><entry><title>Counting Lines of Code in Vim</title><link href="https://zlg.space/blog/counting-lines-of-code-in-vim.html" rel="alternate"/><published>2014-02-10T01:35:00-08:00</published><updated>2014-02-10T01:35:00-08:00</updated><author><name>zlg</name></author><id>tag:zlg.space,2014-02-10:/blog/counting-lines-of-code-in-vim.html</id><summary type="html">&lt;p&gt;Vim is a wonderfully extensible text editor. I use it to work with all sorts of
text. While I was browsing reddit, I saw a thread asking for a way to prevent
&lt;code&gt;:number&lt;/code&gt; from counting blank lines. I checked it out to see if there were any
cool answers. None of what I saw were adequate. For instance, &lt;code&gt;:%s/\S\+//n&lt;/code&gt;
makes every match highlight, clobbering the last text that was searched for.
I figured it was time for me to learn a little more about Vimscript, and so I
wrote a function that will tell you how many &lt;em&gt;actual lines of code&lt;/em&gt; are in your
file:&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Vim is a wonderfully extensible text editor. I use it to work with all sorts of
text. While I was browsing reddit, I saw a thread asking for a way to prevent
&lt;code&gt;:number&lt;/code&gt; from counting blank lines. I checked it out to see if there were any
cool answers. None of what I saw were adequate. For instance, &lt;code&gt;:%s/\S\+//n&lt;/code&gt;
makes every match highlight, clobbering the last text that was searched for.
I figured it was time for me to learn a little more about Vimscript, and so I
wrote a function that will tell you how many &lt;em&gt;actual lines of code&lt;/em&gt; are in your
file:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;quot; Count the number of source lines in a file&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;SID&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;CountCodeLines&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; code_count &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; line &lt;span class="k"&gt;in&lt;/span&gt; getbufline&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;%&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;len&lt;span class="p"&gt;(&lt;/span&gt;line&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;line&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\S\+&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;s:IsCommentLine&lt;span class="p"&gt;(&lt;/span&gt;line&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                continue
            &lt;span class="k"&gt;endif&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; code_count &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;endif&lt;/span&gt;
    &lt;span class="k"&gt;endfor&lt;/span&gt;
    echo code_count . &lt;span class="s1"&gt;&amp;#39; lines of code.&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;endfunction&lt;/span&gt;

&lt;span class="c"&gt;&amp;quot; To be used with CountCodeLines()&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; s:IsCommentLine&lt;span class="p"&gt;(&lt;/span&gt;line&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;l&lt;/span&gt;:comtypes &lt;span class="p"&gt;=&lt;/span&gt; []
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;l&lt;/span&gt;:comlist &lt;span class="p"&gt;=&lt;/span&gt; split&lt;span class="p"&gt;(&lt;/span&gt;&amp;amp;&lt;span class="nb"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; comlist
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;l&lt;/span&gt;:type &lt;span class="p"&gt;=&lt;/span&gt; split&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; len&lt;span class="p"&gt;(&lt;/span&gt;type&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;l&lt;/span&gt;:&lt;span class="k"&gt;opt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; type[&lt;span class="m"&gt;1&lt;/span&gt;]
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;l&lt;/span&gt;:&lt;span class="k"&gt;opt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; type[&lt;span class="m"&gt;0&lt;/span&gt;]
        &lt;span class="k"&gt;endif&lt;/span&gt;
        &lt;span class="k"&gt;call&lt;/span&gt; add&lt;span class="p"&gt;(&lt;/span&gt;comtypes&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;endfor&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; len&lt;span class="p"&gt;(&lt;/span&gt;comtypes&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;:line&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;^\s*&amp;#39;&lt;/span&gt; . escape&lt;span class="p"&gt;(&lt;/span&gt;comtypes[&lt;span class="k"&gt;i&lt;/span&gt;]&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;-1&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;endif&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;endwhile&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;endfunction&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Put that in your &lt;code&gt;~/.vimrc&lt;/code&gt; or another similar location and have at it! I chose 
to map it to &lt;code&gt;&amp;lt;leader&amp;gt;c&lt;/code&gt; with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;nnoremap &amp;lt;leader&amp;gt;c :call &amp;lt;SID&amp;gt;CountCodeLines()&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I'm releasing these functions under the &lt;a href="https://wtfpl.net/txt/copying"&gt;WTFPL&lt;/a&gt; to contribute another
mini-feature to Vim and the free, open source software community. It was a fun
(if slightly aggravating) exercise in Vimscript.&lt;/p&gt;</content><category term="Software"/><category term="vim"/></entry></feed>