#!/bin/ksh # ed # William Robertson - www.williamrobertson.net # More convenient way to invoke editor from command line, influenced by Oracle # SQL*Plus where e.g. "ed myscript" invokes your chosen editor for myscript.sql. # (Especially if you sometimes type "ed somescript" at the Unix prompt, and find # yourself looking at a blank screen with a cryptic number at the bottom.) # Syntax: # ed filename # ed FileName # ed filename.ext filename2 filename3... # If filename not found, ed tries filename.extension for standard extensions: file_extensions="java html htm sql lst lis txt log ctl pls sps spb spp sjf" # The first matching filename.ext is added to the list of filenames for editing. # Case-insensitive, so e.g. 'ed swingcolortest' will find SwingColorTest.java. # # Setting optional environment variable DEBUG=TRUE allows printing of debug info # during running, and suppresses actual 'vi' command at end. Most convenient form is # probably "DEBUG=TRUE ed filename". typeset -i arguments=$# file_list=$* # Substitute your favourite editor here: alias edit='/applications/application_folders/vim/Vim.app/Contents/MacOS/Vim -g' # alias edit=/usr/bin/vi function debug { # Display message if DEBUG set to TRUE: [[ ${DEBUG:=FALSE} = TRUE ]] && print -u2 "$*" } function resolve_filename { # For specified filename parameter, find a matching file and echo its name, # supplying extension if unspecified, using case-insensitive match. # In Mac ksh, file names are interpreted case-insensitively, or almost... # e.g. say a file exists named 'SwingColorTest.java': # 'ls swingcolortest.java' returns 'swingcolortest.java' # 'ls SWINGCOLORTEST.JAVA' returns 'SWINGCOLORTEST.JAVA' # 'ls swingcolortest.*' returns failure. # 'javac swingcolortest.java' can fail because the file is treated as # 'swingcolortest.java' which does not match the class name specified in it. # (Seems to be more to it though as sometimes works...) # Attempt to find the real capitalisation using 'ls | grep -i filename'. original_filename=$1 filename_no_path=$1 if [[ -n ${ORACLE_PATH} ]] then # Add path elements here in standard:path:format (searched left to right): filepath=${ORACLE_PATH}:. else filepath=. fi debug "$0 resolving filename $*" if [[ ${original_filename} = */* ]]; then filepath=${original_filename%/*} debug "Specified path is '${filepath}'" filename_no_path=${original_filename##*/} fi if [[ ${original_filename} != ${filename_no_path} ]]; then debug "Filename without path component is '${filename_no_path}'" fi searchpath=$(print ${filepath} |sed 's/:/ /g') debug Search path is ${searchpath} for dir in ${searchpath} do debug Searching in directory $dir debug about to look for ${dir}/${filename_no_path}, so long as ${dir}/${filename_no_path} is not a directory: if [[ -f ${dir}/${filename_no_path} ]] && [[ ! -d ${dir}/${filename_no_path} ]]; then debug "Case-insensitive check found file '${dir}/${filename_no_path}'" debug "Checking case by listing files named '${filename_no_path}' in directory '${dir}':" # Assignment and test for success combined into one crypric command line: # TRUE if 'ls | grep' command is successful: this will also populate 'resolved_filename'. if resolved_filename=${dir}/$(ls -aC1 ${dir} | grep -i "^${filename_no_path}$") then resolved_filename=${resolved_filename#./} debug "Check for '${filename_no_path}' in '${dir}' found '${resolved_filename}'" else debug \ "File '${original_filename}' confirmed by -f test, but mysteriously absent for ls" fi elif [[ ${filename_no_path} != *.* ]] then debug "Did not find file '${original_filename}' as specified. Trying with standard extensions:" for extension in ${file_extensions} do debug "Extension '.${extension}':" if [[ -f ${dir}/${filename_no_path}.${extension} ]] then # Assignment and test for success combined into one crypric command line: # TRUE if 'ls | grep' command is successful; the result of this will also # populate 'resolved_filename' variable. if resolved_filename=${dir:-.}/$(ls -aC1 ${dir} | grep -i "^${filename_no_path}.${extension}$") then resolved_filename=${resolved_filename#./} debug \ "Found file named '${resolved_filename}' in directory '${dir}'" break else print -u2 \ Case of filename ${original_filename}.${extension} in question fi else debug \ "Checking possible extensions: ${original_filename}.${extension} not found" fi done fi done # end file path loop if [[ -n ${resolved_filename} ]] then print ${resolved_filename} else print -u2 "$0: No file found matching ${original_filename}" return 1 fi } # End of function definitions; start of processing: debug print Debug mode - displaying diagnostics only: [[ ${DEBUG} = TRUE ]] && alias edit if (( arguments > 0 )); then for filename in $@ do filelist="${filelist} $(resolve_filename ${filename})" done # Strip trailing spaces: while [[ ${filelist} != ${filelist%% } ]] do filelist=${filelist%% } done debug "filelist is '${filelist}'" fi debug "Number of arguments = $arguments" if (( arguments > 0 )) && [[ -z ${filelist} ]] then typeset -uL1 yesno read yesno?"No files found. Continue? [Y/N] " if [[ ${yesno} = Y ]]; then [[ ${DEBUG} = TRUE ]] && alias edit edit ${file_list} else exit 0 fi else debug "Editing file list: '${filelist}'" if [[ ${DEBUG:=TRUE} = TRUE ]]; then debug edit ${filelist} else [[ ${DEBUG} = TRUE ]] && set -vx edit ${filelist} fi fi