#!/usr/bin/perl -w # # editfancy ('e' aliased to here) # # Start emacs in the background, bigger, with filename in titlebar. # Use -nw option when connecting via ssh from home. # Also test if the file exists, and try appending "*" if not. # If there's a CVS directory around, report if file needs cvs update. # # 2007-??: Written by Steven J. DeRose, sderose@acm.org. # 2007-10-31 sjd: Ported from shell function. # 2007-11-13 sjd: Continue port; add emacsclient, vi, nedit, -ec, -cvs. # # To do: # Is there way to force emacs to get focus? Apparently not. # Allow editing multiple files # Handle more pass-thru options: # +n +n:c -f function name r font fg bg # Add -find 'pat' option. # emacs.keyword:value (are there important ones not already listed? # use strict; use Getopt::Long; my $name = "editfancy"; my $version = "2010-09-12"; my $dft_bgcolor = "mistyRose"; my $dft_geometry = " -geometry 82x67+30+20"; # WIDTHxHEIGHT+XOFF+YOFF my $dft_maxWidth = 5000; my $cvs = 1; my $ec = 0; my $find = ""; my $geometry = $dft_geometry; my $line = ""; my $maxWidth = $dft_maxWidth; my $nwflag = 0; my $quiet = 0; my $verbose = 0; my @xoptions = (); # can Getopt match /emacs\..*:/? for option name? Getopt::Long::Configure ("ignore_case"); my $result = GetOptions( "cvs!" => \$cvs, "ec!" => \$ec, "find=s" => \$find, "g|geometry" => \$geometry, "h|help|?" => sub { system "perldoc editfancy"; exit; }, "line=i" => \$line, "max=n" => \$maxWidth, "nw!" => \$nwflag, "q|quiet!" => \$quiet, "v|verbose+" => \$verbose, "version" => sub { die "$name: Version of $version, by Steven J. DeRose.\n"; } ); ($result) || die "$name: Bad options.\n"; ############################################################################### # my $file = shift; # If file doesn't exist, see if a similar one does if (! -e $file) { my $guess = `extendFilename $file`; if ( "$guess" ne "") { # ring the bell? warn "$name: File '$file' not found, so editing $guess."; $file="$guess"; } else { warn "$name: File '$file*' not found, creating $file."; } } # See if it's ridiculously wide and offer indenting if (!$quiet) { my $maxlineWidth = `wc -L $file | sed -s 's/[^ 0-9].*\$//'`; if ( $maxlineWidth > $maxWidth ) { warn "$name: WARNING: Long lines (max $maxlineWidth), consider indenting?" } } # Report CVS status if there's a CVS directory present # (should copy path user gave, if any) if ($cvs) { #my $cvspath = $ENV{PWD}; (my $cvspath = $file) =~ s|[^/]*\$||; # Remove filename ($verbose) && warn "Checking for CVS dir at '$cvspath'\n"; if ( -d "$cvspath" . "CVS") { ($verbose) && warn "Checking CVS status...\n"; system "cvs status $file \$* 2>/dev/null | grep 'File:'"; } else { ($quiet) || warn "Does not appear to be a CVS directory.\n"; } } # Extract filename for title bar (doesn't get updated if user visits other files) (my $short = $file) =~ s/^.*\///; ($verbose) && warn "Extracted name for title-bar: '$short'.\n"; # Pick a background color my $bgcolor = $ENV{EMACS_BG}; if ( $bgcolor eq "" ) { $bgcolor = $dft_bgcolor; } # Open a new window, or not? my $nwoption = ""; my $runinbg = " &"; if ($nwflag == 1) { $nwoption = "-nw"; $runinbg = ""; } # Locate the target line # Conveniently, most editors have same syntax for scroll-to-line option. my $scrollOption = ""; if ($line) { $scrollOption = "+$line"; } elsif ($find) { my $fcmd = "grep -n -m 1 '$find' $file 2>/dev/null | sed 's/:.*\$//'"; my $fline = `$fcmd`; chomp $fline; $fline -= 0; ($verbose) && warn " Searched for '$find': got line '$fline'.\n"; if ($fline > 0) { $scrollOption = "+$fline"; } } # Pick the editor, assemble the command, and go my $editorChoice = $ENV{EDITOR}; my $cmd = ""; if ($ec || $editorChoice eq "emacsclient") { warn "Using emacsclient..."; $cmd = "emacsclient -bg $bgcolor $geometry -T \"$file\" $nwoption $scrollOption" . "$file $* $runinbg"; } elsif ($editorChoice eq "emacs") { $cmd = "emacs -bg $bgcolor $geometry -T \"$file\" $nwoption $scrollOption" . "$file $* $runinbg"; } elsif ($editorChoice eq "nedit") { $cmd = "nedit $file $scrollOption"; } elsif ($editorChoice eq "vi") { $cmd = "vi $file $scrollOption"; } else { die "\$EDITOR environment value has unknown value '$editorChoice'.\n"; } ($verbose) && warn "Running:\n $cmd\n"; system $cmd; exit; ############################################################################### # sub showUsage() { warn " =head1 Usage editfancy [options] [file] Launch emacs in the background, with various options, such as for: large window, titlebar, color (uses \$EMACS_BG ($ENV{EMACS_BG})), placement. If the named file doesn't exist, it tries appending '*'. If it's in a CVS directory, report if the file needs update. Responds to \$EDITOR set to vi, nedit, emacs, or emacsclient (your current setting is '$ENV{EDITOR}'). =head1 Options =over =item * B<--cvs> Notify if editing an out-of-date CVS file (default, else --nocvs). =item * B<--ec> Use emacsclient as the editor. =item * B<--geometry> Set X Windows geometry (widthxheight+xoffset+yoffset) =item * B<--max n> Complain if max line width of file greater than this. =item * B<--nw> Use no-window option. =item * B<-q> Suppress most messages. =item * B<-v> Add more detailed messages. =item * B<--version> Display version info and exit. =back =head1 Related commands See 'info emacsclient' as needed. =head1 Known bugs and limitations (unfinished) Cannot pass-through emacs X resource options yet. =head1 Ownership This work by Steven J. DeRose is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. For further information on this license, see http://creativecommons.org/licenses/by-sa/3.0/. The author's present email is sderose at acm.org. For the most recent version, see http://www.derose.net/steve/utilities/. =cut "; }