Repeating the last ‘:’ (Ex) command in Vim

Sometimes I run a complicated search-and-replace (:s/../../) in Vim, and I then want to repeat it somewhere else. In the past, I have always hit :, up-arrow to retrieve the command from the history. It should be no surprise by now that there is an easier way!

@: in normal mode (at-sign, colon) will repeat the last : command. Once you have done @:, you can hit @@ to re-run the command. Quick and easy!

This works because the : register, ":, holds the last Ex command. @ runs a macro, and knows that using the : register means you want to repeat an Ex command. @@ runs the last macro, so works for @: just as it does for @a or any other normal-mode macro.

I found ": in :help registers when I was looking for a register that held the filename of the file open in another window, as opposed to the alternate filename in the current window. Details of ": are at :help ": (believe it or not! 😉 ).

Lightweight Markdown-to-PDF converter: pfft

I just released the first version of my new Markdown-to-PDF converter, pfft.  It runs on Linux, at least as far back as Ubuntu 18.04.

Why yet another converter when pandoc and many others already do the job?  Size.  Pandoc uses TeX to generate PDFs.  All the other converters I found use a Web browser in one way or another to make the PDF.  Pandoc is 50 MB by itself, not counting TeX!  In less than 1.2 MB (a 5.25″ floppy 😉 ) and a single file, pfft will do the job.

Of course, there is a catch: pfft uses Pango and Cairo to make the PDFs.  Those have their own dependencies, but are installed on many Ubuntu systems by default!  So pfft itself does not add to the dependency load those systems already carry.

(By the way, I use and appreciate both TeX and Pandoc.  They are great tools!  But, like all tools, there are some use cases they are not great at.  I wanted a small converter, and now I have one! 🙂 )

Please give pfft a try and let me know how it works for you!  And, if you’re planning to do Hacktoberfest this year, know that I am happy to receive pull requests — there’s lots of room for features and polish in pfft.  Check out the issues list for some ideas, and feel free to add suggestions of your own.  Happy hacking!

Generating Roman numerals in Vala

I have recently been learning and enjoying the Vala programming language.  I am writing a lightweight markdown-to-PDF converter and wanted to be able to automatically number list items in Roman numerals.  Here, in case anyone wants it, is Knuth’s algorithm for producing the Roman numeral for a number.  I converted this to Vala from the original WEB source, part of TeX, as quoted by Hans Wennborg.  Enjoy!

string roman(uint num)
{
    // Knuth's algorithm for Roman numerals, from TeX.  Quoted by
    // Hans Wennborg at https://www.hanshq.net/roman-numerals.html.
    // Converted to Vala by Chris White (github.com/cxw42).  CC-BY 4.0 Intl.

    var sb = new StringBuilder();

    string control = "m2d5c2l5x2v5i";
    int j, k;   // mysterious indices into `control`
    uint u, v;  // mysterious numbers
    j = 0;
    v = 1000;

    while(true) {
        while(num >= v) {
            sb.append_c(control[j]);
            num -= v;
        }
        if(num <= 0) {  // nonpositive input produces no output
            break;
        }

        k = j+2;
        u = v / control[k-1].digit_value();
        if(control[k-1] == '2') {
            k += 2;
            u /= control[k-1].digit_value();
        }

        if(num+u >= v) {
            sb.append_c(control[k]);
            num += u;
        } else {
            j += 2;
            v /= control[j-1].digit_value();
        }
    }

    return sb.str;
} // roman()

(not extensively tested — use at your own risk. No warranty. License details here.)

Git internals for fun and profit

Just ran across this very enjoyable article about how GitHub sped up cloning by several orders of magnitude – https://github.blog/2015-09-22-counting-objects/.

If you haven’t seen it, check out the git commit graph.  In the Linux kernel tree, the time for me to show the commit graph of the five most recent commits went from five seconds to 20ms!  https://devblogs.microsoft.com/devops/supercharging-the-git-commit-graph/.  Requires Git 2.18+, which you can install on Ubuntu LTS from a PPA per this.  Short version:

git config --global core.commitGraph true

and then, in each repo:

git show-ref -s | git commit-graph write --stdin-commits

Vim tips: curly quotes and visual selection

Curly quotes: because reasons.  😉  In Insert mode:

  • Ctl+K '6 will give you an open curly single quote, and Ctl+K '9 will give you the closing curly single quote.
  • Similarly, Ctl+K "6 will give you an open curly single quote, and Ctl+K "9 will give you the closing curly single quote.

Visual mode: turns out you can just hit o when in Visual mode to move the cursor to the other end of the selection.  Handy!

Installing Elementary Files on Ubuntu 18.04 LTS

I learned about elementary OS from Slashdot.  I currently use Nautilus and xfe, but am not 100% happy with either.  I thought I would give Elementary Files (the elementary OS file manager) a try.

  • sudo apt-get install -y ninja-build gobject-introspection libgirepository1.0-dev
  • Uninstall meson if you have it installed (e.g., sudo apt remove meson)
  • pip3 install meson – you need at least v0.50 (I think).
  • Add ~/.local/bin to your PATH if you haven’t yet.
  • sudo apt-get install -y valac libcanberra-dev libdbus-glib-1-dev libgail-3-dev libgee-0.8-dev libglib2.0-dev libgtk-3-dev libnotify-dev libpango1.0-dev libplank-dev libsqlite3-dev libunity-dev libzeitgeist-2.0-dev
  • libcloudproviders-dev (bionic’s package isn’t new enough): git clone https://gitlab.gnome.org/World/libcloudproviders.git ; cd libcloudproviders ; git checkout 0.3.0 ; meson build ; cd build ; ninja && sudo ninja install
  • libgranite-dev (bionic’s package isn’t new enough): git clone https://github.com/elementary/granite.git elementary-granite ; cd elementary-granite/ ; git checkout 5.2.5 ; meson build ; cd build ; ninja && sudo ninja install
  • Files (at last!): git clone https://github.com/elementary/files.git elementary-files ; cd elementary-files ; git checkout 4.2.0 ; meson build ; cd build ; ninja && sudo ninja install

Whew!  This is reminding me why we have package managers 🙂 .

Let me know if this doesn’t work for you — I may have missed something by accident.