#!/usr/bin/perl # make an executeble file use strict; use warnings; sub usage; sub mkexec; sub guesstype; sub getcmd; sub launch_editor; my $DEFAULT_TYPE = 'pl'; my $DEFAULT_MODE = 0755; my $name = shift or usage; my $type = ($ARGV[0] ? shift : guesstype $name); my $bang = { pl => `which perl`, sh => `which sh`, py => `which python`, bash => `which bash`, sed => `which sed`, bc => `which bc` }; my $template = { 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'"; if (exists $bang->{$type}) { -e $name || mkexec $name, mkbody($type); chmod $DEFAULT_MODE, $name; launch_editor $name; } else { die "unknown type: $type\n"; } sub usage { print STDERR "usage: $0 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 .= $template->{$type} if exists $template->{$type}; return sprintf "#!%s\n%s\n", $bang->{$type}, $tmpl; } sub mkexec { my ($name, $body) = @_; open EXE, ">", $name || die "cannot open $name for writing: $!\n"; -W EXE || die "file $name is not writable\n"; print EXE $body; close EXE || 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"; }