#!/usr/bin/perl # vim:set ft=perl ts=4 sw=4 et fdm=marker: # # revim - add customized vim modeline for given files # Copyright (c) 2010 chaoslawful use strict; use warnings; use Getopt::Std; my %opts; getopts('hm:', \%opts); if($opts{h} or !@ARGV) { die <] src/* In , the following placeholder(s) can be used: * %t - Expands to vim file type. E.g. 'c' for .c files, 'perl' for .pl files. EOT } my $vim_ml = $opts{m} || "vim:set ft=%t ts=4 sw=4 et fdm=marker:"; my @files = map glob, @ARGV; for my $file (@files) { next if -d $file; my ($ft, $ml) = detect_filetype($file, $vim_ml); next if !defined($ft); revim($file, $ml); } sub detect_filetype { my ($f, $tmpl) = @_; my ($ft, $lcmt, $rcmt); my %phs; if($f =~ /.([cC]|[hH])$/) { $ft = "c"; ($lcmt, $rcmt) = ("/* ", " */"); } elsif($f =~ /.(pl|pm)$/) { $ft = "perl"; ($lcmt, $rcmt) = ("# ", ""); } elsif($f =~ /.t_?$/) { # assuming tests are written in perl $ft = "perl"; ($lcmt, $rcmt) = ("# ", ""); } else { $ft = undef; } if(defined($ft)) { %phs = ( "%t" => $ft, ); $tmpl =~ s/(%[a-z])/$phs{$1}/ge; $tmpl =~ s/^/$lcmt/; $tmpl =~ s/$/$rcmt/; return ($ft, $tmpl); } return (undef, undef); } sub revim { my ($f, $ml) = @_; my @lines; open my $in, $f or die "Can't open $f for reading: $!"; while(<$in>) { push(@lines, $_); } close $in; my @nlines = grep {!/\bvim?:/} @lines; warn "revim: $f:\tremoved existing vim modeline.\n" if(@nlines != @lines); if($nlines[0] =~ /^#!/) { # has shebang line my $shebang = shift @nlines; unshift(@nlines, $shebang, "$ml\n"); } else { unshift(@nlines, "$ml\n"); } my $text = join '', @nlines; open my $out, "> $f" or die "Can't open $f for writing: $!"; binmode $out; print $out $text; close $out; warn "revim: $f:\tdone.\n"; }