[comp.emacs] file completion in the shell buffer

ramsey@PURDUE.EDU.UUCP (03/20/87)

I am having a real hard time adjusting to the fact that I can't get
file completion in the Gnu-emacs shell buffer under 4.3bsd (Gnu 18.36).

I have tried using the C-q command to add the escape, but due to
having to type a return, and the way the buffer handles returned
control characters, it just doesn't work.

Has anyone worked with this?

Thanks!

-Ed

Ed Ramsey                       ramsey@cs.purdue.edu                    ARPA
Computer Science Department     ramsey%purdue.edu@relay.cs.net          CSNET
Purdue University               {ucbvax,decvax,ihnp4}!purdue!ramsey     UUCP
West Lafayette, IN 47907        (317) 494-6002                          PHONE

prange@mit-eddie.UUCP (03/20/87)

I'm a big user of the emacs shell and found that file name completion
was a bear.  My solution was to write the following function.

(defun insert-file-name-with-completion (name)
  "Prompts for a file or directory name and inserts that name after point.
The name may be non-existent.  Useful in Shell mode."
  (interactive "FInsert file name: ")
  (insert  name))

I bound it to C-c C-f, and use it whenever a long path name is
required.


==========
Michael Prange
UUCP: mit-erl!prange
US Mail: MIT Earth Resources Laboratory
         E34-550
         42 Carleton Street
         Cambridge, MA 02142
Phone: +1 617 253 7866
==========

cef@h.cs.cmu.edu.UUCP (03/20/87)

I just tried the following two things:

	(send-string "shell" "\el")
and	(send-string "shell" "B\e\e").

In my shell, esc-l gives a listing of all files starting with the word
before the point, esc-esc does nme completion.

The first form returned just what 'ls ' would have; the correct result.
The second also worked right and put 'BlindBox' at the point.

So, it seems that it can be done. One would have to write a command that grabs
the current input line (there is some varaible in shell.el that points to it I
believe), and does the following:

    (send-string "shell" (format "%s\e" input-line)) ;for your shell

    (send-string "shell" (format "%s\el" input-line)) ;for my shell
    (send-string "shell" (format "%s\e\e" input-line)) ;for my shell

One aside about "my" shell. I run the csh with the shell variable
'editmode' set to 'emacs'. Theses added bit of functionality may however
be just a local CMU mod, I know some guy here wrote a much spiffier C-shell
and these bells might be part of it.

At any rate, I don't see why the above solution shouldn't work (I havn't tried
writting the thing YET). It seems like about 15 minutes of work to do this.
Most of the time is in checking the shell.el file to see how to grab the 
current line. One should also check what ramifications a command like
our '\el' command would have. After executing this command, the shell
puts the line just typed after the prompt. I don't THINK there will be any
problems with the real start of input being set correctly but you might want to
check it out anyways (probably looking at the value of the start of input
variable and making sure it is correct  will be sufficient).

	Good Luck

		Chuck (Fineman)		[cef@h!seismo]




	

rgs@k.cs.cmu.edu.UUCP (03/20/87)

> I am having a real hard time adjusting to the fact that I can't get
> file completion in the Gnu-emacs shell buffer under 4.3bsd (Gnu 18.36).
> ...
> Has anyone worked with this?

I ran into the same problem and took some time to try to solve it.  I found
it very frustrating that I could not find any standard functions that would
allow me to do the job easily, but I did come to the conclusion that it was
possible.  The code that follows isn't pretty, since I was concentrating
more on getting the thing working than on making it elegant, but it does
seem to work:

-------------------- File filename.el --------------------
(provide 'filename)
; Filename completion facilities.
; This package provides the function "get-file-name" which prompts
; the user for a filename given an initial prefix.  Its semantics are
; not quite identical to normal filename completion for gnu-emacs, but
; tends to more resemble a cross between Gnu and Gosling emacs.

;; Robert Stockton (rgs@SPICE.CS.CMU.EDU)        11/86
;;     Created.

(if (not (boundp 'file-map))
    (progn (setq file-map (copy-keymap minibuffer-local-completion-map))
	   (define-key file-map "?" 'filename-show-completions)
	   (define-key file-map "\^I" 'filename-do-completion)
	   (define-key file-map " " 'filename-do-completion)))

(defun get-file-name (prompt prefix)
  (read-from-minibuffer prompt prefix file-map nil))

(defun filename-show-completions ()
  (interactive)
  (insert "\nMaking completion list...")
  (sit-for 0)
  (delete-backward-char 26)
  (let* ((string (buffer-string ))
	 (dir1 (file-name-directory string))
	 (dir (if dir1
		  (expand-file-name dir1)
		"."))
	 (subname (file-name-nondirectory string))
	 (comp (file-name-all-completions subname dir)))
    (erase-buffer)
    (if dir1
	(insert-string dir))
    (insert-string subname)
    (if comp
	(with-output-to-temp-buffer " *Completions*"
	  (display-completion-list
	   (sort (file-name-all-completions subname dir) 'string<)))
      (ding)
      (filename-minibuffer-message "[No Completions]"))))
  

(defun filename-do-completion ()
  (interactive)
  (let* ((string (buffer-string ))
	 (dir1 (file-name-directory string))
	 (dir (if dir1
		  (expand-file-name dir1)
		"."))
	 (subname (file-name-nondirectory string))
	 (comp (file-name-completion subname dir)))
    (erase-buffer)
    (if dir1
	(insert dir))
    (cond ((and (stringp comp)
		(eq (file-name-completion comp dir) t))
	   (insert comp)
	   (exit-minibuffer))
	  ((equal comp subname)
	   (insert subname)
	   (if (file-exists-p (concat dir subname))
	       (filename-minibuffer-message "[Complete, but not unique]")
	     (filename-show-completions)))
	  ((stringp comp)
	   (insert comp))
	  (comp (insert-string subname)
		(exit-minibuffer))
	  (t (insert subname)
	     (ding)
	     (filename-minibuffer-message "[No Match]")))))

(defun filename-minibuffer-message (message)
  (save-excursion
    (insert " " message))
  (sit-for 2)
  (delete-char (+ 1 (length message))))

---------------- End filename.el; begin shell.el extensions ----------------
;; Robert Stockton (rgs@SPICE.CS.CMU.EDU)        11/12/86
;;     Added expand-inline-filename (analogous to GosMacs version).
;;     Added shell-beginning-of-line.

(require 'filename)

(defun shell-beginning-of-line ()
  "Go to the beginning of the shell command line.
If the point is not within the current command line, just go the to beginning
of the line instead."
  (interactive)
  (let ((start (process-mark (get-buffer-process (current-buffer)))))
    (if (>= (point) start)
	(goto-char start)
      (beginning-of-line))))

(defun expand-inline-filename ()
  "Attempts to complete the filename beneath the point, prompting if necessary.
Attempts to locate a valid completion for the current filename and places it
back on the command line.  If no unique completion is found, prompts for a
completion in the minibuffer."
  (interactive)
  (require 'filename)
  (let (p)
    (save-excursion
      (re-search-backward "\\s ")
      (setq p (+ (point) 1)))
    (let* ((name (buffer-substring p (point)))
	   (dir (or (file-name-directory name) "./"))
	   (subname (file-name-nondirectory name))
	   (comp (file-name-completion subname dir))
	   (string (cond ((stringp comp) comp)
			 (subname)))
	   (fullstring (concat (file-name-directory name) string))
	   (fullname (if (eq (file-name-completion string dir) t)
			 fullstring
		       (get-file-name "File: " fullstring))))
      (delete-region p (point))
      (insert fullname))))
-------------------- End shell.el extensions --------------------
Robert Stockton
ARPA: rgs@CMU-CS-SPICE.ARPA
UUCP: ...!seismo!cmu-cs-k!rgs
      ...!seismo!rgs@CMU-CS-SPICE

denny@mit-eddie.UUCP (03/21/87)

I have a set of modifications to shell.el which, among other things,
contains full file name completion.  It functions in the same manner as
the mini-buffer including displaying a window of possible completions.

If you would like a a copy, send me a piece of mail.


Denny	hplabs!hpfcla!dsndata!denny

root@ICST-CMR.ARPA.UUCP (03/26/87)

Just post it. If you don't, send me a copy anyway.

	(Root Boy) Jim "Just Say Yes" Cottrell	<rbj@icst-cmr.arpa>
	...I want a COLOR T.V. and a VIBRATING BED!!!

P.S. Sorry for postine instead of using direct mail. I have been having
trouble sending to this list recently. This is a test message.