home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / functions / complete-fn.el < prev    next >
Encoding:
Text File  |  1993-03-03  |  4.8 KB  |  131 lines

  1. ;; LCD Archive Entry:
  2. ;; complete-fn|Juergen Nickelsen|nickel@cs.tu-berlin.de|
  3. ;; File name completion in a buffer.|
  4. ;; 1993-02-25|1.1|~/functions/complete-fn.el.Z|
  5.  
  6.  
  7. ; complete-fn.el implements completion of a file name which is typed in
  8. ; a buffer. If you really like to type file names like
  9. ; /home/stone/shape/development/src/atfs/conf/s-ultrix_4/AtFS/Data/config.h
  10. ; you don't need it. (This is a real world example!)
  11. ; I have complete-file-name bound to C-c TAB, and when I realize that I
  12. ; am just, typing a monster like the example above, I can type somewhere
  13. ; in the middle C-c TAB and finish typing the file name in the
  14. ; minibuffer with the usual completion.
  15. ; If you invoke it, it grabs a string from your current buffer that is
  16. ; surrounded by the following characters: ]\n\t |&;:\$*?()['"`<> 
  17. ; This string is then used as initial input for the minibuffer.  (If you
  18. ; *do* use these characters in file names, change the value of
  19. ; file-name-boundary-regexp.)
  20. ; Sometimes a file name occurs next to a character that could belong to
  21. ; a file name, but does not, e.g. in Makefiles:
  22. ;     INCLUDEPATH=/usr/local/include
  23. ; If you have already typed
  24. ;     INCLUDEPATH=/usr/loca
  25. ; and realize that you want to use complete-file-name, you can go back
  26. ; to the first "/", set the mark, and give a single C-u prefix-argument
  27. ; to complete-file-name. The string is then grabbed from the buffer
  28. ; beginning at the mark. (Or should I make it at the point?)
  29. ; If you don't want a string grabbed from the buffer at all, type C-u
  30. ; twice before invoking complete-file-name.
  31. ; All other prefix arguments are silently ignored.
  32. ; Some time a ago I posted a first version of this function, which had
  33. ; a bug: The completion said "complete, but not unique" even when the
  34. ; file name *was* unique -- I had not really understood how completion
  35. ; using completing-read worked. Handling of the prefix arguments was
  36. ; also different then.
  37. ; Have fun! I appreciate any comments.
  38. ;;; $Header: complete-fn.el[1.1] Thu Feb 25 23:53:22 1993 nickel@cs.tu-berlin.de saved $
  39. ;;; Author: nickel@cs.tu-berlin.de
  40. ;;; complete-fn.el
  41. ;;; The command complete-filename lets you use filename completion on
  42. ;;; a filename the cursor is at or after in a text buffer.
  43. ;;; complete-filename tries to guess what text in the buffer already
  44. ;;; belongs to a filename. file-name-boundary-regexp is used to find
  45. ;;; possible delimiters of the filename.
  46.  
  47. (defvar file-name-boundary-regexp "[]\n\t |&;:\\\\\\$*?()['\"`<>]"
  48.   "Regexp matching characters that are supposed not to occur in filenames.")
  49.  
  50. (defun complete-file-name (arg)
  51.   "Complete filename point is at or after using the minibuffer.
  52. With one C-u, use the value of mark as the beginning of the filename.
  53. With two C-u's, don't grab an initial string from the buffer.
  54. Any other prefix argument is ignored."
  55.   (interactive "P")
  56.   (let* ((grab-from (if (equal arg '(4))
  57.             (mark-marker)))
  58.      (dont-grab (equal arg '(16)))
  59.      (file-name
  60.       (if dont-grab
  61.           ""
  62.         (grab-file-name nil grab-from)))
  63.      (template (complete-file-name-internal file-name nil nil 'use-it))
  64.      (completion (completing-read "Complete Filename: "
  65.                       'complete-file-name-internal
  66.                       nil nil template)))
  67.     (if (equal file-name completion)
  68.     (message "No completion")
  69.       (or dont-grab (grab-file-name 'delete grab-from))
  70.       (insert completion))))
  71.  
  72.  
  73. (defun complete-file-name-internal (file-name pred flag &optional use-it)
  74.   "Internal subroutine for complete-file-name. Do not call this."
  75.   (let ((dir (file-name-directory file-name))
  76.     (nondir (file-name-nondirectory file-name)))
  77.     (cond ((null flag)
  78.        (let ((completion (file-name-completion nondir (or dir ""))))
  79.          (if (stringp completion)
  80.          (concat dir completion)
  81.            (if use-it
  82.            file-name
  83.          completion))))
  84.       ((eq flag t)
  85.        (file-name-all-completions nondir (or dir "")))
  86.       ((eq flag 'lambda)
  87.        (file-name-all-completions nondir (or dir ""))))))
  88.  
  89.  
  90. (defun grab-file-name (delete begin)
  91.   "Return filename point is at or after. If DELETE is non-nil, delete
  92. the filename from the buffer. If BEGIN is non-nil, this is the
  93. beginning of the filename."
  94.   (save-excursion
  95.     (if (and (or (eobp) (looking-at file-name-boundary-regexp))
  96.          (or (bobp) (string-match file-name-boundary-regexp
  97.                       (buffer-substring (1- (point))
  98.                             (point)))))
  99.     ""
  100.       (let* ((fnbeg (if begin
  101.             begin
  102.               (save-excursion
  103.             (re-search-backward file-name-boundary-regexp
  104.                         (point-min) 'just-move)
  105.             (if (looking-at file-name-boundary-regexp)
  106.                 (forward-char 1))
  107.             (point))))
  108.          (fnend (progn (re-search-forward file-name-boundary-regexp
  109.                           (point-max) 'just-move)
  110.                (or (eobp) (forward-char -1))
  111.                (point))))
  112.     (prog1
  113.         (buffer-substring fnbeg fnend)
  114.       (if delete
  115.           (delete-region fnbeg fnend)))))))
  116.