blob: aa14da282824a00abb255e40081dbff0f437b8f8 [file] [log] [blame] [raw]
#!/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 <<EOT;
Usage: revim [-m <vim modeline>] src/*
In <vim modeline>, 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";
}