Vim Tips Wiki
Advertisement
Tip 434 Printable Monobook Previous Next

created March 6, 2003 · complexity intermediate · author Karthick Gururaj · version 6.0


When you start editing a *.h file, you'd need some format like this:

/*****************************************************************
* Filename: abc.h
* Description:
* Created: Mar 5 03 09:00:00
* Last modified: Mar 6 03 09:00:00
* <plus more stuff like author, copyright, etc>
*
* Revision History
* Date Author Remarks
* Mar 5 2003 KG File Created
*******************************************************************/
#ifndef _ABC_H_
#define _ABC_H_

#endif
// vim:ts=3:sw=3:ft=c

I wanted my gvim to do the following things at various stages of editing a abc.h file:

  1. Upon opening a new file, insert the skeleton like the one above, and leave me in insert mode after "Description"
  2. When writing a file, update the "Last Modified" timestamp
  3. On opening a existing file, modify the "Revision History" to add a new line, and leave me in insert mode below "Remarks"

The following autogroup (:help :au) commands let you do these (put these in your .vimrc):

if !exists("autocommands_loaded")
  let autocommands_loaded = 1
  au BufNewFile *.h call InsertCHHeader()
  au BufWrite *.h call ModifyTime()
  " You might want to comment-out the line below - see note 6 at the end of the post.
  au BufReadPost *.h call ModifyHeader()
endif

function! InsertCHHeader()
  call InsertSkeleton("skeleton.h") " CHANGE this!
  call InsertFname()
  1
  " Search for Description
  call search("Description:")
  normal $
  startinsert
endfunction

function! InsertSkeleton(fname)
  let path_to_skeletons = $HOME . "/etc/skeletons/" " CHANGE this!
  " Save cpoptions
  let cpoptions = &cpoptions
  " Remove the 'a' option - prevents the name of the
  " alternate file being overwritten with a :read command
  exe "set cpoptions=" . substitute(cpoptions, "a", "", "g")
  exe "read " . path_to_skeletons . a:fname
  " Restore cpoptions
  exe "set cpoptions=" . cpoptions
  " Delete the first line into the black-hole register
  1, 1 delete _
  " Search for Filename:
  call search("Filename:")
  exe "normal A " . expand("%:t")
  " Search for Created:
  let current_time = strftime("%b %d %Y %T") "CHANGE this!
  call search("Created:")
  exe "normal A " . current_time
  " Search for Last modified:
  call search("Last modified:")
  exe "normal A " . current_time

  " Search for Date
  let date_line_no = search("Date")
  let rev_history = getline(line("."))
  let rev_history = substitute(rev_history, "Date ", strftime("%b %d %Y"), "") " CHANGE this!
  let rev_history = substitute(rev_history, "Author", "KG ", "") "CHANGE this!
  let rev_history = substitute(rev_history, "Remarks", "File created.", "")
  call append(date_line_no, rev_history)
endfunction

function! InsertFname()
  " Convert newname.h to _NEWNAME_H_
  let fname = expand("%:t")
  let fname = toupper(fname)
  let fname = substitute(fname, "\\.", "_", "g")
  " Search for #ifndef
  call search("#ifndef")
  exe "normal A " . "_" . fname . "_"
  " Search for #define
  call search("#define")
  exe "normal A " . "_" . fname . "_"
endfunction

function! ModifyHeader()
  " Modify header only if we have write permissions
  if &readonly == 0
    " Search for Date
    let date_line_no = search("Date")
    if date_line_no != 0
      let rev_history = getline(line("."))
      " Substitute Date, and Author fields
      let rev_history = substitute(rev_history, "Date ", strftime("%b %d %Y"), "") " CHANGE this!
      let rev_history = substitute(rev_history, "Author", "KG ", "") " CHANGE this!
      let rev_history = substitute(rev_history, "Remarks", "", "")
      " echo "Modified = " . rev_history
      call append(date_line_no, rev_history)
      normal j$
      startinsert
    endif
  endif
endfunction

function! ModifyTime()
  " Do the updation only if the current buffer is modified
  if &modified == 1
    let current_time = strftime("%b %d %Y %X") " CHANGE this!
    " Save current position at mark i
    normal mi
    " Search for Last modified:
    let modified_line_no = search("Last modified:")
    if modified_line_no != 0 && modified_line_no < 10
      " There is a match in first 10 lines
      " Go to the : in modified:
      exe "normal f:2l" . strlen(current_time) . "s" . current_time
      echo "Modified date stamp to " . current_time
      sleep 500m
      " Restore position
      normal `i
    endif
  endif
endfunction

Notes

1. The strftime() function is not portable. You might need to change the format specifier for your system.

2. The autogroup commands assumes that there is a file called skeleton.h at the location ~/etc/skeletons.

You might have to modify the path and file name. In my case, the skeleton.h file looks like:
/******************************************************************************
 * Filename:
 * Description:
 *
 * Version: 1.0
 * Created:
 * Last modified:
 * Revision: None
 *
 * Author: Karthick Gururaj
 * Company: [Removed]
 * e-mail: [Removed]
 *
 * Revision history
 * Date Author Remarks
 *
 ******************************************************************************/
 #ifndef
 #define
 #endif
 // vim:sw=3:ts=3
Search the script for the pattern "CHANGE" to see where you might have to make changes..

3. I have not tried to make the script super-portable (that looks obvious eh?). The reasoning is, any changes are a one time effort.

4. The scripts don't modify search history or register values. I have used one letter for marking thou'

5. If you open a new header file, and quit it without writing, no file is created.

6. I found having an autogroup command for modifing the revision history everytime the file is opened to be irritating. So I have disabled this in my system. Note on note: I also had some problems when trying to open the file thro' the quickfix window.

7. You can define more such skeletons for other extentions.

Comments

If you're providing code samples of this complexity, consider submitting a script instead of a tip.

Also, there are some pretty good scripts for skeleton insertion already submitted -- they have the added advantage of working with several different filetypes. (I was debating doing something similar to what you have at one time to make my life easier, but located one of these instead and haven't ever looked back.)


Advertisement