To wean myself off using vi for quick edits, I’ve aliased “vi” to “eve” in the shell, and set EDITOR to point to “eve” also. The “eve” program is a re-implementation of emacsclient in Perl; the only difference is that it execs “vi” if there isn’t already an emacsserver running.
You know, modern emacsclient binaries have a -a switch, so you could accomplish the same thing with “emacsclient -a /usr/bin/vi $*”, then you don’t have to launch perl everytime you want to edit a file.
-Rawb-
Yes, but you can’t set EDITOR to “emacsclient -a …” because a lot of software calls execlp($EDITOR, $EDITOR, NULL). I.e. they don’t handle arguments.
– Rui Paulo
I believe the suggestion is using this instead of Perl:
echo -e "#\!/bin/bash\n\nemacsclient -a /usr/bin/vi \$*" > /usr/local/bin/eve EDITOR=eve
#!/usr/bin/perl -w
# eve - Edit with VI or Emacs
# Good as a value for EDITOR or as the target of a 'vi' alias
# If there is an emacsserver already running then connect to it, otherwise
# run /usr/bin/vi.
use strict;
use POSIX;
use Socket;
use Sys::Hostname;
socket(EMACS, AF_UNIX, SOCK_STREAM, 0) || die "unix domain socket: $!";
my $server = sprintf "/tmp/esrv%d-%s", &POSIX::geteuid(), hostname;
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime,
$ctime, $blksize, $blocks) = stat($server);
if(!defined $uid || $uid != &POSIX::geteuid()) {
exec "/usr/bin/vi", @ARGV;
}
if(connect(EMACS, sockaddr_un $server) < 0) {
exec "/usr/bin/vi", @ARGV;
}
my $cwd = &POSIX::getcwd;
foreach (@ARGV) {
if(/^\+\d+$/) {
print EMACS "$_ ";
} elsif(/^\//) {
print EMACS "e_file_name($_), ' ';
} else {
print EMACS "e_file_name("$cwd/$_"), ' ';
}
}
printf STDERR "Waiting for Emacs...";
select(STDERR); $| = 1;
print EMACS "\n";
select(EMACS); $| = 1;
while(<EMACS>) {
printf STDERR $_;
}
exit 0;
########################################################################
sub quote_file_name {
my ($filename) = @_;
$filename =~ s/\&/\&\&/g;
$filename =~ s/^-/\&-/g;
$filename =~ s/ /\&_/g;
return $filename;
}