fourside.github.io

Jekyllのpostをvim scriptで作る

2017/12/31 15:00:00 +00:00

問題

Jekyllでpost用のファイルを作るのがめんどくさい。

  • ファイル名が yyyy-mm-dd-{title}.md
    • 数字やハイフンなんて打ちにくいところにあるのに…
  • お決まりのテンプレートを書かなくちゃいけない
    • dateが特にめんどい
    • こんなの
---
layout: post
title: "記事のタイトル"
date: 2018-01-01 00:00:00 +0900
categories: vim
---

解決方法

vim pluginを探すと3つほどぱっと見つかるんだけど、欲しいものは簡単なものだし、自分でvim scriptを書いてみようと思った。

欲しいもの

  • コマンドを実行するとバッファが開かれ、そこにテンプレートが展開される
  • コマンドは複数の引数を受け取ってハイフンでつなぎ、それが yyyy-mm-dd-{title}.mdtitle になる
  • 吐き出す場所はひとまずカレントディレクトリでいいや

参考にしたもの

  • Vimスクリプト基礎文法最速マスター - 永遠に未完成
    • 数年前にもvim script書こうと思い立ったことがあって、ヘルプよりこっちを見てしまう
  • vim-jp » Vim script事始め
    • :h write-plugin が丁寧でvimはドキュメントしっかりしてるな~と思った
    • q-args というのを初めて知った。 args だとコマンドの引数を文字列として扱ってくれないので不便だなあと悩んでいた。
    • プラグインの2重ロードを防ぐイディオム、開発のとき邪魔だからコメントアウトしてたんだけど、うっかりコミットしそう
      • 何回でもロードしていいように書くのが正解なのかな
  • Vimスクリプトを書いてみよう — KaoriYa
    • わかりやすい
  • 自分のvimrc
    • 普段のメモを取るように、日付をファイル名にしたバッファを開くコマンドを作っていたのだった
    • それもどこからかコピーして持ってきたやつだったはず…

できたもの

長いので折りたたみたい…

" Vim global plugin for creating jekyll's post
" Last Change: 2018 Jun 01
" Maintainer: fourside <fourside@gmail.com>
" License: This file is placed in the public domain.
if exists("g:loaded_jekyll_post")
finish
endif
let g:loaded_jekyll_post = 1
let s:save_cpo = &cpo
set cpo&vim
let s:zone_offset = strftime('%z')
if has('win32')
let s:zone_offset = '+0900'
endif
let s:template = [
\ "---",
\ "layout: post",
\ "title: \"\"",
\ "date: " . strftime('%Y-%m-%d %H:%M:%S ') . s:zone_offset,
\ "categories: ",
\ "---",
\]
function! s:JekyllPost(...)
" variable-length args ignores a delimiter when joining
let title = join(split(join(a:000), " "), "-")
let filename = strftime('%Y-%m-%d-') . l:title . '.md'
execute ':edit ' . filename
if getfsize(filename) > 0
return
endif
call append(0, s:template)
endfunction
if !exists(":JekyllPost")
command -nargs=1 JekyllPost :call s:JekyllPost(<q-args>)
endif
let &cpo = s:save_cpo
unlet s:save_cpo
view raw jekyll-post.vim hosted with ❤ by GitHub

はまったところ

  • 可変長引数をjoinすると、デリミタが無視されてスペースで連結されてしまう
    • 仕方なく、joinしてsplitしてjoinした…
  • strftime('%z')から +0900 みたいなタイムゾーンのオフセットを得たいのだけど、Windowsだと 東京(標準時) が返ってきてしまう。

fourside

Written by fourside