#!/usr/bin/perl # make an executable file use strict; use warnings; sub usage; sub mkexec; sub guesstype; sub getcmd; sub launch_editor; my $DEFAULT_TYPE = 'sh'; my $DEFAULT_MODE = 0755; my $DEFAULT_FORCE = 0; my $DEFAULT_EDIT = 0; ## .... ## . . . . . . . . . . . ## INIT ## ------------------------------------------------------------------- ## '''' ## ' ' ' ' ' ' ' ' ' ' ' my $force = $DEFAULT_FORCE; my $name; my $type; my $edit; foreach (@ARGV) { if (m/-f|--force/) { $force++; } elsif (m/-e|--edit/) { $edit++; } elsif (m/-E|--no-edit/) { $edit = 0; } elsif (defined $name) { $type = $_; } else { $name = $_; } } usage unless defined $name; $type = guesstype $name unless defined $type; my $bangs = { pl => `which perl`, sh => '/bin/sh', py => `which python`, bash => '/bin/bash', sed => `which sed`, bc => `which bc` }; my $templates = { pl => "use strict;\nuse warnings;\n", py => "if __name__ == '__main__':\n" }; my $editors = [ qw/ vim editor / ]; my $cmds; $cmds->{vim}->{test} = "vim --version 2>/dev/null"; $cmds->{vim}->{run} = "vim +\"normal G\$\" '%s'"; $cmds->{editor}->{test} = "editor --version 2>/dev/null"; $cmds->{editor}->{run} = "editor '%s'"; ## ... ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## RUN ## ----------------------------------------------------------------- # ## ''' ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # if (exists $bangs->{$type}) { $force and -e $name and (defined `cp "$name" "$name~"` or die $!); (not -e $name or $force) and mkexec $name, mkbody($type); chmod $DEFAULT_MODE, $name; launch_editor $name if $edit; } else { die "unknown type: $type\n"; } ## .... ## ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''-. ## SUBZ ## ----------------------------------------------------------------- : ## '''' ## ..............................................................-' sub usage { print STDERR "usage: $0 [-f|-E] filename [type]\n"; exit 0; } sub guesstype { my $name = shift; my ($ext) = $name =~ m|\.(\w+)$|; return ( $ext ? $ext : $DEFAULT_TYPE); } sub mkbody { my $type = shift; my $tmpl = ""; $tmpl .= $templates->{$type} if exists $templates->{$type}; return sprintf "#!%s\n%s\n", $bangs->{$type}, $tmpl; } sub mkexec { my ($name, $body) = @_; open EXE, ">", $name or die "cannot open $name for writing: $!\n"; -W EXE or die "file $name is not writable\n"; print EXE $body; close EXE or die "cannot close $name: $!\n"; } sub get_cmd { foreach (@$editors) { return $cmds->{$_}->{run} if `$cmds->{$_}->{test}` } warn "no supported editor available\n"; return; } sub launch_editor { my $name = shift; my $form = get_cmd; if ($form) { my $command = sprintf get_cmd, $name; exec "$command"; } else { return } warn "failed to launch editor: $form\n"; }