サイトマップ 更新履歴 ニュース Elispセクション 利用手引

EditWithViOrEmacs

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.

-PeterHousel-

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 &quote_file_name($_), ' ';
    } else {
	print EMACS &quote_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;
}

CategoryExternalUtilities