The more I learn vim, the more I am impressed with the efficient ways it handles complex repetitive editing tasks:

My task is to transform a yaml file to a bunch of m4 definitions

# Welcome to Jekyll!
#
# This config file is meant for settings that affect your whole blog, values
# which you are expected to set up once and rarely edit after that. If you find
# yourself editing this file very often, consider using Jekyll's data files
# feature for the data you need to update frequently.
#
# For technical reasons, this file is *NOT* reloaded automatically when you use
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.

# Site settings
# These are used to personalize your new site. If you look in the HTML files,
# you will see them accessed via Kountanis, p@kountanis.com, and so on.
# You can create any custom variable you would like, and they will be accessible
# in the templates via .
title: Site
email: site@example.com
description: "some example site"
logo: false

baseurl: ""
url: "https://example.com"
permalink: ":year/:month/:day/:title/"
domain_name: "https://example.com"

# Details for the RSS feed generator
author: "anon"

# cache buster, increment when we have changes
cache_version: 2

excerpt_separator: ""


# plugin settings
paginate: 10
paginate_path: "/blog/page/:num"

# analytics

# highlighter: pygments
# baseurl: /


To transform this, I want to first remove all the comments. The most efficient way I figured was using global repeats:

:g/^#.*/normal dd

Cool! Now it looks like this:


title: Site
email: site@example.com
description: "some example site"
logo: false

baseurl: ""
url: "https://example.com"
permalink: ":year/:month/:day/:title/"
domain_name: "https://example.com"

author: "anon"

cache_version: 2

excerpt_separator: ""


paginate: 10
paginate_path: "/blog/page/:num"


Notice the blank lines.

Next step is, I need to transform each line into an m4 define statement. At first, I record a macro for doing it on one line:

<Esc>qaIdefine(<Esc>f:r,<Esc>A)<Esc>jq

Next, using another global repeat, I can execute this on lines that are nonempty, starting from the line I tested it in

<Esc>:3,$g/^\w/normal @a

After three neat, nonrepetitive, precise edits, the whole thing is transformed!


define(title, Site)
define(email, site@example.com)
define(description, "some example site")
define(logo, false)

define(baseurl, "")
define(url, "https://example.com")
define(permalink, ":year/:month/:day/:title/")
define(domain_name, "https://example.com")

define(author, "anon")

define(cache_version, 2)

define(excerpt_separator, "")


define(paginate, 10)
define(paginate_path, "/blog/page/:num")