vimのプレゼンツール

JUIのLTでIngyがvimでプレゼンしてたのにインスパイアされて生まれて初めてvimscript書いてみた。食わず嫌いなだけだったらしく意外とやって見ると面白かった。まだまだ完成度は低いけど最低限動くようにはなったのでコードさらしておく。たぶん自作しなくてもあったんだろうけど探すの面倒だったんだよね。

使い方

  • 後述するscriptをpresentation.vimとでもして保存する。
  • 適当なバッファで:source presentation.vimで読み込む。
  • :PresentationEnableでプレゼン用の設定を有効化及び、プレゼンデータ読み込み
  • l で次のスライド、h で前のスライド
  • :PresentationDisableでプレゼン用設定を解除(厳密には解除というか自分好みの設定に戻してるだけだけど。


今後どうするか

  • プレゼンデータは外部ファイル化して読み込む形にする
  • j, kで一行ずつ進んだり戻ったりできるようにする
  • 万が一要望とかあればコメントに書いてくれると僕のモチベーションがあがります。たぶん。
let s:Presentation = { 'slides' : [], 'current' : 0, 'max' : 0 }

function! s:Presentation.load()
  let self.slides = [
        \ {
        \   'title' : 'Presentation.vim作ってみたよ',
        \   'contents' : [
        \     '* 仕様',
        \     '* 使い方',
        \     '* 今後の予定',
        \   ]
        \ },
        \ {
        \   'title' : '仕様',
        \   'contents' : [
        \     '* l で次のスライドを表示',
        \     '* h で前のスライドを表示',
        \   ]
        \ },
        \ {
        \   'title' : '使い方',
        \   'contents' : [
        \     '* 任意の空バッファ上で:source presentation.vim',
        \     '* :PresentationEnable でプレゼンモード開始',
        \     '* :PresentationDisable でプレゼンモード終了',
        \   ]
        \ },
        \ {
        \   'title' : '今後の予定',
        \   'contents' : [
        \     '* スライドの中身は外部のymlとか呼ぶようにしたい。',
        \     '* j, kでスライドのコンテンツを順に表示したい。',
        \     '* 万が一要望があればコメントくだしあ><',
        \   ]
        \ },]
  let self.current = 0
  let self.max = len(self.slides)
endfunction

function! s:Presentation.showPage()
  call self.showPageTitle()
  call self.showPageContents()
endfunction

function! s:Presentation.showPageTitle()
  execute 'normal o '
  call setpos('.', [0, winline(), 1, winwidth(0)/5])
  execute 'normal i ' . self.currentSlide()['title']
  execute 'normal o '
endfunction

function! s:Presentation.showPageContents()
  for content in self.currentSlide()['contents']
    execute 'normal o '
    call setpos('.', [0, winline(), 1, winwidth(0)/6])
    execute 'normal i ' . content
  endfor
endfunction

function! s:Presentation.currentSlide()
  return self.slides[self.current]
endfunction

function! s:Presentation.clearPage()
  execute 'normal ggdG'
endfunction

function! s:Presentation.showNextPage()
  let nextIndex = self.current + 1
  if nextIndex == self.max
    echo '最後のページです'
    return
  endif
  call self.clearPage()
  let self.current = nextIndex
  call self.showPage()
endfunction

function! s:Presentation.showPrevPage()
  let prevIndex = self.current - 1
  if prevIndex < 0
    echo '最初のページです'
    return
  endif
  call self.clearPage()
  let self.current = prevIndex
  call self.showPage()
endfunction

" 次ページを表示
function! s:ShowNextPage()
  call s:Presentation.showNextPage()
endfunction

" 前ページを表示
function! s:ShowPrevPage()
  call s:Presentation.showPrevPage()
endfunction

" プレゼンテーションを有効化する
function! s:Enable()
  call s:Presentation.load()
  set paste
  set ve=all
  set laststatus=0

"  map <buffer> j :call s:Presentation.nextLine()<CR>
"  map <buffer> k :call s:Presentation.prevLine()<CR>
  map <buffer> h :call <SID>ShowPrevPage()<CR>
  map <buffer> l :call <SID>ShowNextPage()<CR>

  call s:Presentation.showPage()
endfunction

" プレゼンテーションを無効化する
function! s:Disable()
  set nopaste
  set ve=
  set laststatus=2
endfunction

command! -bar -narg=0 PresentationEnable  call s:Enable()
command! -bar -narg=0 PresentationDisable  call s:Disable()