<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Blog entries tagged vim :: mwop.net</title>
  <updated>2023-12-19T12:14:00-06:00</updated>
  <generator uri="https://getlaminas.org" version="2">Laminas_Feed_Writer</generator>
  <link rel="alternate" type="text/html" href="https://mwop.net/blog/tag/vim"/>
  <link rel="self" type="application/atom+xml" href="https://mwop.net/blog/tag/vim/atom.xml"/>
  <id>https://mwop.net/blog/tag/vim</id>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Advent 2023: (n)vim Plugins: vim-markdown]]></title>
    <published>2023-12-19T12:14:00-06:00</published>
    <updated>2023-12-19T12:14:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2023-12-19-advent-vim-markdown.html"/>
    <id>https://mwop.net/blog/2023-12-19-advent-vim-markdown.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I'm a huge fan of <xhtml:a href="https://www.markdownguide.org/">Markdown</xhtml:a>. There's something
elegant in using textual sigils to provide contextual information.
I've used it for taking notes, creating RSS feed content, producing
my blog, and even in emails (I soooo wish there were a way to
convert markdown within Outlook for the web and GMail!)</xhtml:p>
<xhtml:p>So it should come as no surprise that I use a variety of tools
to help me when writing markdown in (n)vim.</xhtml:p>
<xhtml:h3>What are the tools?</xhtml:h3>
<xhtml:p>The <xhtml:a href="https://github.com/aareman/vim-markdown">aareman/vim-markdown</xhtml:a>
plugin provides the core functionality, and features syntax
highlighting. What's great is that in a terminal that supports it,
you'll actually see things appear in bold, italics, or underlined.
Headers, links, and monospace text each get a different color, and
sometimes even weight.</xhtml:p>
<xhtml:p>From there, I have a number of other plugins that augment the
functionality from vim-markdown:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:a href="dhruvasagar/vim-table-mode">vim-table-mode</xhtml:a>
provides on-the-fly autoformatting of textual tables, including
those in Markdown. This is invaluable, as it allows me to see
<xhtml:em>as I type</xhtml:em> if I'm missing columns, adding extra columns,
etc.</xhtml:li>
<xhtml:li><xhtml:a href="https://github.com/img-paste-devs/img-paste.vim">img-paste.vim</xhtml:a>
allows pasting a screenshot into a markdown document. It will copy
the screenshot to a specified relative directory, and then create
the markup for displaying it in the document.</xhtml:li>
<xhtml:li><xhtml:a href="https://github.com/vim-pandoc/vim-pandoc-syntax">vim-pandoc-syntax</xhtml:a>
does much of the heavy lifting for syntax highlighting,
particularly when it comes to fenced code blocks. If you use
<xhtml:a href="https://github.github.com/gfm/">Github Flavored
Markdown</xhtml:a>, you can optionally specify a <xhtml:em>language</xhtml:em> when
creating a fenced code block; vim-pandoc-syntax will identify the
language, and use it to provide syntax highlighting within the code
block for the given language.</xhtml:li>
</xhtml:ul>
<xhtml:p>Additionally, with <xhtml:a href="/blog/2023-12-17-advent-vim-coc.html">coc.nvim</xhtml:a>, I get
integration with <xhtml:a href="https://github.com/markdownlint/markdownlint">markdownlint</xhtml:a>,
which flags potential syntax and style issues.</xhtml:p>
<xhtml:h3>How I configure it</xhtml:h3>
<xhtml:p>I configure vim-markdown using the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-vimrc">let g:markdown_disable_folding            = 1
let g:markdown_disable_motions            = 0
let g:markdown_disable_spell_checking     = 0
let g:markdown_disable_conceal            = 0
let g:markdown_disable_table_mode         = 0
let g:markdown_disable_pandoc_integration = 0
let g:markdown_disable_clean_empty_on_cr  = 0

nnoremap &lt;buffer&gt; &lt;Leader&gt;x :call markdown#SwitchStatus()&lt;CR&gt;
</xhtml:code></xhtml:pre>
<xhtml:p>These do the following:</xhtml:p>
<xhtml:ul>
<xhtml:li>I rarely use code folding, and when I do, I want to do it
manually. As such, I disable auto-folding done by the plugin.</xhtml:li>
<xhtml:li>vim-markdown provides a variety of <xhtml:em>motions</xhtml:em> that let
you jump around more quickly in a markdown document, particularly
to the previous header (<xhtml:code>[[</xhtml:code>) or the next header
(<xhtml:code>]]</xhtml:code>). I want to keep these around.</xhtml:li>
<xhtml:li>Spell checking is nice.</xhtml:li>
<xhtml:li>"conceal" will <xhtml:em>conceal</xhtml:em> markup sigils when you're not
on a line; the terminal continues to highlight them appropriately
(e.g. bold, italic, underlined, etc.). Links are collapsed to just
the highlighted linked text, collapsing the content around them.
Doing this makes <xhtml:em>reading</xhtml:em> the document easier; when you're
on the line, it will reveal all concealed characters so you can
edit.</xhtml:li>
<xhtml:li>Table mode enables the integration with vim-table-mode; I
definitely want this.</xhtml:li>
<xhtml:li>Pandoc integration enables the pandoc syntax highlighting; I
definitely want this.</xhtml:li>
<xhtml:li>If I hit Enter from a list item, it creates a new list item.
This last setting means that I can hit Enter again, and it will
clear the list item and start a line below. It's an easy way to end
a list and start typing the next paragraph.</xhtml:li>
<xhtml:li>I often use GFM checkboxes for TODO lists. The mapping
declaration maps <xhtml:code>&lt;Leader&gt;x</xhtml:code> to toggle the
checkbox.</xhtml:li>
</xhtml:ul>
<xhtml:h3>Final thoughts</xhtml:h3>
<xhtml:p>After <xhtml:a href="/blog/2023-12-15-advent-vim-surround.html">vim-surround</xhtml:a> and
<xhtml:a href="/blog/2023-12-17-advent-vim-coc.html">coc.nvim</xhtml:a>, this
is undoubtedly the plugin that gives me the most value. I benefited
from it <xhtml:em>typing up this very blog post</xhtml:em>! While a GUI IDE can
provide side-by-side editing where you can see how the Markdown is
transformed, I rarely need that; the whole point of Markdown is to
provide a <xhtml:em>human readable</xhtml:em> format that provides
<xhtml:em>contextual markup</xhtml:em>. Reading the raw file should be
enough.</xhtml:p>
<xhtml:p>vim-markdown gives me the ability to have a raw Markdown file,
while simultaneously giving me just enough visual context to
understand things even when skimming a document.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2023-12-19-advent-vim-markdown.html">Advent
2023: (n)vim Plugins: vim-markdown</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2023-12-19T12:14:00-06:00">19
December 2023</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Advent 2023: (n)vim Plugins: vim-fugitive]]></title>
    <published>2023-12-18T15:34:00-06:00</published>
    <updated>2023-12-18T15:34:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2023-12-18-advent-vim-fugitive.html"/>
    <id>https://mwop.net/blog/2023-12-18-advent-vim-fugitive.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>Because I've spent most of my professional life coding, I've
also spent a lot of time using source control. I've been using
specifically <xhtml:a href="https://git-scm.com/">git</xhtml:a> for many years
(even pre-dating the Zend Framework migration from <xhtml:a href="https://subversion.apache.org">Subversion</xhtml:a>). While I typically
use a terminal multiplexer (for me, that's <xhtml:a href="https://github.com/tmux/tmux/wiki">tmux</xhtml:a>; for others, that
might be <xhtml:a href="https://www.gnu.org/software/screen/">screen</xhtml:a>), and can move to
another pane or create one quickly in order to run source control
commands, doing so interrupts flow.</xhtml:p>
<xhtml:p>That's where <xhtml:a href="https://github.com/tpope/vim-fugitive">vim-fugitive</xhtml:a> comes into
play.</xhtml:p>
<xhtml:h3>What does it solve?</xhtml:h3>
<xhtml:p>Fugitive integrates with git, plain and simple. It exposes a
number of commands and functions that allow you to do common
operations quickly, but also has some deeper bindings to allow
doing more complex things such as viewing a file from previous
commits, or performing a diff between the staged and working
version, or using <xhtml:code>git blame</xhtml:code> within vim.</xhtml:p>
<xhtml:h3>How do I use it?</xhtml:h3>
<xhtml:p>Admittedly, I use a very small subset of what Fugitive
provides.</xhtml:p>
<xhtml:p>On a daily basis, I use <xhtml:code>:Gwrite</xhtml:code> to stage changes,
and <xhtml:code>:G</xhtml:code> to view the status of the working tree. When in
the status view, I often use <xhtml:code>cc</xhtml:code> to
<xhtml:strong>c</xhtml:strong>ommit <xhtml:strong>c</xhtml:strong>hanges, which splits open
a pane for writing the commit message. I also use
<xhtml:code>:GRemove</xhtml:code> when I want to remove a file from the
tree.</xhtml:p>
<xhtml:p>Something else that has come in handy when reviewing code with
others: <xhtml:code>:GBrowse</xhtml:code> can open the file in the canonical
repository, using the visual selection as the line range, allowing
you to quickly share a link to specific code to review.</xhtml:p>
<xhtml:h3>Final Thoughts</xhtml:h3>
<xhtml:p>This plugin does exactly what it says on the tin. I love the
fact that it integrates with the underlying <xhtml:code>git</xhtml:code>
command, as that follows the Unix Philosophy of doing one thing
well, and piping out to other processes to perform complex
behavior. For me, the fact that I can stay directly within my
editor and still get full access to git when needed is tremondously
powerful.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2023-12-18-advent-vim-fugitive.html">Advent
2023: (n)vim Plugins: vim-fugitive</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2023-12-18T15:34:00-06:00">18
December 2023</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Advent 2023: (n)vim Plugins: coc.nvim]]></title>
    <published>2023-12-17T13:32:00-06:00</published>
    <updated>2023-12-17T13:32:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2023-12-17-advent-vim-coc.html"/>
    <id>https://mwop.net/blog/2023-12-17-advent-vim-coc.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I've used vim and variants since 2001. In 2019, a friend
introduced me to <xhtml:a href="https://github.com/neoclide/coc.nvim">coc.nvim</xhtml:a>, which turned
out to be my initial gateway to nvim, which I adopted a year or two
later.</xhtml:p>
<xhtml:h3>What is coc.nvim?</xhtml:h3>
<xhtml:p>The plugin name is an acronym for "Conquer of Completion", and
its goal is to "Make your Vim/Neovim as smart as VS Code". While it
can be used with either vim or neovim, it has some optimizations
under the hood to allow usage with neovim's <xhtml:a href="https://neovim.io/doc/user/lsp.html">language server protocol
support</xhtml:a>, which allows it to expose more features and perform
better when using that editor.</xhtml:p>
<xhtml:p>The language server protocol exposes features like (per the
neovim documentation) "go-to-definition, find-references, hover,
completion, rename, format, refactor, etc., using semantic
whole-project analysis."</xhtml:p>
<xhtml:p>In practice, this means the following:</xhtml:p>
<xhtml:ul>
<xhtml:li>You get signature hints. In PHP, this will pick up hints from
the signature, but also hints from docblocks.</xhtml:li>
<xhtml:li>You get completion. Hitting <xhtml:code>&lt;Tab&gt;</xhtml:code>, you'll
see a list of possible matches.
<xhtml:ul>
<xhtml:li>When in PHP, if the match is for a class name, it will add the
import statements for you.</xhtml:li>
<xhtml:li>Also in PHP, if the match is for a method that exists in an
implemented interface or a parent class, it will complete the
signature for you, and perform any imports required.</xhtml:li>
</xhtml:ul>
</xhtml:li>
<xhtml:li>If your cursor is on something like a property name, a method
name, a class name, or more, you can jump to the definition (I have
this mapped to <xhtml:code>gd</xhtml:code>, for "<xhtml:strong>g</xhtml:strong>o to
<xhtml:strong>d</xhtml:strong>efinition).</xhtml:li>
<xhtml:li>Depending on the language server in use, you may also get the
ability to do limited refactoring, such as changing a
variable/property name throughout a file, or renaming a method and
all calls to it.</xhtml:li>
</xhtml:ul>
<xhtml:p>Interestingly enough, the LSP is what is used under-the-hood by
IDEs like VS Code, so I'm getting the same features I'd get using a
dedicated IDE!</xhtml:p>
<xhtml:p>These features helped me so much, I ponied up for an <xhtml:a href="https://intelephense.com/">Intelephense</xhtml:a> license.</xhtml:p>
<xhtml:h3>If neovim already supports language servers natively, why use
coc.nvim?</xhtml:h3>
<xhtml:p>I use a variety of languages, and the configuration for each
varies widely. On top of that, when I started using neovim, I
wasn't yet familiar with Lua, which is how you configure things
like the LSP. But even once I learned... the documentation for the
various LSP implementations is often missing or inscrutable; it's
hard to know what options are available, and how to modify the
behavior programmatically.</xhtml:p>
<xhtml:p>coc.nvim just takes care of it, gives me a single location for
configuration, gives me a single set of keybindings to remember,
and provides a unified interface for operations like jumping to
definitions, performing refactors, and more.</xhtml:p>
<xhtml:p>Less futzing, more working.</xhtml:p>
<xhtml:h3>Why was this helpful?</xhtml:h3>
<xhtml:p>Prior to adopting coc.nvim, I used things like <xhtml:a href="https://ctags.sourceforge.net/">ctags</xhtml:a> to provide some limited
completion and ability to jump to definitions. However, this was
problematic in that I would forget to regenerate ctags for a
project when I added or changed dependencies, as well as when
adding my own code; they were always out-of-date. Using them, I
ended up having to keep a mental map in my head of the project, so
that I could open the class file with a definition when needing to
understand what the signature allowed, or what the method returned.
This approach was fine when I was doing development every day, or
working on familiar code bases, but often neither of these are true
anymore.</xhtml:p>
<xhtml:h3>Why not just use a "real" IDE?</xhtml:h3>
<xhtml:p>Listen, IDEs are great. But even when I've taken time to get to
know an IDE, I've found I'm just not as productive when using one.
Vim and its descendants are highly optimized for touch typists, and
make movement and selection ridiculously fast compared to using a
mouse, trackpad, or visual pointer.</xhtml:p>
<xhtml:p>Having tools like coc.nvim allow me to get some of the chief
benefits of an IDE from within my preferred editor. Sure, I don't
get advanced refactoring tools, but I can always reach for <xhtml:a href="https://getrector.com/">Rector</xhtml:a> when I need to. Debugging?
<xhtml:a href="https://github.com/vim-vdebug/vdebug">vim-debug</xhtml:a> gives
me most of what I would need, and I can reach for a visual IDE if I
need more granular control.</xhtml:p>
<xhtml:p>The LSP and coc.nvim give me the best of both worlds: excellent
tooling for a touch typist, with IDE features that give contextual
information when I need it.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2023-12-17-advent-vim-coc.html">Advent 2023:
(n)vim Plugins: coc.nvim</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2023-12-17T13:32:00-06:00">17 December
2023</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Advent 2023: (n)vim Plugins: tabular]]></title>
    <published>2023-12-16T14:56:00-06:00</published>
    <updated>2023-12-16T14:56:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2023-12-16-advent-vim-tabular.html"/>
    <id>https://mwop.net/blog/2023-12-16-advent-vim-tabular.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p><xhtml:a href="/blog/2023-12-15-advent-vim-surround.html">Yesterday, I
discussed vim-surround</xhtml:a>. Today I'm going to discuss another
plugin I've used a ton: <xhtml:a href="https://github.com/godlygeek/tabular">tabular</xhtml:a>.</xhtml:p>
<xhtml:h3>What problem does it solve?</xhtml:h3>
<xhtml:p>Let's say you have a PHP associative array declaration:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">[
    <xhtml:span class="hljs-string">"name"</xhtml:span> =&gt; <xhtml:span class="hljs-string">"Matthew"</xhtml:span>,
    <xhtml:span class="hljs-string">"status"</xhtml:span> =&gt; <xhtml:span class="hljs-string">"online"</xhtml:span>,
    <xhtml:span class="hljs-string">"url"</xhtml:span> =&gt; <xhtml:span class="hljs-string">"https://mwop.net"</xhtml:span>
]
</xhtml:code></xhtml:pre>
<xhtml:p>Now, for some folks, this declaration is fine. However, I tend
to prefer aligning the declarations, as it helps me visually parse
the block more easily.</xhtml:p>
<xhtml:p>Now, I could go to each line, and insert space before the
<xhtml:code>=&gt;</xhtml:code> assignment operators. This works, and for a
short declaration like in this example, it's relatively quick. But
when the declaration is larger, or the sizes of the keys vary a
lot, this can become tedious quickly.</xhtml:p>
<xhtml:p>Another place I've used it is Markdown tables:</xhtml:p>
<xhtml:pre><xhtml:code class="language-markdown hljs markdown" data-lang="markdown">| Name | Status | URL |
| ---- | ------ | --- |
| Matthew | online | mwop.net |
| An Example | offline | example.com |
| API | online | api.example.com |
</xhtml:code></xhtml:pre>
<xhtml:p>This demonstrates the problem even better, as you can see that
the columns do not align, which makes understanding if each row has
all the required columns harder.</xhtml:p>
<xhtml:h3>Tabular</xhtml:h3>
<xhtml:p>The tabular plugin allows you to easily <xhtml:em>tabularize</xhtml:em>
text. You visually select the rows you want to line up, and then
invoke it, providing a <xhtml:em>search</xhtml:em> string (a regular
expression) for matching the character(s) to align against. It then
does the work of determining how much space to add to each column
to get things to line up.</xhtml:p>
<xhtml:p>Going back to the original example, I'd select all the entries
within the array, and then:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>:</xhtml:code> to enter command mode</xhtml:li>
<xhtml:li><xhtml:code>Tabularize /=&gt;</xhtml:code> to invoke tabular, and tell it
to align against <xhtml:code>=&gt;</xhtml:code></xhtml:li>
<xhtml:li><xhtml:code>Enter</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p>and then you get:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">[
    <xhtml:span class="hljs-string">"name"</xhtml:span>   =&gt; <xhtml:span class="hljs-string">"Matthew"</xhtml:span>,
    <xhtml:span class="hljs-string">"status"</xhtml:span> =&gt; <xhtml:span class="hljs-string">"online"</xhtml:span>,
    <xhtml:span class="hljs-string">"url"</xhtml:span>    =&gt; <xhtml:span class="hljs-string">"https://mwop.net"</xhtml:span>
]
</xhtml:code></xhtml:pre>
<xhtml:p>In the second example, I'd select all rows, including the
header, and use <xhtml:code>|</xhtml:code> as the search. This results in:</xhtml:p>
<xhtml:pre><xhtml:code class="language-markdown hljs markdown" data-lang="markdown">| Name       | Status  | URL             |
| ----       | ------  | ---             |
| Matthew    | online  | mwop.net        |
| An Example | offline | example.com     |
| API        | online  | api.example.com |
</xhtml:code></xhtml:pre>
<xhtml:blockquote>
<xhtml:h4>Hint: use your tab key</xhtml:h4>
<xhtml:p>The Tab key is your friend, both in vim's command mode, as well
as in your shell. I generally type <xhtml:code>:Tabu[Tab]</xhtml:code>, and it
expands to <xhtml:code>:Tabularize</xhtml:code> for me. And, of course, you
could bind it to a keystroke or function if you wanted.</xhtml:p>
</xhtml:blockquote>
<xhtml:h3>However...</xhtml:h3>
<xhtml:p>Interestingly, I use tabular less and less.</xhtml:p>
<xhtml:p>Why?</xhtml:p>
<xhtml:p>My coding standard tools can do code alignment, and since I have
to run this anyways, I can save myself some time by just
<xhtml:em>not</xhtml:em> doing alignment during my coding session.</xhtml:p>
<xhtml:p>With markdown tables, my current markdown plugins and language
server configuration autoindents for me. As I finish a row, it
automatically reformats the table to tabularize everything, which
means I don't need to take any extra steps to format.</xhtml:p>
<xhtml:h3>Final Thoughts</xhtml:h3>
<xhtml:p>I keep this plugin around because when I <xhtml:em>do</xhtml:em> need it,
it's super convenient, less error-prone than doing it manually, and
saves me time.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2023-12-16-advent-vim-tabular.html">Advent
2023: (n)vim Plugins: tabular</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2023-12-16T14:56:00-06:00">16
December 2023</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Advent 2023: (n)vim Plugins: vim-surround]]></title>
    <published>2023-12-15T17:43:00-06:00</published>
    <updated>2023-12-15T17:43:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2023-12-15-advent-vim-surround.html"/>
    <id>https://mwop.net/blog/2023-12-15-advent-vim-surround.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I've <xhtml:a href="https://mwop.net/blog/tag/vim">blogged about vim a
number of times</xhtml:a>. I've been using vim or its descendents for 22
years now; I switched to <xhtml:a href="https://neovim.io">neovim</xhtml:a> a
few years back, but it's compatible with the existing vim
ecosystem. (The primary differences, to my mind, are that it has a
more optimized engine which is more performant, and that you can
now configure and extend it using <xhtml:a href="https://www.lua.org">Lua</xhtml:a> if you want. Otherwise... it's just
vim.)</xhtml:p>
<xhtml:p>I used to "collect" plugins, but at this point, particularly
since switching over to neovim, I've reduced my plugins quite a
bit, to only those I use on a regular basis.</xhtml:p>
<xhtml:p>So, I figured today, I'd start a mini-series as part of my
Advent 2023 blogging, on some of my most used plugins.</xhtml:p>
<xhtml:p>Today's plugin: <xhtml:a href="https://github.com/tpope/vim-surround">vim-surround</xhtml:a>.</xhtml:p>
<xhtml:h3>What does it do?</xhtml:h3>
<xhtml:p>vim-surround, at it's heart, allows you to surround a selection
with a character or pair of characters.</xhtml:p>
<xhtml:p>Why is this useful?</xhtml:p>
<xhtml:p>Let's say you're writing an exception message, and suddenly
realize that you forgot to put it in quotes as you close the
parens:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">throw</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> RuntimeException(This is the <xhtml:span class="hljs-keyword">exception</xhtml:span> message I will present)
</xhtml:code></xhtml:pre>
<xhtml:p>Normally, I might use <xhtml:code>f(</xhtml:code> to jump to the first
paren, hit <xhtml:code>a</xhtml:code> to append at that point, and then hit
<xhtml:code>'</xhtml:code> to add the initial quote, and Esc to return to
normal mode. I'd repeat, but use <xhtml:code>t)</xhtml:code> to jump to the
character before the closing paren.</xhtml:p>
<xhtml:p>With vim-surround, I can leverage vim's selection strokes to
quickly do this.</xhtml:p>
<xhtml:ul>
<xhtml:li>Hit <xhtml:code>vi(</xhtml:code> from anywhere within the parentheses,
which selects everything between then. I can even do this when on
the ")" character; it performs the same selection.</xhtml:li>
<xhtml:li>Hit Shift-s to trigger vim-surround</xhtml:li>
<xhtml:li>Type <xhtml:code>'</xhtml:code> to surround the selected text with the
quotes.</xhtml:li>
</xhtml:ul>
<xhtml:p>This may not seem like much, but the amount of effort it saves
is tremendous:</xhtml:p>
<xhtml:ul>
<xhtml:li>I use it a ton when writing Markdown, to mark words or phrases
as italic (<xhtml:code>_</xhtml:code>), bold <xhtml:code>**</xhtml:code> (this one requires
doing the selection twice), or just to add quotes.</xhtml:li>
<xhtml:li>In HTML, I can use it to add tags! When you trigger
vim-surround, you can start typing a tag — e.g.
<xhtml:code>&lt;em&gt;</xhtml:code> — and vim-surround will wait until the tag
is complete, and then surround the selection with that tag.</xhtml:li>
<xhtml:li>In code, I'll often use it to surround a selection with parens
or square brackets, or add quotes (as demonstrated above).</xhtml:li>
</xhtml:ul>
<xhtml:h3>Sidebar: efficient selection</xhtml:h3>
<xhtml:p>Vim provides actions that give you the ability to select
(<xhtml:code>v</xhtml:code>), replace (<xhtml:code>c</xhtml:code>), delete
(<xhtml:code>d</xhtml:code>), and yank (<xhtml:code>y</xhtml:code>) text. These actions
operate on the selection you provide.</xhtml:p>
<xhtml:p>The selection <xhtml:code>w</xhtml:code> indicates to operate on the current
<xhtml:em>word</xhtml:em>, and by default, it operates from the current
position to the next <xhtml:em>word boundary</xhtml:em>. This is important: the
selection is really a <xhtml:em>boundary</xhtml:em> you wish to select
<xhtml:em>to</xhtml:em>.</xhtml:p>
<xhtml:p>There are modifiers you can provide for the selection: "i" means
"inner", and will select everything <xhtml:em>up to</xhtml:em> the boundary,
but not the boundary itself, but, more importantly, the boundary
<xhtml:em>to either side of the current position</xhtml:em>.t</xhtml:p>
<xhtml:p>There are some boundaries that are particularly interesting: "("
and ")", "{" and "}", "[" and "]", "&lt;"/"&gt;", and both quote
styles, when paired with "i" or "a" modifiers, will select
<xhtml:em>bewteen pairs</xhtml:em>.</xhtml:p>
<xhtml:p>In the example above, I used <xhtml:code>vi(</xhtml:code> to select
everything <xhtml:em>inside</xhtml:em> the parens. "a" means "all", and acts
like "i", but selects everything up to and including the boundary.
If I'd used <xhtml:code>vaw</xhtml:code> in the example, it would have selected
everything inside the parens, <xhtml:em>as well as</xhtml:em> the parens.</xhtml:p>
<xhtml:p>You can be really efficient in your text selection and
manipulation knowing these rules, and it's when using these rules
that vim-surround shines.</xhtml:p>
<xhtml:h3>Final Thoughts</xhtml:h3>
<xhtml:p>It's the simplicity of operations such as text selection and
using vim-surround that are a key reason for sticking with vim all
these years. They allow me to efficiently edit text without needing
to leave the home row of the keyboard, or requriing a mouse.</xhtml:p>
<xhtml:p>So far in my career, I've avoided RSI, and I credit tools like
this as a big part of that.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2023-12-15-advent-vim-surround.html">Advent
2023: (n)vim Plugins: vim-surround</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2023-12-15T17:43:00-06:00">15
December 2023</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Advent 2023: Logseq]]></title>
    <published>2023-12-01T23:59:59-06:00</published>
    <updated>2023-12-02T23:59:59-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2023-12-01-advent-logseq.html"/>
    <id>https://mwop.net/blog/2023-12-01-advent-logseq.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>In years past, folks across a variety of programming languages
have organized Advent events in December, to highlight different
tools, different frameworks, different programming practices, and
more, often inviting guests to author each post.</xhtml:p>
<xhtml:p>I thought I'd try an experiment: I've had a ton of ideas for
blog posts, many of them short, and just... never write them. What
if I were to do a personal advent, and write these up?</xhtml:p>
<xhtml:p>Let's see how far I get.</xhtml:p>
<xhtml:p>Today's topic: <xhtml:a href="https://logseq.com">Logseq</xhtml:a>.</xhtml:p>
<xhtml:h3>What was I trying to solve?</xhtml:h3>
<xhtml:p>For many years (over a decade), I kept a little knowledge base
of markdown files. I had a <xhtml:code>diary</xhtml:code> command that would
open a file named after the current day's date, creating it if it
didn't exist, in <xhtml:a href="https://www.vim.org">vim</xhtml:a>. I'd create
todo lists, notes from meetings, ideas I wanted to investigate,
even blog and email drafts.</xhtml:p>
<xhtml:p>When I needed to find something, I'd use a tool such as <xhtml:a href="https://beyondgrep.com">ack</xhtml:a> to search through all files.</xhtml:p>
<xhtml:p>It worked, but I noticed a lot of things:</xhtml:p>
<xhtml:ul>
<xhtml:li>For a long time, I'd have a TODO list for the day, and if I
didn't finish items, I'd copy them to the next day's file. This was
tedious, though at one point I created a script to make it easier.
But worse: I discovered that the list would grow and grow, and lead
to anxiety when I didn't finish them. (Occasionally, I'd toss items
off the list, in recognition that I'd likely never do them.)</xhtml:li>
<xhtml:li>Searching worked, but it was error prone. I'd often forget to
make search case insensitive. Or the terms would return too many
items. Because it was regular expression based searching, there was
no way to say "find all files with this search term that also
contain this other search term, but not necessarily in any
proximity to each other."</xhtml:li>
<xhtml:li>It was great while I was on a computer, but next to impossible
to use on a mobile or tablet. As such, I tended to use it for work
or for organizing programming projects, but not for the day-to-day.
And there's a lot I want to be able to come back to, much of it
when I'm not at my computer: recipes, lists of things to watch and
read, art inspiration, shopping lists, and more. So having a
file-based solution was not going to work.</xhtml:li>
</xhtml:ul>
<xhtml:p>I tried a few different things over time:</xhtml:p>
<xhtml:ul>
<xhtml:li>Evernote. I actually used this for a couple of years, mainly to
capture bookmarks, but cancelled it quite some time back (likely
around 2017) when I realized I was getting locked into an
ecosystem, and one that was increasingly moving away from how I
actually wanted to use it. And the fact that it didn't really allow
linking between notes, or have a vim mode made it something I
wouldn't open regularly.</xhtml:li>
<xhtml:li>Google Keep. This was installed by default on my Android phone,
and the data went with me... but it was difficult to use it on the
computer, and the search for it was really spotty, which was
surprising for a company that started as a search engine.</xhtml:li>
<xhtml:li><xhtml:a href="https://github.com/nextcloud/notes">Nextcloud
Notes</xhtml:a>. When I started using this, I imported my markdown
files... and my instance was too underpowered to handle the sheer
volume of notes I had. On top of that, once I got the notes
imported to Nextcloud, the Android app would choke trying to sync,
and was super slow when I would try to use it. And search... was
not great.</xhtml:li>
<xhtml:li><xhtml:a href="https://joplinapp.org">Joplin</xhtml:a>. This is an open
source app that works on top of either Nextcloud Notes, or just on
a filesystem. Again, I struggled with the sheer number of notes I
had, and the fact that I couldn't use it on mobile made it not a
great fit for me.</xhtml:li>
<xhtml:li><xhtml:a href="https://xwmx.github.io/nb/">nb</xhtml:a>. Somebody on
Mastodon recommended this a little over a year ago, and I dove in
as it was just markdown, vim, and the CLI. While it's text centric,
it also has things like search and todo lists and more... but this
was also it's hugest limitation: I couldn't feasibly use it on my
phone or from my tablet. On top of that, the way that lists worked,
and the fact that if you wanted project-specific lists you
essentially had to have separate collections, meant that I stuggled
to use it regularly or stick with it.</xhtml:li>
</xhtml:ul>
<xhtml:p>I've basically limped along, hopping from one solution to the
next, without fully settling on any due to limitations.</xhtml:p>
<xhtml:h3>What is Logseq?</xhtml:h3>
<xhtml:p>Logseq is a <xhtml:a href="https://en.wikipedia.org/wiki/Personal_knowledge_management">Personal
Knowledge Manager</xhtml:a> (PKM) application. PKM tools provide a way to
collect information, and, more importantly, surface it. There's
been a proliferation of these tools in the past years; you may have
heard of <xhtml:a href="https://obsidian.md">Obsidian</xhtml:a>, <xhtml:a href="https://www.notion.so">Notion</xhtml:a>, and <xhtml:a href="https://simplenote.com">SimpleNote</xhtml:a>. But the idea is not new;
things like <xhtml:a href="https://orgmode.org">Org Mode for emacs</xhtml:a>
have existed for ages, and some PKM ideas derive from the <xhtml:a href="https://zettelkasten.de/introduction/">Zettelkasten
method</xhtml:a>.</xhtml:p>
<xhtml:p>Logseq itself is an open source application, built using Node
and running in Electron; as such, it's cross-platform (I've used it
on Linux, Android, iOS, and Windows). It stores the actual content
as <xhtml:a href="https://www.markdownguide.org">Markdown</xhtml:a>, though it
uses tabs instead of spaces for indentation, and every line is a
bullet point (more on this later). Because it uses local file
storage, you can use <xhtml:a href="https://git-scm.org">git</xhtml:a> to
version files and sync between systems, or you can use any file
syncing you have available. (I've used <xhtml:a href="https://syncthing.net">Syncthing</xhtml:a>, <xhtml:a href="https://nextcloud.com">Nextcloud</xhtml:a>, and even OneDrive at work.)
The project rolled out a beta of a sync-as-a-service offering this
past year, but I appreciate that it's not necessary or required in
the least in order to use it.</xhtml:p>
<xhtml:h3>How does Logseq work?</xhtml:h3>
<xhtml:p>I started using this in late December or January of this past
year, and was quickly surprised by what it enabled.</xhtml:p>
<xhtml:p>Let me explain.</xhtml:p>
<xhtml:p>When you open Logseq, you start in the <xhtml:strong>Journal</xhtml:strong>.
This is a daily record, and once the day rolls over, it starts a
new one. 99% of my work is done in the journal, and this is
<xhtml:em>fantastic</xhtml:em>. It allows me to understand <xhtml:em>when</xhtml:em> I
learned something, had a meeting, or recorded a task. While you
<xhtml:em>can</xhtml:em> create separate pages, most of the stuff I want to
track is relatively ephemeral.</xhtml:p>
<xhtml:p>Next, you can <xhtml:strong>tag</xhtml:strong> pages. Let's say I'm writing
a note, and it's related to PHP; I can type <xhtml:code>#php</xhtml:code>, and
this becomes a link. If I click that link, it takes me to the page
— which may or may not exist. But even if it does <xhtml:em>not</xhtml:em>
exist, it will reference all the pages that link to it. This is a
cheap and easy way to organize things, and if I later want to add
notes specific to that page, I can; it then becomes a first-class
page in the system.</xhtml:p>
<xhtml:p>Tags are done as <xhtml:strong>metadata</xhtml:strong>, and metadata can be
applied at the page level or item level. Some, like <xhtml:code>tags::
{tag list}</xhtml:code> and <xhtml:code>due:: {date}</xhtml:code> are special to the
system, and will surface functionality. But they can be anything.
I've used them to be able to note page or item <xhtml:em>types</xhtml:em>,
people I have meetings with (which I link to the pages for each
person), and more.</xhtml:p>
<xhtml:p>You can also create <xhtml:strong>templates</xhtml:strong>. These are text
snippets that you want to re-use. As examples, for work, I created
templates for meetings (to allow me to indicate who the meeting was
with, when it happened, the agenda, any notes I took, and any
action items from it), and for weekly prioritization (more on that
later). At home, I created templates for bookmarks (so I could give
information on <xhtml:em>why</xhtml:em> I found the bookmark useful, the title
of the page, and related tags), and recipes (so I could tag the
type of food, specific ingredients, etc.).</xhtml:p>
<xhtml:p>Tagging pages makes it easy to <xhtml:strong>search</xhtml:strong>. I can
search, and if there's a page matching the keyword, I can go to it
and immediately see what other notes I've taken on that subject.
Even better, though, Logseq includes both some basic search
functionality that allows selecting for things like tags/pages,
attributes (such as whether or not something is a task), and free
text, and this can be done <xhtml:em>within the page itself</xhtml:em>,
allowing you to see what matches immediately.</xhtml:p>
<xhtml:p>You can also create <xhtml:strong>slash functions</xhtml:strong> that pull
in templates or evaluate to text. An example I use frequently is
one I installed from the Logseq marketplace, which creates a search
for tasks completed in the past week.</xhtml:p>
<xhtml:p>All of this brings me to another cool feature. I noted in the
description of Logseq that each line in a page is a bullet point.
Logseq creates hashes for each of these, which allows referencing
them.</xhtml:p>
<xhtml:p>This means you can:</xhtml:p>
<xhtml:ul>
<xhtml:li>Link to any page or <xhtml:em>item in a page</xhtml:em>.</xhtml:li>
<xhtml:li>Embed items <xhtml:em>anywhere</xhtml:em>. To do this, you right click on
the bullet for the item, which allows you to copy a block embed;
you then paste this in another page, and you see the content
<xhtml:em>right there</xhtml:em>, and can even manipulate it from there!</xhtml:li>
</xhtml:ul>
<xhtml:p>Because of all this functionality, Logseq <xhtml:em>surfaces relevant
information when you need it</xhtml:em>.</xhtml:p>
<xhtml:p>Did you <xhtml:em>schedule</xhtml:em> something in the future? If so, the
Journal will show you upcoming scheduled items — not all of them,
but the ones coming up <xhtml:em>soon</xhtml:em> (which you can define in the
configuration). You can create Journal pages for dates <xhtml:em>in the
future</xhtml:em>, and if they include todo items... those will show up
on the Journal as well, so you can remember. I often create Journal
pages ahead of time to create agendas for my one-on-ones; this
ensures that those fleeting thoughts of "I should ask them about
so-and-so" don't get forgotten when the day of the meeting rolls
around.</xhtml:p>
<xhtml:h3>How do I use Logseq?</xhtml:h3>
<xhtml:h4>Prioritization</xhtml:h4>
<xhtml:p>My prioritization template for work brings in two search
queries, one for pages with a <xhtml:em>project</xhtml:em> type that are
<xhtml:em>incomplete</xhtml:em>, another for <xhtml:em>incomplete tasks</xhtml:em> that are
not part of a project, which represents my backlog. This allows me
to go through each week and identify what on the backlog I can
and/or should work on in the coming week, cancel tasks I recognize
I will no longer do or which are no longer relevant, mark things as
done that I may have completed this past week without realizing a
task existed, and so on.</xhtml:p>
<xhtml:p>What I do is go through these items, and choose what I want to
work on. I then <xhtml:em>embed</xhtml:em> those items into the page for that
week, which gives me a list <xhtml:em>without duplication</xhtml:em>, and which
I can then reference later when I'm wanting to understand what I
did that week. I often also <xhtml:em>schedule</xhtml:em> items at that time,
to ensure they surface on my journal pages.</xhtml:p>
<xhtml:p>At the end of the week, I run the query to show what I completed
the past week on that prioritization page. This gives me an
excellent reference of what I <xhtml:em>actually</xhtml:em> did — which is
often far more than I'd planned on for the week! Often, if I find I
did not finish what I set out to do that week, I can tell at a
glance <xhtml:em>why</xhtml:em>: an unexpected request from my GM, a request
from marketing, additional customer calls, etc.</xhtml:p>
<xhtml:p>These features have allowed me to be more intentional in my
interactions with co-workers, ensure I'm more accountable to myself
and to others in ensuring I get work done, and allow me to be
better organized.</xhtml:p>
<xhtml:h4>Home cookbook</xhtml:h4>
<xhtml:p>I've tried a number of solutions for recipes in the past,
including building my own apps.</xhtml:p>
<xhtml:p>The problem is (a) maintaining those apps, and (b) being able to
find recipes when I need them.</xhtml:p>
<xhtml:p>For my personal Logseq instance, I created a template for
recipes so that they are in a common structure, and that template
includes metadata and tags so I can (a) find the original source if
I need it, and (b) search for recipes by ingredients I commonly
might have on hand.</xhtml:p>
<xhtml:p>I've got everything in it from recipes and tips for salting,
brining, and seasoning, to main dishes, to cocktails.</xhtml:p>
<xhtml:p>Want to do a Rum-based cocktail? Search for <xhtml:code>(and [[rum]]
[[cocktail]])</xhtml:code>. Need the instructions for brining and
roasting the annual turkey? Search for "turkey".</xhtml:p>
<xhtml:p>It's been magical.</xhtml:p>
<xhtml:h4>Weekend projects and household todos</xhtml:h4>
<xhtml:p>I often know that I need to do something around the house, but
forget by the time the weekend arrives. I now create these as tasks
in Logseq, with the tag "weekend". I can surface them quickly, and
even use the ability to embed links to items to create a todo list
for the weekend!</xhtml:p>
<xhtml:h3>Final words</xhtml:h3>
<xhtml:p>Would I recommend Logseq?</xhtml:p>
<xhtml:p>Wholeheartedly!</xhtml:p>
<xhtml:p>Look, it's not perfect. The Markdown it uses is tab-delimited,
and each line is a bullet point, which makes using it to draft blog
posts or other Markdown a bit of a pain. (I'm planning to write a
tool to convert to standard Markdown over my holiday break,
though!) But it <xhtml:em>is</xhtml:em> Markdown, and it even supports things
like blockquotes and fenced code blocks and tables, which gives a
wealth of ways to format text.</xhtml:p>
<xhtml:p>On top of that, it has a rich plugin architecture and ecosystem.
You can do whiteboards, embed drawing widgets (I created an
architectural diagram I shared with my engineering team using one
of these!), create Kanban boards, or even use it as a full-featured
calendar. One I use extensively is a plugin giving Vim bindings,
which allows me to move around and edit in ways that are relatively
familiar. If I absolutely have to, I can edit the files by hand
(though with the slight differences in Markdown, this can sometimes
introduce issues).</xhtml:p>
<xhtml:p>The fact that it is open source also means I can use it in
perpeituity, so long as I am able to compile it and/or find an
Electron version it works with. And because it's using plain text
and SQLite under the hood, I can take the data and use it however I
want.</xhtml:p>
<xhtml:p>Is it the right tool for <xhtml:em>you</xhtml:em>? I don't know. I think the
important thing is to try one of these tools and <xhtml:em>stick with
it</xhtml:em>. More and more functionality and content surfaces for me
the longer I use the tool, and this is true of any good tool, I've
found. (I'm still learning things in vim to this day, and it's been
23 years of use to me!)</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2023-12-01-advent-logseq.html">Advent 2023:
Logseq</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2023-12-01T23:59:59-06:00">1 December 2023</xhtml:time> on
<xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Vim Toolbox, 2010 Edition]]></title>
    <published>2010-12-15T07:49:00-06:00</published>
    <updated>2010-12-17T03:50:53-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/249-vim-toolbox-2010-edition.html"/>
    <id>https://mwop.net/blog/249-vim-toolbox-2010-edition.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I've been using <xhtml:a href="http://www.vim.org/">Vim</xhtml:a> for close
to a decade. I've often said that <xhtml:em>"Unix is my IDE"</xhtml:em> —
because Vim is built in the Unix philosophy, allowing me to pipe
input into it, out of it, and every which way I want. It fits very
nicely with the Unix philosophy of doing one task well, and
allowing redirection. I've found it ideal for web development in
general and PHP development specifically — in fact, I've had
excellent experiences in every language I've tried my hand at
developing in when using Vim.</xhtml:p>
<xhtml:p>Vim is also my chosen productivity suite. When I want to write a
document, I don't go into OO.o Writer or MS Word or some other word
processor; I open up a window and start typing. In most cases, I
can either cut and paste my work into other tools, or pipe it to
transformation tools. I worry about the <xhtml:em>content</xhtml:em> first, and
the <xhtml:em>presentation</xhtml:em> later… like any good MVC application.
;-)</xhtml:p>
<xhtml:p>Like any good tool, you have to invest time in it in order to
reap its benefits. My learning has, to date, fallen into three time
periods:</xhtml:p>
<xhtml:ul>
<xhtml:li>The initial months in which I first learned Vim, via vimtutor
and Steve Oualline's Vim book.</xhtml:li>
<xhtml:li>A period in 2006-2007 when I felt the need to make my coding
more efficient, and first started playing with exuberant-ctags and
omni-completion.</xhtml:li>
<xhtml:li>The last quarter of 2010 (yes, that's now) when I was
introduced to a number of new tools via Twitter.</xhtml:li>
</xhtml:ul>
<xhtml:p>So, this is my Vim Toolbox, 2010 edition.</xhtml:p>
<xhtml:h2>Getting Plugins</xhtml:h2>
<xhtml:p>I've added two primary ways to add new plugins to my
arsenal:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p><xhtml:a href="https://github.com/c9s/Vimana">Vimana</xhtml:a>, which is a
command-line tool for discovering, downloading, installing, and
upgrading scripts found on <xhtml:a href="http://www.vim.org">vim.org</xhtml:a>. It's not perfect, but if you know
the name of the script, and it's provided in either a <xhtml:a href="http://www.vim.org/scripts/script.php?script_id=1502">vimball</xhtml:a>
format and/or follows the Vim runtime file structure, it's a great
way to keep your plugins, syntax files, etc. up-to-date.</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p><xhtml:a href="http://tammersaleh.com/posts/the-modern-vim-config-with-pathogen">Vim
Pathogen</xhtml:a> allows you to install plugins as "bundles", allowing
you to keep them up-to-date separately, in their own file tree.
This looks like the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-vim hljs vim" data-lang="vim">.<xhtml:span class="hljs-keyword">vim</xhtml:span>/
    bundle/
        <xhtml:span class="hljs-keyword">vim</xhtml:span>-task/
            ftdetect/
            ftplugin/
            <xhtml:span class="hljs-keyword">syntax</xhtml:span>/
</xhtml:code></xhtml:pre>
<xhtml:p>In short, a "bundle" mimics the structure of a Vim
directory.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>The latter, Pathogen, is my preferred installation method of
choice at this point. Why? One acronym: DVCS.</xhtml:p>
<xhtml:p>A ton of popular Vim plugins are now being either developed or
mirrored on GitHub or other DVCS sites. This allows you to clone
them and then create a branch that's specific to your
configuration. As an example, the popular <xhtml:a href="http://www.vim.org/scripts/script.php?script_id=2540">snipMate
plugin</xhtml:a> has its key-bindings hard-coded — which causes problems
if you're already using those bindings. Which, if you're using any
form of omni-completion, is all too likely. I simply <xhtml:a href="https://github.com/weierophinney/snipmate.vim">cloned the snipMate
repo</xhtml:a>, and created a branch for my configuration (I use
<xhtml:code>&lt;Leader&gt;&lt;tab&gt;</xhtml:code> to invoke it).</xhtml:p>
<xhtml:p>Now, it gets even better: I've made <xhtml:a href="http://git.mwop.net/?a=summary&amp;p=vimrc">a git repository for
my Vim configuration</xhtml:a>; with judicious use of <xhtml:code>git
submodule</xhtml:code>, I can now add pathogen bundles as submodules of
my repository. Right now, I've got bundles for html5.vim,
mustache.vim, NErdtree, snipMate, TagList, vim-fugitive, vim-task,
and vimwiki. This keeps my repository lean, while retaining the
features I need and use daily.</xhtml:p>
<xhtml:p>As part of creating my Vim configuration repository, I also made
a few changes to facilitate the process. First, I moved
<xhtml:code>$HOME/.vimrc</xhtml:code> to <xhtml:code>$HOME/.vim/vimrc</xhtml:code>, and
symlinked the former to the latter. This allows me to keep all my
Vim configuration in one place.</xhtml:p>
<xhtml:p>Next, I moved my Vim view files outside the directory; this data
is volatile and constantly changing, and really does not need to be
versioned. These are now in my <xhtml:code>$HOME/.vim.view/</xhtml:code>
directory. Finally, I moved my tag files into a new
<xhtml:code>$HOME/.vim.tags/</xhtml:code> directory. More on that later, but,
again, the rationale is that this data is volatile and does not
need to be versioned.</xhtml:p>
<xhtml:h2>DVCS</xhtml:h2>
<xhtml:p>I mentioned I created a Git repository for my Vim configuration.
In part, this is due to the fact that I'm proficient with Git — I
use it day-in, day-out. Hg and other DVCS systems are also great;
I'm not using them nearly as often, however.</xhtml:p>
<xhtml:p>To that end, I'm now using <xhtml:a href="https://github.com/tpope/vim-fugitive">vim-fugitive</xhtml:a>. The
author boasts that it's "a Git wrapper so awesome, it should be
illegal"; I wouldn't necessarily go that far, but I do find it
incredibly useful. While I'm typically working in a console, I also
find myself in GVim windows regularly as well — and having a nice,
familiar interface to Git is very useful. If you use both Vim and
Git, I highly recommend checking out vim-fugitive.</xhtml:p>
<xhtml:h2>Filesystem Navigation and Projects</xhtml:h2>
<xhtml:p>At some point, unless you're one of those developers who likes
to code everything in a single file, you need to do some sort of
navigation. A couple years back, <xhtml:a href="http://zmievski.org/">Andrei Zmievski</xhtml:a> introduced me to
<xhtml:a href="http://www.vim.org/scripts/script.php?script_id=1658">NErdtree</xhtml:a>,
a dead-simple, colorized navigation. I use this every. single.
day.</xhtml:p>
<xhtml:p>I also use a tool called <xhtml:a href="http://www.vim.org/scripts/script.php?script_id=69">Project</xhtml:a>.
This tool allows you to specify "files of interest" to a project —
either by automatically scanning a tree, or manually. Additionally,
the way you specify the hierarchy can be entirely arbitrary —
allowing you to flatten the tree when it's getting in the way. I
use this tool regularly as well, though not quite as much as
NErdtree.</xhtml:p>
<xhtml:h2>Navigating Code</xhtml:h2>
<xhtml:p>One often touted feature of modern IDEs is code completion and
hinting. These are definitely useful features, particularly when
working on unfamiliar code, or code you haven't touched in some
time.</xhtml:p>
<xhtml:p>Vim actually has some great tools for this already. One is
built-in: omni-completion (<xhtml:code>:he new-omni-completion</xhtml:code> for
Vim's help on the feature). By default, it inspects the files in
open buffers to provide completion (assuming it has a definition
for that language and/or syntax highlighting) — but it can also
utilize <xhtml:em>tag</xhtml:em> files.</xhtml:p>
<xhtml:p>The built-in omni-completion for PHP is reasonable — you can
jump around by class names, function/method names, variables, etc.
It gets much, much more useful, however, when you utilize tag
files, as you don't need the files already open in order to get
completion. I've <xhtml:a href="/blog/134-exuberant-ctags-with-PHP-in-Vim.html">blogged about
ctags before</xhtml:a>; however, I've updated my scripts a bit.</xhtml:p>
<xhtml:p>First, exuberant-ctags is much more PHP aware now than when I
blogged. This means you don't need to do any special regex-fu in
order to properly identify abstract classes, interfaces, and
methods. Second, I found that I could generate a single script with
prompts to indicate the directory and tag file name. <xhtml:a href="http://git.mwop.net/?a=viewblob&amp;p=vimrc&amp;h=3a8ca75bcd6a28dbea2cee02f31d72e82f415e5b&amp;hb=c1a728c96fa593be5c570c78cac5dcb2b7052fd3&amp;f=bin/mkTags">
That script</xhtml:a> basically looks like this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash"><xhtml:span class="hljs-meta">#!/bin/sh</xhtml:span>
dir=<xhtml:span class="hljs-string">""</xhtml:span>
name=<xhtml:span class="hljs-string">""</xhtml:span>
<xhtml:span class="hljs-keyword">if</xhtml:span> [ <xhtml:span class="hljs-variable">$#</xhtml:span> -ge 2 ] ; <xhtml:span class="hljs-keyword">then</xhtml:span>
    <xhtml:span class="hljs-comment"># Two arguments: first is directory, second is "alias"</xhtml:span>
    dir=<xhtml:span class="hljs-variable">$1</xhtml:span>
    name=<xhtml:span class="hljs-variable">$2</xhtml:span>
<xhtml:span class="hljs-keyword">else</xhtml:span>
    <xhtml:span class="hljs-keyword">if</xhtml:span> [ <xhtml:span class="hljs-variable">$#</xhtml:span> -eq 1 ] ; <xhtml:span class="hljs-keyword">then</xhtml:span>
        <xhtml:span class="hljs-comment"># One argument: use as directory, and use basename of directory as alias</xhtml:span>
        dir=<xhtml:span class="hljs-variable">$1</xhtml:span>
        name=`basename <xhtml:span class="hljs-variable">$1</xhtml:span>`
    <xhtml:span class="hljs-keyword">else</xhtml:span>
        <xhtml:span class="hljs-comment"># Otherwise: prompt</xhtml:span>
        <xhtml:span class="hljs-built_in">echo</xhtml:span> <xhtml:span class="hljs-string">"Enter the path to a directory containing PHP code you wish"</xhtml:span>
        <xhtml:span class="hljs-built_in">echo</xhtml:span> <xhtml:span class="hljs-string">"to create tags for:"</xhtml:span>
        <xhtml:span class="hljs-built_in">read</xhtml:span> dir
        <xhtml:span class="hljs-built_in">echo</xhtml:span> <xhtml:span class="hljs-string">"Enter the name of the tagfile you wish to create:"</xhtml:span>
        <xhtml:span class="hljs-built_in">read</xhtml:span> name
    <xhtml:span class="hljs-keyword">fi</xhtml:span>
<xhtml:span class="hljs-keyword">fi</xhtml:span>

<xhtml:span class="hljs-built_in">echo</xhtml:span> <xhtml:span class="hljs-string">"Creating tags for directory '<xhtml:span class="hljs-variable">$dir</xhtml:span>' using alias '<xhtml:span class="hljs-variable">$name</xhtml:span>'"</xhtml:span>
<xhtml:span class="hljs-built_in">cd</xhtml:span> <xhtml:span class="hljs-variable">$dir</xhtml:span>
<xhtml:span class="hljs-built_in">exec</xhtml:span> ctags-exuberant -f ~/.vim.tags/<xhtml:span class="hljs-variable">$name</xhtml:span> \
-h <xhtml:span class="hljs-string">".php"</xhtml:span> -R \
--exclude=<xhtml:span class="hljs-string">"\.svn"</xhtml:span> \
--totals=yes \
--tag-relative=yes \
--fields=+afkst \
--PHP-kinds=+cf 
<xhtml:span class="hljs-built_in">echo</xhtml:span> <xhtml:span class="hljs-string">"[DONE]"</xhtml:span>
</xhtml:code></xhtml:pre>
<xhtml:p>Two things to note:</xhtml:p>
<xhtml:ul>
<xhtml:li>It creates the tag files in <xhtml:code>$HOME/.vim.tags/</xhtml:code>. I do
this as my tag files change fairly regularly, and can be
re-generated on the fly as needed. There's no reason to version
them.</xhtml:li>
<xhtml:li>Once generated, you need to load them. I created a "LoadTags"
Vim function that will load a tag file by the given name from the
<xhtml:code>$HOME/.vim.tags/</xhtml:code> directory. By default, I load the
ones I most commonly use (ZF1, ZF2, PHPUnit). Otherwise, a quick
<xhtml:code>:Ltag &lt;tag filename&gt;</xhtml:code> will load on-demand.</xhtml:li>
</xhtml:ul>
<xhtml:p>Once the tags are created, you can use Vim's normal tag features
to load files, jump to files, etc. The most common commands I use
are:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:code>:stag &lt;tagname&gt;</xhtml:code>, which splits the current
window and loads the given tag in the newly created split.</xhtml:li>
<xhtml:li><xhtml:code>&lt;Ctrl-w&gt;]</xhtml:code>, when on text you suspect of being
a tag (such as a classname), will split the current window and load
that tag file in the new pane.</xhtml:li>
</xhtml:ul>
<xhtml:p>These two commands I use constantly, and are huge timesavers — I
can basically use the code as my documentation.</xhtml:p>
<xhtml:p>Additionally, the main use of omni-completion is to give
tab-completion for known tags. This means that you can start
typing, hit <xhtml:code>&lt;Tab&gt;</xhtml:code>, and either have it
immediately complete, or give you a list of potential matches. It's
not quite as useful as a good IDE — it's not context-aware, so
you'll get <xhtml:strong>any</xhtml:strong> potential match from
<xhtml:strong>any</xhtml:strong> class — but it's better than nothing, provides
reasonable hinting, and helps protect you from spelling errors.</xhtml:p>
<xhtml:p>That said, there's also something to be said about just having
the signatures and prototypes of the various methods easily
accessible. For that, there's the <xhtml:a href="http://vim-taglist.sourceforge.net/">Vim TagList</xhtml:a> plugin. This
plugin will scan open files and produce a list of classes,
variables, and methods. With this list, you can get the method
prototypes, as well as jump directly to their definitions. Pressing
<xhtml:code>&lt;Space&gt;</xhtml:code> will show you the prototype,
<xhtml:code>&lt;CR&gt;</xhtml:code> will jump to it.</xhtml:p>
<xhtml:p>Between these two features (omni-completion with tags and
TagList), I have most of the useful features of any IDE immediately
available.</xhtml:p>
<xhtml:h2>Working With Code</xhtml:h2>
<xhtml:p>Since I sling code for a living, it's useful to have some
plugins and syntax highlighting to make working with code
easier.</xhtml:p>
<xhtml:p>First off, I've been experimenting with HTML5; as such, I added
the <xhtml:a href="https://github.com/othree/html5.vim">html5.vim</xhtml:a>
syntax highlighting as a Pathogen module. This adds support for a
bunch of HTML5-specific features, while retaining the fantastic
HTML support already in the official HTML syntax provided with
Vim.</xhtml:p>
<xhtml:p>Next, I use the <xhtml:a href="http://www.vim.org/scripts/script.php?script_id=967">php.vim</xhtml:a>
syntax file from vim.org. This particular syntax file has support
for PHP 5.3 features, which come in very handy while I'm coding for
ZF2. The author of this syntax has also created a script
(<xhtml:code>php_vimgen.php</xhtml:code>) for generating syntax files for core
classes as well as extensions using the Reflection API. I've
modified the tool in my repository to strip out the generated
syntax, and instead source it from the file created with the
<xhtml:code>php_vimgen.php</xhtml:code> script; I've also altered said script
to create the syntax in <xhtml:code>__DIR__ .
'/php_syntax_vimgen.vim'</xhtml:code>, ensuring I can always source it
from the same location. This allows me to keep my PHP syntax
highlighting up-to-date.</xhtml:p>
<xhtml:p>Finally, I use <xhtml:a href="http://www.vim.org/scripts/script.php?script_id=2540">snipMate</xhtml:a>,
a tool that emulates TextMate's "snippet" features. Basically, this
is dead-simple, templated code generation. You can write your own
files (<xhtml:a href="http://git.mwop.net/?a=tree&amp;p=vimrc&amp;h=5990c978d877f9dcad2a02239ae3af74bcb75ba4&amp;hb=c1a728c96fa593be5c570c78cac5dcb2b7052fd3&amp;f=snippets/php">I
did</xhtml:a>), or use those that come with it. Once you've got some
snippets, you type a word (usually a mnemonic for the operation
you're trying to perform), and it will either just spit up a
template, or optionally provide "prompts" for you to fill in (along
with variable completion!). Basically, I never code accessors and
mutators anymore; snipMate does these for me, with a little
prompting.</xhtml:p>
<xhtml:h2>Organization</xhtml:h2>
<xhtml:p>I use Vim day-in, day-out, for all sorts of things: mail,
drafting blog posts, drafting presentation outlines, taking meeting
notes, managing my todo list, and more. As such, I try to keep as
much of my "organization" within Vim — it's just easier.</xhtml:p>
<xhtml:p>I've tried a number of tools over the years. For a good 4 or 5
years, my primary tool was <xhtml:a href="http://www.vimoutliner.org/">VimOutliner</xhtml:a>. It provided decent
syntax, decent folding, and reasonable HTML generation from the
outline. However, in recent years, I feel the project had stalled,
and I also found that the way I wanted to use it had changed:
outlining is great, but I often want to use the outline as a
starting point for generating content; task tracking is fine, but I
found, for whatever reason, that the way VimOutliner handled task
status often didn't work well — either from a tooling or a syntax
standpoint.</xhtml:p>
<xhtml:p>At some point, <xhtml:a href="http://twitter.com/tswicegood">Travis
Swicegood</xhtml:a> introduced me to <xhtml:a href="http://code.google.com/p/vimwiki/">vimwiki</xhtml:a>. This tool provides
a personal wiki <xhtml:em>within</xhtml:em> Vim. This tool allowed me to
organize my notes in an ad-hoc, semi-hierarchical way, link back
and forth between them, and have not only reasonable in-editor
highlighting, but great HTML generation. This allowed me to ditch
VimOutliner for everything but task tracking. Once I made my "wiki"
directory a Git repository, I then received versioning basically
for free (especially with vim-fugitive, which makes it easy for me
to hit <xhtml:code>:Gwrite</xhtml:code> and <xhtml:code>:Gcommit</xhtml:code> when I create
and/or update files).</xhtml:p>
<xhtml:p>Another feature vimwiki provides is a "diary". You access it
using <xhtml:code>&lt;Leader&gt;w&lt;Leader&gt;w</xhtml:code>, which opens up a
new wiki page for the current day (or, if you already opened it
before, re-opens the one created earlier in the day). This is a
really useful tool for taking notes during meetings, or when doing
research, etc.</xhtml:p>
<xhtml:p>Couple these features with integrated search (<xhtml:code>:VWS
/pattern/</xhtml:code>), and vimwiki is <xhtml:em>the</xhtml:em> killer productivity
tool in my toolbox.</xhtml:p>
<xhtml:p>At another point, Travis then pointed out another tool: <xhtml:a href="https://github.com/samsonw/vim-task">vim-task</xhtml:a>. This is perhaps
the most dead-simple task tracker I've ever used; each line is a
task, and is either incomplete (starts with a "-"), or complete
(starts with a checkmark). A simple keybinding, which I've mapped
to <xhtml:code>&lt;Leader&gt;m</xhtml:code>, toggles status - and complete
items get highlighted in green and italicized, making you feel good
and giving a good visual queue as to what you've completed.</xhtml:p>
<xhtml:p>At some point, Travis also tossed out the idea that combining
vimwiki with vim-task would be useful — and I latched onto this
idea. I've now created <xhtml:a href="https://github.com/weierophinney/vimwiki/tree/feature/vim-task">a
fork of vimwiki with vim-task integration</xhtml:a>, which allows me to
keep my tasks and notes in a single place… and, since my wiki is
versioned, my tasks are as well.</xhtml:p>
<xhtml:h2>Various Oddities</xhtml:h2>
<xhtml:p>As I mentioned at the start of this post, I've been using Vim
for close to a decade. Part of the reason Vim was appealing to me
was due to the fact that it kept me in the "home row" of the
keyboard — which provides a huge amount of efficency. You don't
have to move to the arrow keys to scroll, no leaving the keyboard
for the mouse, etc. That said, some key combinations are difficult
to reach:</xhtml:p>
<xhtml:ul>
<xhtml:li>The placement of the <xhtml:code>&lt;Esc&gt;</xhtml:code> key varies from
keyboard to keyboard, and is rarely in a place that is easy to
reach. On my current keyboard, it's in the top left corner, above
the function keys; it's impossible to reach without moving my hand.
A tip I picked up pretty much when I began using Vim was to map
<xhtml:code>jj</xhtml:code> to <xhtml:code>&lt;Esc&gt;</xhtml:code>; it's rare to type a
<xhtml:code>j</xhtml:code> repeatedly in the English language, and it's
dead-center on the home row. This is incredibly efficent.</xhtml:li>
<xhtml:li>I've mapped my Caps Lock key to <xhtml:code>&lt;Ctrl&gt;</xhtml:code> on
every system I've owned in the past decade. I never used it, and
it's almst always on the home row. Again, hugely efficient.</xhtml:li>
<xhtml:li>Keybindings are great, but there's so many already in use that
it's hard <xhtml:em>not</xhtml:em> to overwrite existing ones. Using the
<xhtml:code>&lt;Leader&gt;</xhtml:code> key to define keybindings has been
great. As examples, I mapped <xhtml:code>&lt;Leader&gt;m</xhtml:code> to toggle
tasks, and <xhtml:code>&lt;Leader&gt;&lt;Tab&gt;</xhtml:code> to invoke
snipMate.</xhtml:li>
</xhtml:ul>
<xhtml:p>In Vim, <xhtml:code>&lt;C-m&gt;</xhtml:code> has long been the "make"
binding, and <xhtml:code>&lt;C-l&gt;</xhtml:code> for linters. In languages
like PHP and JavaScript, these often don't make sense. However,
I've bound these in both languages — in PHP, "make" executes the
current script using the PHP executable, while "lint" runs it
through the PHP linter. In JS, I leave "make" unbound, while "lint"
runs the script through jslint.</xhtml:p>
<xhtml:p>I've also added the "php-doc.vim" plugin, and mapped
<xhtml:code>&lt;C-P&gt;</xhtml:code> to create PHP docblocks; the plugin is
context aware, and will create appropriate annotations.</xhtml:p>
<xhtml:h2>Cloning my repo</xhtml:h2>
<xhtml:p>As noted, I've created a repository for my Vim configuration. If
you want to clone it and explore it, you can do so as follows:</xhtml:p>
<xhtml:ul>
<xhtml:li>Browse the repository: <xhtml:a href="http://git.mwop.net/?a=summary&amp;p=vimrc">http://git.mwop.net/?a=summary&amp;p=vimrc</xhtml:a></xhtml:li>
<xhtml:li>Clone the repo: <xhtml:code>git clone
git://mwop.net/vimrc.git</xhtml:code></xhtml:li>
</xhtml:ul>
<xhtml:p>Be aware that there a number of git submodules in play (all the
pathogen modules are git submodules). To initialize these, simply
run <xhtml:code>git submodule init</xhtml:code> followed by <xhtml:code>git submodule
update</xhtml:code> after you clone the repository.</xhtml:p>
<xhtml:h2>Resources</xhtml:h2>
<xhtml:p>I didn't learn all this overnight. As with any toolset, it's
only as good as the amount of time you invest learning it. For me,
my primary resources lately have been:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:a href="http://twitter.com/#!/search/%23vim">#vim hashtag on
Twitter</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="http://vimcasts.org/">VimCasts</xhtml:a> are a fantastic
source of information, provided by Drew Neil. Seriously, these are
<xhtml:strong>completely</xhtml:strong> worth the time spent watching
them.</xhtml:li>
<xhtml:li><xhtml:a href="http://twitter.com/tswicegood">Travis Swicegood</xhtml:a>
has tweeted a number of times about interesting things he does with
Vim and Git, and inspired me to write the vim-task syntax for
vimwiki.</xhtml:li>
</xhtml:ul>
<xhtml:h2>More Tools</xhtml:h2>
<xhtml:p>This post has been on my <xhtml:em>Vim</xhtml:em> toolbox. I've also been
usig a number of other tools lately — <xhtml:a href="http://tmux.sourceforge.net/">tmux</xhtml:a>, <xhtml:a href="http://www.zsh.org/">zsh</xhtml:a> (in particular, git prompts),
<xhtml:a href="http://hotot.org/">Hotot</xhtml:a> (GTK2 + WebKit Twitter
client), and more; I may blog about those in the future — using
Vim. ;-)</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/249-vim-toolbox-2010-edition.html">Vim
Toolbox, 2010 Edition</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2010-12-15T07:49:00-06:00">15 December
2010</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Vimgrep and Vim Project]]></title>
    <published>2008-10-21T07:36:49-05:00</published>
    <updated>2008-10-22T21:55:03-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/194-Vimgrep-and-Vim-Project.html"/>
    <id>https://mwop.net/blog/194-Vimgrep-and-Vim-Project.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>Chris Hartjes today was <xhtml:a href="http://www.littlehart.net/atthekeyboard/2008/10/20/vim-programming-bounty-fuzzyfind-inside-files/">
on a quest for a "find in project" feature for Vim</xhtml:a>. "Find in
Project" was a feature of Textmate that he'd grown accustomed to
and was having trouble finding an equivalent for.</xhtml:p>
<xhtml:p>The funny thing is that Textmate is a newcomer, and, of course,
vim has had such a feature for years. The thing to remember with
vim, of course, is its unix roots; typically if you know the unix
command for doing something, you can find what you need in vim. In
this case, the key is the vimgrep plugin, which ships in the
standard vim distribution.</xhtml:p>
<xhtml:p>There are a variety of resources on vimgrep. The vim
documentation includes a chapter on it, and a quick <xhtml:a href="http://www.google.com/search?q=vimgrep">google search</xhtml:a> on the
subject turns up some nice tutorials immediately. If you've ever
used grep, the syntax is very straightforward:</xhtml:p>
<xhtml:pre><xhtml:code class="language-markdown hljs markdown" data-lang="markdown">vimgrep /{pattern}/[<xhtml:span class="hljs-string">g</xhtml:span>][<xhtml:span class="hljs-symbol">j</xhtml:span>] {file} ...
</xhtml:code></xhtml:pre>
<xhtml:p>The "g" option indicates that all matches for a search will be
returned instead of just one per line, and the "j" option tells vim
<xhtml:em>not</xhtml:em> to jump to the first match automatically. What does
the "g" flag really mean, though, and how are searches
returned?</xhtml:p>
<xhtml:p>Vimgrep returns search results in what's known as a "quickfix"
window, and this is where the vimgrep documentation falls apart… it
doesn't explain what this is, or link to it (which would be a nice
indication that it actually has a separate topic for this).</xhtml:p>
<xhtml:p>The Quickfix window is a pane that shows a search result per
line. Each line shows the file that matches, the line number, and
the contents of that line:</xhtml:p>
<xhtml:pre><xhtml:code class="language-awk hljs awk" data-lang="awk"><xhtml:span class="hljs-regexp">/home/m</xhtml:span>atthew<xhtml:span class="hljs-regexp">/git/</xhtml:span>bugapp<xhtml:span class="hljs-regexp">/application/</xhtml:span>controllers<xhtml:span class="hljs-regexp">/helpers/</xhtml:span>GetForm.php|<xhtml:span class="hljs-number">10</xhtml:span>| * @var Zend_Loader_PluginLoader
</xhtml:code></xhtml:pre>
<xhtml:p>You can't do much from this window; it simply serves as a visual
indicator of what file you're currently looking at from the list.
However, in the main window, you can start iterating through the
results one at a time, using a subset of the Quickfix commands. As
a quick summary:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>:cc</xhtml:strong> will move to the next match in the
list</xhtml:li>
<xhtml:li><xhtml:strong>:cn</xhtml:strong> will move to the next match in the
list</xhtml:li>
<xhtml:li><xhtml:strong>:cp</xhtml:strong> will move to the previous match in the
list</xhtml:li>
<xhtml:li><xhtml:strong>:cr</xhtml:strong> will rewind to the first match in the
list</xhtml:li>
<xhtml:li><xhtml:strong>:cla</xhtml:strong> will fast forward to the last match in
the list</xhtml:li>
</xhtml:ul>
<xhtml:p>When done, you can simply close the Quickfix window/pane, and
continue working.</xhtml:p>
<xhtml:p>I should note that vimgrep <xhtml:em>is</xhtml:em> cross-platform. On
*nix-based systems, it defaults to using the native grep command,
but it also contains an internal (slower) implementation for use on
operating systems that do not provide grep by default. You may also
map the command to alternate implementations if desired.</xhtml:p>
<xhtml:p>I personally use this feature most with the <xhtml:a href="http://www.vim.org/scripts/script.php?script_id=69">project
plugin</xhtml:a>. Project maps vimgrep to two different commands:
<xhtml:code>&lt;Leader&gt;g</xhtml:code> and <xhtml:code>&lt;Leader&gt;G</xhtml:code>. The
first will grep all files in the current project at the current
level; the second does the same, but also recurses into
subprojects. This is an incredibly easy way to refactor code,
particularly for name changes.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/194-Vimgrep-and-Vim-Project.html">Vimgrep
and Vim Project</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2008-10-21T07:36:49-05:00">21 October
2008</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Vim Productivity Tips for PHP Developers]]></title>
    <published>2008-03-22T10:41:26-05:00</published>
    <updated>2008-03-25T11:39:35-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/164-Vim-Productivity-Tips-for-PHP-Developers.html"/>
    <id>https://mwop.net/blog/164-Vim-Productivity-Tips-for-PHP-Developers.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I use <xhtml:a href="http://www.vim.org/">Vim</xhtml:a> for all my editing
needs — TODO lists, email, presentation outlines, coding in any
language… everything. So, I thought I'd start sharing some of my
vim habits and tools with others, particularly those that pertain
to using Vim with PHP.</xhtml:p>
<xhtml:h3>Mapping the PHP interpreter and linter to keystrokes</xhtml:h3>
<xhtml:p>Probably the most useful thing I've done as a PHP developer is
to add mappings to run the current file through (a) the PHP
interpreter (using <xhtml:code>Ctrl-M</xhtml:code>), and (b) the PHP
interpreter's linter (using <xhtml:code>Ctrl-L</xhtml:code>). These are
accomplished with the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-asciidoc hljs asciidoc" data-lang="asciidoc">" run file with PHP CLI (CTRL-M)
<xhtml:span class="hljs-meta">:autocmd FileType php noremap &lt;C-M&gt; :w!&lt;CR&gt;:!$HOME/bin/php</xhtml:span> %&lt;CR&gt;

" PHP parser check (CTRL-L)
<xhtml:span class="hljs-meta">:autocmd FileType php noremap &lt;C-L&gt; :!$HOME/bin/php</xhtml:span> -l %&lt;CR&gt;
</xhtml:code></xhtml:pre>
<xhtml:p>(I have <xhtml:code>\~/bin/php</xhtml:code> as my PHP interpreter, which
allows me to run PHP with a custom config file, as well as to
change which PHP binary I'm using.)</xhtml:p>
<xhtml:p>These two commands allow me to quickly and easily check that my
syntax is okay, as well as to run unit test suites easily.</xhtml:p>
<xhtml:h3>Vim Project</xhtml:h3>
<xhtml:p>Next up is the excellent <xhtml:a href="http://www.vim.org/scripts/script.php?script_id=69">Project
plugin</xhtml:a>.</xhtml:p>
<xhtml:p>"Project", at its most basic, allows you to setup a navigation
pane with a list of files related to your project. The files are
typically organized by directory, but the beauty is that the
hierarchy can be defined however it makes sense for your given
project. It also has tools for creating projects based on a given
directory, recursively pulling in files based on filters you
specify. Type <xhtml:code>:help project</xhtml:code> to get documentation on
this after you install it; <xhtml:code>\C</xhtml:code> will help you create
your first project.</xhtml:p>
<xhtml:p>Each project can consist of one or more project folds; these can
be sub projects, or a self-defined hierarchy or grouping of files.
For instance, in my Zend Framework project file, I have "library",
"tests", and "documentation" folds — "library" points to
"library/Zend/", "tests" points to "tests/", and "documentation"
points to "documentation/manual/en/". Within each, I then have
folds for each subdirectory. Since directories and subprojects are
specified as folds, you can use Vim's native folding mechanisms to
keep only the file of interest visible, which is very handy.</xhtml:p>
<xhtml:p><xhtml:img src="/uploads/2008-03-22-VimProject.png" alt="Vim Project"/></xhtml:p>
<xhtml:p>Basically, Project allows vim to act like a minimal IDE. With
the file list on the left, you simply hit enter on a file, and it
loads in the main pane. More fun is when you use the
<xhtml:code>\S</xhtml:code> command, which will split the main pane and load
the file into the new pane. This is particularly useful when doing
Test Driven Development, as you can have one pane for the unit test
code, and another for the class file, allowing you to jump back and
forth between them. Add to this the <xhtml:code>Ctrl-M</xhtml:code> and
<xhtml:code>Ctrl-L</xhtml:code> commands I listed earlier, and you're now also
able to quickly and easily check your files for syntax errors and
run tests directly within the Vim window.</xhtml:p>
<xhtml:p><xhtml:img src="/uploads/2008-03-22-VimUnitTests.png" alt="Vim Project"/></xhtml:p>
<xhtml:p>There are other commands, too. You can run all files through a
particular script, grep all files in a project, map particular file
types to specific launchers, etc. Combine it with other Vim
functionality, and you have a minimal, yet powerful, IDE at your
disposal that launches in under a second.</xhtml:p>
<xhtml:p>By default, Project stores projects in
<xhtml:code>$HOME/.vimprojects</xhtml:code>. I find that I don't necessarily
want all my projects at any given time, so I've created a
<xhtml:code>$HOME/.projects/</xhtml:code> directory that has a project entry
for each project — I simply save the contents of a project fold to
files under this tree. I can then perform <xhtml:code>:r
~/.projects/&lt;projectname&gt;</xhtml:code> to read in a given project
when I want to work on it. This helps me keep my workspace
uncluttered, and also helps me focus on a given project at a
time.</xhtml:p>
<xhtml:h3>Ctags</xhtml:h3>
<xhtml:p>I've <xhtml:a href="/blog/134-exuberant-ctags-with-PHP-in-Vim.html">covered ctags</xhtml:a>
elsewhere, so I won't cover them here, but with ctags defined, I
get tab completion for most classes and methods (and Vim takes care
of tab-completion for class members in the current class file), as
well as the ability to quickly and easily open class files for
classes I've tagged — which is useful when you want to see what
methods are available and how they work.</xhtml:p>
<xhtml:hr/>
<xhtml:p>I'll try and cover other vim techniques I use in upcoming blog
entries. Those listed in here, though, have greatly increased my
productivity, and are things I use daily.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/164-Vim-Productivity-Tips-for-PHP-Developers.html">
Vim Productivity Tips for PHP Developers</xhtml:a> was originally
published <xhtml:time class="dt-published" datetime="2008-03-22T10:41:26-05:00">22 March 2008</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[exuberant ctags with PHP in Vim]]></title>
    <published>2007-01-31T14:20:00-06:00</published>
    <updated>2010-03-25T16:18:59-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/134-exuberant-ctags-with-PHP-in-Vim.html"/>
    <id>https://mwop.net/blog/134-exuberant-ctags-with-PHP-in-Vim.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>One reason I've heard PHP developers use for adopting an IDE
when developing is the ability to click on a class or function name
and jump to the declaration. Sounds like magic, and it's definitely
something I've desired.</xhtml:p>
<xhtml:p>One way I get around it is by adopting PEAR coding standards for
naming my classes. Since they define a one-to-one mapping of class
name to the file system (substitute the underscore character
(<xhtml:code>_</xhtml:code>) with the directory separator), I can usually very
quickly and easily open a class file, particularly if I start in
the base directory of the project install.</xhtml:p>
<xhtml:p>Today, however, I found <xhtml:a href="http://ctags.sourceforge.net">exuberant ctags</xhtml:a>, a library which
can be used to generate an index file mapping language objects to
source files and the line in the source file where they are
declared. Contrary to its name, it's not just for the C language;
it currently supports 33 different programming languages, including
PHP.</xhtml:p>
<xhtml:p>I decided to try it out on the Zend Framework core library
today. At first run, it was pretty useful. However, it was only
mapping classes, and, in addition, only those defined with the
single word 'class' — abstract classes and interfaces were entirely
left out. So, I looked into the documentation to see if I could
change the behaviour.</xhtml:p>
<xhtml:p>And, being a Unix program, of course I could. First off, you can
add functions to the items it indexes with a simple flag.
Additionally, you can use POSIX regular expressions to refine what
it searches.</xhtml:p>
<xhtml:p>I whipped up the following script to create my tags index:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash"><xhtml:span class="hljs-meta">#!/bin/bash</xhtml:span>
<xhtml:span class="hljs-built_in">cd</xhtml:span> /path/to/framework/library
<xhtml:span class="hljs-built_in">exec</xhtml:span> ctags-exuberant -f ~/.vim/mytags/framework \
-h \".php\" -R \
--exclude=\"\.svn\" \
--totals=yes \
--tag-relative=yes \
--PHP-kinds=+cf \
--regex-PHP=<xhtml:span class="hljs-string">'/abstract class ([^ ]*)//c/'</xhtml:span> \
--regex-PHP=<xhtml:span class="hljs-string">'/interface ([^ ]*)//c/'</xhtml:span> \
--regex-PHP=<xhtml:span class="hljs-string">'/(public |static |abstract |protected |private )+function ([^ (]*)//f/'</xhtml:span>
</xhtml:code></xhtml:pre>
<xhtml:p>This script creates the tag index in the file
<xhtml:code>$HOME/.vim/mytags/framework</xhtml:code>. It scans for PHP files
recursively through the tree, excluding any files found in a
<xhtml:code>.svn</xhtml:code> directory (I'm using a checkout from the
subversion repository). The file paths in the index are created
relative to the tags file; this was important, because if this
wasn't provided, vim was unable to jump to the file, as it couldn't
find it. <xhtml:code>--PHP-kinds=+cf</xhtml:code> tells it to index classes and
functions. Next, I've got three regular expressions. The first
tells it to match classes beginning with 'abstract class' as
classes. The second tells it to match interfaces as classes. The
last is so that PHP 5 methods, which begin with a visibility
operator, to be matched as functions.</xhtml:p>
<xhtml:p>Once the index file is generated (it takes less than a second),
all you need to do in vim is tell it to load it: <xhtml:code>:set
tags=~/.vim/mytags/framework</xhtml:code>. At this point, you can do all
sorts of fun stuff. Place the cursor on a class name or method
name, anywhere in it, and hit <xhtml:code>Ctrl-]</xhtml:code>, and you'll jump
to the file and line of its declaration; <xhtml:code>Ctrl-T</xhtml:code> then
takes you back. If you change the invocation to <xhtml:code>Ctrl-W
]</xhtml:code>, it will split the current window and open the declaration
in the new pane. (If you're familiar with how help works with Vim,
this should seem pretty familiar.)</xhtml:p>
<xhtml:p>One more reason to stick with Vim for your PHP editing needs.
:-)</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/134-exuberant-ctags-with-PHP-in-Vim.html">exuberant
ctags with PHP in Vim</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2007-01-31T14:20:00-06:00">31 January
2007</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
</feed>
