Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim script: Buffer/CheatSheet Toggle

I want to make a vim cheat sheet plugin. It's real simple:

  • I want to toggle my cheatsheets. A vertsplit toggle, like Taglist or NERDTree.
  • I want the cheatsheet to be filetype specific. So I toggle my c++ cheatsheet when I have opened a .cpp file.
  • I want the cheatsheet to be horizontally split. So it shows two files, my syntax cheat sheet and my snippet trigger cheat sheet.

I already have a collection of these cheatsheets, in vimhelp format, but now I have to manually open them.

I haven't really done any vim scripting, but I imagine this would be really simple to put together. I'm sorta sick of googling unrelated codesnippets, so what I'm asking here is:

  1. Could anyone give me a short sum-up of what I need to learn in regards to vim scripting to piece this together. What I have a hard time finding is how to toggle the buffer window.

  2. If you know any intro tutorials that covers the material I need to get this up and running, please provide a link.

tx,

aktivb

like image 535
aktivb Avatar asked Mar 04 '11 14:03

aktivb


People also ask

How do I toggle between buffers in Vim?

To toggle between the current and the last buffer use the Ctrl-^ (normal mode) command (on most keyboards, hold down Ctrl and press the 6 key on the main keyboard).

What is D in Vim?

Key 4: d (delete) The w key. d tells Vim to delete something. w tells Vim to move to the next word. Combined, you delete the current word.

How do I switch to command mode in Vim?

To go into INSERT mode from COMMAND mode, you type i . To go back to COMMAND mode, you type the esc key. vim starts out in COMMAND mode. Over time, you will likely spend more time in COMMAND mode than INSERT mode.

How do I exit insert mode in Vim?

To exit from 'insert' mode, hit ESC (the escape key). If you want to force a quit (i.e. quit without saving) type: :q!


2 Answers

The function below may not do exactly what you want, and I haven't tested it, but it should give you some ideas.

The main idea is that the function reads the filetype of the current buffer (you can test this by typing :echo &ft) and then sets the path of the appropriate cheat sheat. If it exists, this path is then opened (read-only and non-modifiable) in a split window. You can then call this function any way you wish, for example by mapping it to the {F5} key as shown.

I'm not sure about the toggling possibilities (is this really easier than just closing the split window?) but you could look at the bufloaded() function, which returns whether or not a given file is currently being accessed.

function! Load_Cheat_Sheet()
    let l:ft = &ft

    if l:ft == 'html'
        let l:path = 'path/to/html/cheat/sheet'
    elseif l:ft == 'c'
        let l:path = 'path/to/c/cheat/sheet'
    elseif l:ft == 'tex'
        let l:path = 'path/to/tex/cheat/sheet'
    endif

    if l:path != '' && filereadable(l:path)
        execute ':split +setlocal\ noma\ ro ' l:path
    endif
endfunction

map <F5> :call Load_Cheat_Sheet()<CR>

Hope this helps. Just shout if anything is unclear, or you want to know more.

like image 121
Prince Goulash Avatar answered Oct 04 '22 20:10

Prince Goulash


I had forgotten about this until I got a notice about Eduan's answer. Since I posted this question I've done quite a bit of vim scripting, including getting this to work:

let g:cheatsheet_dir = "~/.vim/bundle/cheatsheet/doc/"                                                                     
let g:cheatsheet_ext = ".cs.txt"

command! -nargs=? -complete=customlist,CheatSheetComplete CS call ToggleCheatSheet(<f-args>)           
nmap <F5> :CS<CR>

" strip extension from complete list    
function! CheatSheetComplete(A,L,P)
  return map(split(globpath(g:cheatsheet_dir, a:A.'*'.g:cheatsheet_ext)),                           
       \ "v:val[".strlen(expand(g:cheatsheet_dir)).                                                     
       \ ":-".(strlen(g:cheatsheet_ext) + 1)."]")                                                              
endfun

" specify cheatsheet or use filetype of open buffer as default
" instead of saving window status in a boolean variable, 
" test if the file is open (by name). If a boolean is used, 
" you'll run into trouble if you close the window manually with :wq etc                           
function! ToggleCheatSheet(...)
  if a:0    
    let s:file = g:cheatsheet_dir.a:1.g:cheatsheet_ext
  else                                     
    if !exists("s:file") || bufwinnr(s:file) == -1                                                                                 
      let s:file = g:cheatsheet_dir.&ft.g:cheatsheet_ext
    endif
  endif                                    
  if bufwinnr(s:file) != -1
    call ToggleWindowClose(s:file)
  else
    call ToggleWindowOpen(s:file)
  endif                 
endfun             


" stateless open and close so it can be used with other plugins              
function! ToggleWindowOpen(file)           
  let splitr = &splitright
  set splitright                           
  exe ":vsp ".a:file  
  exe ":vertical resize 84"
  if !splitr    
    set splitright
  endif                        
endfun

function! ToggleWindowClose(file)    
  let w_orig = bufwinnr('%')
  let w = bufwinnr(a:file)
  exe w.'wincmd w'
  exe ':silent wq!'      
  if w != w_orig        
    exe w_orig.'wincmd w'
  endif
endfun                                            
like image 28
aktivb Avatar answered Oct 04 '22 19:10

aktivb