Help us understand the problem. What is going on with this article?

vimを高機能なPDFリーダーにする設定

vimをPDFリーダーに仕上げるために、以下の仕様を満たすvim設定を作ります。

  • pdfファイルを開いたときにテキスト形式に変換して表示してほしい
  • 文字を変更しようとしたときに警告してほしい
  • j, kのカーソル移動を画面移動に割り当てたい
    • デフォルトではC-E, C-Yになっている
    • vimpagerっぽい挙動にしたい

最終的な設定

いきなり結論。次のautocmdを.vimrcに書く。

PDFを開いたときにテキストに変換して開くautocmd
augroup MyAutoCmd
    if executable('pdftotext')
        " PDFファイルを開いた時、text形式に変換してから開く
        autocmd BufRead *.pdf :enew | 0read !pdftotext -layout -nopgbrk "#" -
    endif
    " 圧縮ファイルとPDFファイルを開いた時、readonlyモードで開き、j/kキーマップを変更
    autocmd BufRead *.zip,*.gz,*.bz2,*.xz,*.pdf setlocal readonly nolist
        \| nn <buffer> j <C-E> | nn <buffer> k <C-Y>
augroup END

以下解説

pdfファイルを開いたときにテキスト形式に変換して表示してほしい

pdftotextというコマンドを使えるようにして1

autocmd BufRead *.pdf :enew | 0read !pdftotext -layout -nopgbrk "#" -

を実行します。
PDFをvimで開く肝の設定です。
1行ずつ日本語にしてみます。

  • BufRead *.pdf: pdfファイルをバッファに開こうとしたときに次のコマンドを実行します。
  • :ene |: 新しいバッファを開いて次のコマンドを実行します。
  • 0r !pdftotext -layout -nopgbrk "#" -: pdftotextコマンドで変換した代替バッファ(#)を新しいバッファの最初の行に読み込みます。
    • -layout: インデントを保持するpdftotextのオプションです。あったほうが綺麗です。
    • -nopgbrk: 改ページによる改行を入れないpdftotextのオプションです。あったほうが綺麗です。
    • pdftotext の最後の引数"-"ダッシュは変換結果を標準出力にアウトプットします。これがないとtxtファイルが生成されるだけでvimで開き直さないといけません。必須です。
    • 0rの数字"0"がないと最初の行が空行になってかっこ悪いので、あったほうが良いです。
    • #をダブルクォートで囲うのは空白を含んだPDFファイルが引数に与えられたときの空白エスケープ用です。必須です。

文字を変更しようとしたときに警告してほしい

書いているうちに両方をワンコマンドで実行できることに気がついたので、目次が変になりましたが悪しからず。

j, kのカーソル移動を画面移動に割り当てたい

これは好みの設定ですので、なくても構いません。

圧縮ファイルかpdfファイルを開いたときの設定
autocmd BufRead *.zip,*.gz,*.bz2,*.xz,*.pdf setlocal readonly nolist
    \| nn <buffer> j <C-E> | nn <buffer> k <C-Y>

1行ずつ日本語にしてみます。

  • autocmd BufRead *.zip,*.gz,*.bz2,*.xz,*.pdf: 圧縮形式(zip, gz, bz2, xz)やPDF(pdf)拡張子のファイルをバッファに読み込むときに次のコマンドを実行します。
  • setlocal readonly nolist |: 現在のバッファのみ(setlocal)、読込専用(readonly)にして不可視文字を表示しない(nolist)ようにして、次のコマンドを実行します。
  • nn <buffer> j <C-E> | nn <buffer> k <C-Y>: カーソル上下移動(j/k)を画面移動(C-E/C-Y)に割り当てます。
    • nnはnnoremapの略です。
    • バッファローカルなキーマップの指定はmapの引数に<buffer>を指定します。

<buffer>について、vimヘルプより

map-local
カレントバッファだけで使用できるマップを作成するには、マップコマンドの引数に"<buffer>" を指定します。例:
        :map <buffer>  ,w  /[.,;]<CR>
この場合、他のバッファで、",w" に対して別の操作を割り当てることができます:
        :map <buffer>  ,w  /[#&!]<CR>

不可視文字の設定
私のvimは改行や意味のない空白を表示するために次のように設定しています。

set list  " 不可視文字の表示
set listchars=tab:»-,trail:-,eol:,extends:»,precedes:«,nbsp:%

PDFを読むときは編集するわけでもないし、ない方が綺麗だと思ったので不可視文字を非表示にしました。

弱点

  • 代替バッファにバイナリで開いたPDFが残ります。autcmdで | buload "#"とつなげて消したかったのですがうまくいかず…。commandを設定する方法2では代替バッファが残りません。
  • PDFのファイルサイズが大きいとテキスト変換に時間がかかります。これはpdftotextの問題です。

  1. 手前味噌ですが、pdftotextについて記事を書いています。圧縮形式で保存する方法についても触れています。Qiita - ターミナル上でPDFのテキストを読む 

  2. 参考: Vim で PDF ファイルを読む こちらはautocmdではなく:Pdfという自作コマンドを設定する方法です。これだとターミナルから$ vim something.pdfとしたときに変換してくれないので参考にとどめておきました。無理やりやるなら$ vim -c "Pdf something.pdf"ですがタイプが長くなりますし、従来のvimコマンド:e:tabedit:vsplitと併用できません。その点、autocmdならバッファに読み込む際に処理を行うので、従来のvimコマンドと相性が良いです。 

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away