diff options
| author | Karl Heuer | 1997-06-28 21:27:18 +0000 |
|---|---|---|
| committer | Karl Heuer | 1997-06-28 21:27:18 +0000 |
| commit | 3788c735f77c99a57ce36d9143ee4d9c8d6f9440 (patch) | |
| tree | 7ff69bca631854ab7908f99d0d12b6654ca67f1b | |
| parent | 0a63b21287ea9de2c4a1aaaa3fd063baa9a2da92 (diff) | |
| download | emacs-3788c735f77c99a57ce36d9143ee4d9c8d6f9440.tar.gz emacs-3788c735f77c99a57ce36d9143ee4d9c8d6f9440.zip | |
XEmacs compatibility hacks cleaned up.
(ffap-url-fetcher): If `browse-url' is bound, use that.
(ffap-locate-file): New optional arg dir-ok.
(ffap-at-mouse): Fix return value.
| -rw-r--r-- | lisp/ffap.el | 291 |
1 files changed, 155 insertions, 136 deletions
diff --git a/lisp/ffap.el b/lisp/ffap.el index bb8cf9c4806..e97c217e4da 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el | |||
| @@ -5,7 +5,8 @@ | |||
| 5 | ;; Author: Michelangelo Grigni <mic@mathcs.emory.edu> | 5 | ;; Author: Michelangelo Grigni <mic@mathcs.emory.edu> |
| 6 | ;; Created: 29 Mar 1993 | 6 | ;; Created: 29 Mar 1993 |
| 7 | ;; Keywords: files, hypermedia, matching, mouse | 7 | ;; Keywords: files, hypermedia, matching, mouse |
| 8 | ;; X-URL: ftp://ftp.mathcs.emory.edu:/pub/mic/emacs/ | 8 | ;; X-URL: ftp://ftp.mathcs.emory.edu/pub/mic/emacs/ |
| 9 | ;; X-Source: this file is generated from ffap.epp | ||
| 9 | 10 | ||
| 10 | ;; This file is part of GNU Emacs. | 11 | ;; This file is part of GNU Emacs. |
| 11 | 12 | ||
| @@ -67,10 +68,10 @@ | |||
| 67 | ;; (setq ffap-machine-p-known 'accept) ; no pinging | 68 | ;; (setq ffap-machine-p-known 'accept) ; no pinging |
| 68 | ;; (setq ffap-url-regexp nil) ; disable URL features in ffap | 69 | ;; (setq ffap-url-regexp nil) ; disable URL features in ffap |
| 69 | ;; | 70 | ;; |
| 70 | ;; ffap uses w3 (if found) or else browse-url to fetch URL's. For | 71 | ;; ffap uses `browse-url' (if found, else `w3-fetch') to fetch URL's. |
| 71 | ;; a hairier `ffap-url-fetcher', try ffap-url.el (same ftp site). | 72 | ;; For a hairier `ffap-url-fetcher', try ffap-url.el (same ftp site). |
| 72 | ;; Also, you can add `ffap-menu-rescan' to various hooks to fontify | 73 | ;; Also, you can add `ffap-menu-rescan' to various hooks to fontify |
| 73 | ;; the file and URL references within a buffer. | 74 | ;; the file and URL references within a buffer. |
| 74 | 75 | ||
| 75 | 76 | ||
| 76 | ;;; Change Log: | 77 | ;;; Change Log: |
| @@ -97,16 +98,21 @@ | |||
| 97 | 98 | ||
| 98 | (provide 'ffap) | 99 | (provide 'ffap) |
| 99 | 100 | ||
| 100 | ;; The code is organized in pages, separated by formfeed characters. | 101 | ;; Please do not delete this variable, it is checked in bug reports. |
| 101 | ;; See the next two pages for standard customization ideas. | 102 | (defconst ffap-version "1.9-fsf <97/06/25 13:21:41 mic>" |
| 103 | "The version of ffap: \"Major.Minor-Build <Timestamp>\"") | ||
| 102 | 104 | ||
| 103 | |||
| 104 | ;;; User Variables: | ||
| 105 | 105 | ||
| 106 | (defgroup ffap nil | 106 | (defgroup ffap nil |
| 107 | "Find file or URL at point." | 107 | "Find file or URL at point." |
| 108 | :link '(url-link :tag "URL" "ftp://ftp.mathcs.emory.edu/pub/mic/emacs/") | ||
| 108 | :group 'matching) | 109 | :group 'matching) |
| 109 | 110 | ||
| 111 | ;; The code is organized in pages, separated by formfeed characters. | ||
| 112 | ;; See the next two pages for standard customization ideas. | ||
| 113 | |||
| 114 | |||
| 115 | ;;; User Variables: | ||
| 110 | 116 | ||
| 111 | (defun ffap-soft-value (name &optional default) | 117 | (defun ffap-soft-value (name &optional default) |
| 112 | "Return value of symbol with NAME, if it is interned. | 118 | "Return value of symbol with NAME, if it is interned. |
| @@ -218,16 +224,17 @@ ffap most of the time." | |||
| 218 | (put 'ffap-file-finder 'risky-local-variable t) | 224 | (put 'ffap-file-finder 'risky-local-variable t) |
| 219 | 225 | ||
| 220 | (defcustom ffap-url-fetcher | 226 | (defcustom ffap-url-fetcher |
| 221 | (cond ((fboundp 'w3-fetch) 'w3-fetch) | 227 | (if (fboundp 'browse-url) |
| 222 | ((fboundp 'browse-url-netscape) 'browse-url-netscape) | 228 | 'browse-url ; rely on browse-url-browser-function |
| 223 | (t 'w3-fetch)) | 229 | 'w3-fetch) |
| 224 | ;; Remote control references: | 230 | ;; Remote control references: |
| 225 | ;; http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/remote-control.html | 231 | ;; http://www.ncsa.uiuc.edu/SDG/Software/XMosaic/remote-control.html |
| 226 | ;; http://home.netscape.com/newsref/std/x-remote.html | 232 | ;; http://home.netscape.com/newsref/std/x-remote.html |
| 227 | "*A function of one argument, called by ffap to fetch an URL. | 233 | "*A function of one argument, called by ffap to fetch an URL. |
| 228 | Reasonable choices are `w3-fetch' or `browse-url-netscape'. | 234 | Reasonable choices are `w3-fetch' or a `browse-url-*' function. |
| 229 | For a fancier alternative, get ffap-url.el." | 235 | For a fancy alternative, get ffap-url.el." |
| 230 | :type '(choice (const w3-fetch) | 236 | :type '(choice (const w3-fetch) |
| 237 | (const browse-url) ; in recent versions of browse-url | ||
| 231 | (const browse-url-netscape) | 238 | (const browse-url-netscape) |
| 232 | (const browse-url-mosaic) | 239 | (const browse-url-mosaic) |
| 233 | function) | 240 | function) |
| @@ -235,18 +242,16 @@ For a fancier alternative, get ffap-url.el." | |||
| 235 | (put 'ffap-url-fetcher 'risky-local-variable t) | 242 | (put 'ffap-url-fetcher 'risky-local-variable t) |
| 236 | 243 | ||
| 237 | 244 | ||
| 238 | ;;; Compatibility (XEmacs code suppressed in this version): | 245 | ;;; Compatibility: |
| 239 | 246 | ;; | |
| 240 | (progn | 247 | ;; This version of ffap supports Emacs 20 only, see the ftp site |
| 241 | (defalias 'ffap-make-overlay 'make-overlay) | 248 | ;; for a more general version. The following functions are necessary |
| 242 | (defalias 'ffap-delete-overlay 'delete-overlay) ; reusable | 249 | ;; "leftovers" from the more general version. |
| 243 | (defalias 'ffap-move-overlay 'move-overlay) | 250 | |
| 244 | (defalias 'ffap-overlay-put 'overlay-put) ; 'face | 251 | (defun ffap-mouse-event nil ; current mouse event, or nil |
| 245 | (defalias 'ffap-find-face 'internal-find-face) | 252 | (and (listp last-nonmenu-event) last-nonmenu-event)) |
| 246 | (defun ffap-mouse-event nil ; current mouse event, or nil | 253 | (defun ffap-event-buffer (event) |
| 247 | (and (listp last-nonmenu-event) last-nonmenu-event)) | 254 | (window-buffer (car (event-start event)))) |
| 248 | (defun ffap-event-buffer (event) (window-buffer (car (event-start event)))) | ||
| 249 | ) | ||
| 250 | 255 | ||
| 251 | 256 | ||
| 252 | ;;; Find Next Thing in buffer (`ffap-next'): | 257 | ;;; Find Next Thing in buffer (`ffap-next'): |
| @@ -355,8 +360,9 @@ What `ffap-machine-p' does with hostnames that have an unknown domain | |||
| 355 | (defun ffap-what-domain (domain) | 360 | (defun ffap-what-domain (domain) |
| 356 | ;; Like what-domain in mail-extr.el, returns string or nil. | 361 | ;; Like what-domain in mail-extr.el, returns string or nil. |
| 357 | (require 'mail-extr) | 362 | (require 'mail-extr) |
| 358 | (get (intern-soft (downcase domain) mail-extr-all-top-level-domains) | 363 | (let ((ob (or (ffap-soft-value "mail-extr-all-top-level-domains") |
| 359 | 'domain-name)) | 364 | (ffap-soft-value "all-top-level-domains")))) ; XEmacs |
| 365 | (and ob (get (intern-soft (downcase domain) ob) 'domain-name)))) | ||
| 360 | 366 | ||
| 361 | (defun ffap-machine-p (host &optional service quiet strategy) | 367 | (defun ffap-machine-p (host &optional service quiet strategy) |
| 362 | "Decide whether HOST is the name of a real, reachable machine. | 368 | "Decide whether HOST is the name of a real, reachable machine. |
| @@ -444,15 +450,37 @@ Returned values: | |||
| 444 | (funcall found fullname name)))) | 450 | (funcall found fullname name)))) |
| 445 | ;; (ffap-replace-path-component "/who@foo.com:/whatever" "/new") | 451 | ;; (ffap-replace-path-component "/who@foo.com:/whatever" "/new") |
| 446 | 452 | ||
| 447 | (defun ffap-file-exists-string (file) | 453 | (defun ffap-file-suffix (file) |
| 448 | ;; With certain packages (ange-ftp, jka-compr?) file-exists-p | 454 | "Return trailing \".foo\" suffix of FILE, or nil if none." |
| 449 | ;; sometimes returns a nicer string than it is given. Otherwise, it | 455 | (let ((pos (string-match "\\.[^./]*\\'" file))) |
| 450 | ;; just returns nil or t. | 456 | (and pos (substring file pos nil)))) |
| 451 | "Return FILE \(maybe modified\) if it exists, else nil." | 457 | |
| 452 | (and file ; quietly reject nil | 458 | (defvar ffap-compression-suffixes '(".gz" ".Z") ; .z is mostly dead |
| 453 | (let ((exists (file-exists-p file))) | 459 | "List of suffixes tried by `ffap-file-exists-string'.") |
| 454 | (and exists (if (stringp exists) exists file))))) | 460 | |
| 455 | 461 | (defun ffap-file-exists-string (file &optional nomodify) | |
| 462 | ;; Early jka-compr versions modified file-exists-p to return the | ||
| 463 | ;; filename, maybe modified by adding a suffix like ".gz". That | ||
| 464 | ;; broke the interface of file-exists-p, so it was later dropped. | ||
| 465 | ;; Here we document and simulate the old behavior. | ||
| 466 | "Return FILE \(maybe modified\) if it exists, else nil. | ||
| 467 | When using jka-compr (a.k.a. `auto-compression-mode'), the returned | ||
| 468 | name may have a suffix added from `ffap-compression-suffixes'. | ||
| 469 | The optional NOMODIFY argument suppresses the extra search." | ||
| 470 | (cond | ||
| 471 | ((not file) nil) ; quietly reject nil | ||
| 472 | ((file-exists-p file) file) ; try unmodified first | ||
| 473 | ;; three reasons to suppress search: | ||
| 474 | (nomodify nil) | ||
| 475 | ((not (rassq 'jka-compr-handler file-name-handler-alist)) nil) | ||
| 476 | ((member (ffap-file-suffix file) ffap-compression-suffixes) nil) | ||
| 477 | (t ; ok, do the search | ||
| 478 | (let ((list ffap-compression-suffixes) try ret) | ||
| 479 | (while list | ||
| 480 | (if (file-exists-p (setq try (concat file (car list)))) | ||
| 481 | (setq ret try list nil) | ||
| 482 | (setq list (cdr list)))) | ||
| 483 | ret)))) | ||
| 456 | 484 | ||
| 457 | (defun ffap-file-remote-p (filename) | 485 | (defun ffap-file-remote-p (filename) |
| 458 | "If FILENAME looks remote, return it \(maybe slightly improved\)." | 486 | "If FILENAME looks remote, return it \(maybe slightly improved\)." |
| @@ -562,12 +590,9 @@ Looks at `ffap-ftp-default-user', returns \"\" for \"localhost\"." | |||
| 562 | ((and ffap-url-unwrap-local (ffap-url-unwrap-local url))) | 590 | ((and ffap-url-unwrap-local (ffap-url-unwrap-local url))) |
| 563 | ((and ffap-url-unwrap-remote ffap-ftp-regexp | 591 | ((and ffap-url-unwrap-remote ffap-ftp-regexp |
| 564 | (ffap-url-unwrap-remote url))) | 592 | (ffap-url-unwrap-remote url))) |
| 565 | ;; This might autoload the url package, oh well: | 593 | ((fboundp 'url-normalize-url) ; may autoload url (part of w3) |
| 566 | (t (let ((normal (and (fboundp 'url-normalize-url) | 594 | (url-normalize-url url)) |
| 567 | (url-normalize-url url)))) | 595 | (url))) |
| 568 | ;; In case url-normalize-url is confused: | ||
| 569 | (or (and normal (not (zerop (length normal))) normal) | ||
| 570 | url))))) | ||
| 571 | 596 | ||
| 572 | 597 | ||
| 573 | ;;; Path Handling: | 598 | ;;; Path Handling: |
| @@ -659,24 +684,23 @@ kpathsea, a library used by some versions of TeX." | |||
| 659 | (list dir)))) | 684 | (list dir)))) |
| 660 | path))) | 685 | path))) |
| 661 | 686 | ||
| 662 | (defvar ffap-locate-jka-suffixes t | 687 | (defun ffap-locate-file (file &optional nosuffix path dir-ok) |
| 663 | "List of compression suffixes tried by `ffap-locate-file'. | 688 | ;; The Emacs 20 version of locate-library could almost replace this, |
| 664 | 689 | ;; except it does not let us overrride the suffix list. The | |
| 665 | If not a list, it will be initialized by `ffap-locate-file', depending | 690 | ;; compression-suffixes search moved to ffap-file-exists-string. |
| 666 | on whether you use jka-compr (a.k.a. `auto-compression-mode'). | ||
| 667 | Typical values are nil or '(\".gz\" \".Z\").") ; .z is dead | ||
| 668 | |||
| 669 | (defun ffap-locate-file (file &optional nosuffix path) | ||
| 670 | ;; Note the Emacs 20 version of locate-library could almost | ||
| 671 | ;; replace this function, except that it does not let us overrride | ||
| 672 | ;; the list of suffixes. | ||
| 673 | "A generic path-searching function, mimics `load' by default. | 691 | "A generic path-searching function, mimics `load' by default. |
| 674 | Returns path to file that \(load FILE\) would load, or nil. | 692 | Returns path to file that \(load FILE\) would load, or nil. |
| 675 | Optional NOSUFFIX, if nil or t, is like the fourth argument | 693 | Optional NOSUFFIX, if nil or t, is like the fourth argument |
| 676 | for load: whether to try the suffixes (\".elc\" \".el\" \"\"). | 694 | for load: whether to try the suffixes (\".elc\" \".el\" \"\"). |
| 677 | If a nonempty list, it is a list of suffixes to try instead. | 695 | If a nonempty list, it is a list of suffixes to try instead. |
| 678 | Optional PATH is a list of directories instead of `load-path'." | 696 | Optional PATH is a list of directories instead of `load-path'. |
| 697 | Optional DIR-OK means that returning a directory is allowed, | ||
| 698 | DIR-OK is already implicit if FILE looks like a directory. | ||
| 699 | |||
| 700 | This uses ffap-file-exists-string, which may try adding suffixes from | ||
| 701 | `ffap-compression-suffixes'." | ||
| 679 | (or path (setq path load-path)) | 702 | (or path (setq path load-path)) |
| 703 | (or dir-ok (setq dir-ok (equal "" (file-name-nondirectory file)))) | ||
| 680 | (if (file-name-absolute-p file) | 704 | (if (file-name-absolute-p file) |
| 681 | (setq path (list (file-name-directory file)) | 705 | (setq path (list (file-name-directory file)) |
| 682 | file (file-name-nondirectory file))) | 706 | file (file-name-nondirectory file))) |
| @@ -684,36 +708,19 @@ Optional PATH is a list of directories instead of `load-path'." | |||
| 684 | (cond | 708 | (cond |
| 685 | ((consp nosuffix) nosuffix) | 709 | ((consp nosuffix) nosuffix) |
| 686 | (nosuffix '("")) | 710 | (nosuffix '("")) |
| 687 | (t '(".elc" ".el" ""))))) | 711 | (t '(".elc" ".el" "")))) |
| 688 | ;; Note we no longer check for old versions of jka-compr, that | 712 | suffixes try found) |
| 689 | ;; would aggressively try to convert any foo to foo.gz. | 713 | (while path |
| 690 | (or (listp ffap-locate-jka-suffixes) | 714 | (setq suffixes suffixes-to-try) |
| 691 | (setq ffap-locate-jka-suffixes | 715 | (while suffixes |
| 692 | (and (rassq 'jka-compr-handler file-name-handler-alist) | 716 | (setq try (ffap-file-exists-string |
| 693 | '(".gz" ".Z")))) ; ".z" is dead, "" is implicit | 717 | (expand-file-name |
| 694 | (if ffap-locate-jka-suffixes ; | 718 | (concat file (car suffixes)) (car path)))) |
| 695 | (setq suffixes-to-try | 719 | (if (and try (or dir-ok (not (file-directory-p try)))) |
| 696 | (apply 'nconc | 720 | (setq found try suffixes nil path nil) |
| 697 | (mapcar | 721 | (setq suffixes (cdr suffixes)))) |
| 698 | (function | 722 | (setq path (cdr path))) |
| 699 | (lambda (suf) | 723 | found)) |
| 700 | (cons suf | ||
| 701 | (mapcar | ||
| 702 | (function (lambda (x) (concat suf x))) | ||
| 703 | ffap-locate-jka-suffixes)))) | ||
| 704 | suffixes-to-try)))) | ||
| 705 | (let (found suffixes) | ||
| 706 | (while (and path (not found)) | ||
| 707 | (setq suffixes suffixes-to-try) | ||
| 708 | (while (and suffixes (not found)) | ||
| 709 | (let ((try (expand-file-name | ||
| 710 | (concat file (car suffixes)) | ||
| 711 | (car path)))) | ||
| 712 | (if (and (file-exists-p try) (not (file-directory-p try))) | ||
| 713 | (setq found try))) | ||
| 714 | (setq suffixes (cdr suffixes))) | ||
| 715 | (setq path (cdr path))) | ||
| 716 | found))) | ||
| 717 | 724 | ||
| 718 | 725 | ||
| 719 | ;;; Action List (`ffap-alist'): | 726 | ;;; Action List (`ffap-alist'): |
| @@ -731,6 +738,7 @@ Optional PATH is a list of directories instead of `load-path'." | |||
| 731 | ("\\`[-a-z]+\\'" . ffap-info-3) ; (emacs)Top [only in the parentheses] | 738 | ("\\`[-a-z]+\\'" . ffap-info-3) ; (emacs)Top [only in the parentheses] |
| 732 | ("\\.elc?\\'" . ffap-el) ; simple.el, simple.elc | 739 | ("\\.elc?\\'" . ffap-el) ; simple.el, simple.elc |
| 733 | (emacs-lisp-mode . ffap-el-mode) ; rmail, gnus, simple, custom | 740 | (emacs-lisp-mode . ffap-el-mode) ; rmail, gnus, simple, custom |
| 741 | ;; (lisp-interaction-mode . ffap-el-mode) ; maybe | ||
| 734 | (finder-mode . ffap-el-mode) ; type {C-h p} and try it | 742 | (finder-mode . ffap-el-mode) ; type {C-h p} and try it |
| 735 | (help-mode . ffap-el-mode) ; maybe useful | 743 | (help-mode . ffap-el-mode) ; maybe useful |
| 736 | (c++-mode . ffap-c-mode) ; search ffap-c-path | 744 | (c++-mode . ffap-c-mode) ; search ffap-c-path |
| @@ -758,6 +766,21 @@ url, or nil. If nil, search the alist for further matches.") | |||
| 758 | 766 | ||
| 759 | (put 'ffap-alist 'risky-local-variable t) | 767 | (put 'ffap-alist 'risky-local-variable t) |
| 760 | 768 | ||
| 769 | ;; Example `ffap-alist' modifications: | ||
| 770 | ;; | ||
| 771 | ;; (setq ffap-alist ; remove a feature in `ffap-alist' | ||
| 772 | ;; (delete (assoc 'c-mode ffap-alist) ffap-alist)) | ||
| 773 | ;; | ||
| 774 | ;; (setq ffap-alist ; add something to `ffap-alist' | ||
| 775 | ;; (cons | ||
| 776 | ;; (cons "^YSN[0-9]+$" | ||
| 777 | ;; (defun ffap-ysn (name) | ||
| 778 | ;; (concat | ||
| 779 | ;; "http://www.physics.uiuc.edu/" | ||
| 780 | ;; "ysn/httpd/htdocs/ysnarchive/issuefiles/" | ||
| 781 | ;; (substring name 3) ".html"))) | ||
| 782 | ;; ffap-alist)) | ||
| 783 | |||
| 761 | 784 | ||
| 762 | ;;; Action Definitions: | 785 | ;;; Action Definitions: |
| 763 | ;; | 786 | ;; |
| @@ -1157,7 +1180,9 @@ which may actually result in an url rather than a filename." | |||
| 1157 | (or (ffap-url-p guess) | 1180 | (or (ffap-url-p guess) |
| 1158 | (progn | 1181 | (progn |
| 1159 | (or (ffap-file-remote-p guess) | 1182 | (or (ffap-file-remote-p guess) |
| 1160 | (setq guess (abbreviate-file-name (expand-file-name guess)))) | 1183 | (setq guess |
| 1184 | (abbreviate-file-name (expand-file-name guess)) | ||
| 1185 | )) | ||
| 1161 | (setq dir (file-name-directory guess)))) | 1186 | (setq dir (file-name-directory guess)))) |
| 1162 | (setq guess | 1187 | (setq guess |
| 1163 | (completing-read | 1188 | (completing-read |
| @@ -1242,22 +1267,24 @@ Uses the face `ffap' if it is defined, or else `highlight'." | |||
| 1242 | (cond | 1267 | (cond |
| 1243 | (remove | 1268 | (remove |
| 1244 | (and ffap-highlight-overlay | 1269 | (and ffap-highlight-overlay |
| 1245 | (ffap-delete-overlay ffap-highlight-overlay))) | 1270 | (delete-overlay ffap-highlight-overlay)) |
| 1271 | ) | ||
| 1246 | ((not ffap-highlight) nil) | 1272 | ((not ffap-highlight) nil) |
| 1247 | (ffap-highlight-overlay | 1273 | (ffap-highlight-overlay |
| 1248 | (ffap-move-overlay ffap-highlight-overlay | 1274 | (move-overlay |
| 1249 | (car ffap-string-at-point-region) | 1275 | ffap-highlight-overlay |
| 1250 | (nth 1 ffap-string-at-point-region) | 1276 | (car ffap-string-at-point-region) |
| 1251 | (current-buffer))) | 1277 | (nth 1 ffap-string-at-point-region) |
| 1278 | (current-buffer))) | ||
| 1252 | (t | 1279 | (t |
| 1253 | (setq ffap-highlight-overlay | 1280 | (setq ffap-highlight-overlay |
| 1254 | (apply 'ffap-make-overlay ffap-string-at-point-region)) | 1281 | (apply 'make-overlay ffap-string-at-point-region)) |
| 1255 | (ffap-overlay-put ffap-highlight-overlay 'face | 1282 | (overlay-put ffap-highlight-overlay 'face |
| 1256 | (if (ffap-find-face 'ffap) | 1283 | (if (internal-find-face 'ffap) |
| 1257 | 'ffap 'highlight))))) | 1284 | 'ffap 'highlight))))) |
| 1258 | 1285 | ||
| 1259 | 1286 | ||
| 1260 | ;;; The big cheese (`ffap'): | 1287 | ;;; Main Entrance (`find-file-at-point' == `ffap'): |
| 1261 | 1288 | ||
| 1262 | (defun ffap-guesser nil | 1289 | (defun ffap-guesser nil |
| 1263 | "Return file or URL or nil, guessed from text around point." | 1290 | "Return file or URL or nil, guessed from text around point." |
| @@ -1271,12 +1298,15 @@ Uses the face `ffap' if it is defined, or else `highlight'." | |||
| 1271 | ;; Does guess and prompt step for find-file-at-point. | 1298 | ;; Does guess and prompt step for find-file-at-point. |
| 1272 | ;; Extra complication for the temporary highlighting. | 1299 | ;; Extra complication for the temporary highlighting. |
| 1273 | (unwind-protect | 1300 | (unwind-protect |
| 1274 | (ffap-read-file-or-url | 1301 | ;; This catch will let ffap-alist entries do their own prompting |
| 1275 | (if ffap-url-regexp "Find file or URL: " "Find file: ") | 1302 | ;; and then maybe skip over this prompt (ff-paths, for example). |
| 1276 | (prog1 | 1303 | (catch 'ffap-prompter |
| 1277 | (setq guess (or guess (ffap-guesser))) | 1304 | (ffap-read-file-or-url |
| 1278 | (and guess (ffap-highlight)) | 1305 | (if ffap-url-regexp "Find file or URL: " "Find file: ") |
| 1279 | )) | 1306 | (prog1 |
| 1307 | (setq guess (or guess (ffap-guesser))) ; using ffap-alist here | ||
| 1308 | (and guess (ffap-highlight)) | ||
| 1309 | ))) | ||
| 1280 | (ffap-highlight t))) | 1310 | (ffap-highlight t))) |
| 1281 | 1311 | ||
| 1282 | ;;;###autoload | 1312 | ;;;###autoload |
| @@ -1336,9 +1366,9 @@ For example, try \":/\" for URL (and some ftp) references.") | |||
| 1336 | (make-variable-buffer-local 'ffap-menu-alist) | 1366 | (make-variable-buffer-local 'ffap-menu-alist) |
| 1337 | 1367 | ||
| 1338 | (defvar ffap-menu-text-plist | 1368 | (defvar ffap-menu-text-plist |
| 1339 | (and window-system | 1369 | (cond |
| 1340 | '(face bold mouse-face highlight) ; keymap <mousy-map> | 1370 | ((not window-system) nil) |
| 1341 | ) | 1371 | (t '(face bold mouse-face highlight))) ; keymap <mousy-map> |
| 1342 | "Text properties applied to strings found by `ffap-menu-rescan'. | 1372 | "Text properties applied to strings found by `ffap-menu-rescan'. |
| 1343 | These properties may be used to fontify the menu references.") | 1373 | These properties may be used to fontify the menu references.") |
| 1344 | 1374 | ||
| @@ -1470,8 +1500,11 @@ Ignored when `ffap-at-mouse' is called programmatically.") | |||
| 1470 | ;;;###autoload | 1500 | ;;;###autoload |
| 1471 | (defun ffap-at-mouse (e) | 1501 | (defun ffap-at-mouse (e) |
| 1472 | "Find file or url guessed from text around mouse click. | 1502 | "Find file or url guessed from text around mouse click. |
| 1473 | Interactively, calls `ffap-at-mouse-fallback' if nothing is found. | 1503 | Interactively, calls `ffap-at-mouse-fallback' if no guess is found. |
| 1474 | Returns t or nil to indicate success." | 1504 | Return value: |
| 1505 | * if a guess string is found, return it (after finding it) | ||
| 1506 | * if the fallback is called, return whatever it returns | ||
| 1507 | * otherwise, nil" | ||
| 1475 | (interactive "e") | 1508 | (interactive "e") |
| 1476 | (let ((guess | 1509 | (let ((guess |
| 1477 | ;; Maybe less surprising without the save-excursion? | 1510 | ;; Maybe less surprising without the save-excursion? |
| @@ -1489,12 +1522,13 @@ Returns t or nil to indicate success." | |||
| 1489 | (sit-for 0) ; display | 1522 | (sit-for 0) ; display |
| 1490 | (message "Finding `%s'" guess) | 1523 | (message "Finding `%s'" guess) |
| 1491 | (find-file-at-point guess) | 1524 | (find-file-at-point guess) |
| 1492 | t) ; success: return non-nil | 1525 | guess) ; success: return non-nil |
| 1493 | (ffap-highlight t))) | 1526 | (ffap-highlight t))) |
| 1494 | ((interactive-p) | 1527 | ((interactive-p) |
| 1495 | (if ffap-at-mouse-fallback | 1528 | (if ffap-at-mouse-fallback |
| 1496 | (call-interactively ffap-at-mouse-fallback) | 1529 | (call-interactively ffap-at-mouse-fallback) |
| 1497 | (message "No file or url found at mouse click."))) | 1530 | (message "No file or url found at mouse click.") |
| 1531 | nil)) ; no fallback, return nil | ||
| 1498 | ;; failure: return nil | 1532 | ;; failure: return nil |
| 1499 | ))) | 1533 | ))) |
| 1500 | 1534 | ||
| @@ -1542,7 +1576,7 @@ Only intended for interactive use." | |||
| 1542 | (let ((reporter-prompt-for-summary-p t)) | 1576 | (let ((reporter-prompt-for-summary-p t)) |
| 1543 | (reporter-submit-bug-report | 1577 | (reporter-submit-bug-report |
| 1544 | "Michelangelo Grigni <mic@mathcs.emory.edu>" | 1578 | "Michelangelo Grigni <mic@mathcs.emory.edu>" |
| 1545 | "ffap" ; version? just rely on Emacs version | 1579 | "ffap" |
| 1546 | (mapcar 'intern (all-completions "ffap-" obarray 'boundp))))) | 1580 | (mapcar 'intern (all-completions "ffap-" obarray 'boundp))))) |
| 1547 | 1581 | ||
| 1548 | (fset 'ffap-submit-bug 'ffap-bug) ; another likely name | 1582 | (fset 'ffap-submit-bug 'ffap-bug) ; another likely name |
| @@ -1594,19 +1628,19 @@ Only intended for interactive use." | |||
| 1594 | ;;; Offer default global bindings (`ffap-bindings'): | 1628 | ;;; Offer default global bindings (`ffap-bindings'): |
| 1595 | 1629 | ||
| 1596 | (defvar ffap-bindings | 1630 | (defvar ffap-bindings |
| 1597 | '( | 1631 | '( |
| 1598 | (global-set-key [S-mouse-3] 'ffap-at-mouse) | 1632 | (global-set-key [S-mouse-3] 'ffap-at-mouse) |
| 1599 | (global-set-key [C-S-mouse-3] 'ffap-menu) | 1633 | (global-set-key [C-S-mouse-3] 'ffap-menu) |
| 1600 | (global-set-key "\C-x\C-f" 'find-file-at-point) | 1634 | (global-set-key "\C-x\C-f" 'find-file-at-point) |
| 1601 | (global-set-key "\C-x4f" 'ffap-other-window) | 1635 | (global-set-key "\C-x4f" 'ffap-other-window) |
| 1602 | (global-set-key "\C-x5f" 'ffap-other-frame) | 1636 | (global-set-key "\C-x5f" 'ffap-other-frame) |
| 1603 | (add-hook 'gnus-summary-mode-hook 'ffap-gnus-hook) | 1637 | (add-hook 'gnus-summary-mode-hook 'ffap-gnus-hook) |
| 1604 | (add-hook 'gnus-article-mode-hook 'ffap-gnus-hook) | 1638 | (add-hook 'gnus-article-mode-hook 'ffap-gnus-hook) |
| 1605 | (add-hook 'vm-mode-hook 'ffap-ro-mode-hook) | 1639 | (add-hook 'vm-mode-hook 'ffap-ro-mode-hook) |
| 1606 | (add-hook 'rmail-mode-hook 'ffap-ro-mode-hook) | 1640 | (add-hook 'rmail-mode-hook 'ffap-ro-mode-hook) |
| 1607 | ;; (setq dired-x-hands-off-my-keys t) ; the default | 1641 | ;; (setq dired-x-hands-off-my-keys t) ; the default |
| 1608 | ) | 1642 | ) |
| 1609 | "List of binding forms evaluated by function `ffap-bindings'. | 1643 | "List of binding forms evaluated by function `ffap-bindings'. |
| 1610 | A reasonable ffap installation needs just these two lines: | 1644 | A reasonable ffap installation needs just these two lines: |
| 1611 | (require 'ffap) | 1645 | (require 'ffap) |
| 1612 | (ffap-bindings) | 1646 | (ffap-bindings) |
| @@ -1616,20 +1650,5 @@ Of course if you do not like these bindings, just roll your own!") | |||
| 1616 | "Evaluate the forms in variable `ffap-bindings'." | 1650 | "Evaluate the forms in variable `ffap-bindings'." |
| 1617 | (eval (cons 'progn ffap-bindings))) | 1651 | (eval (cons 'progn ffap-bindings))) |
| 1618 | 1652 | ||
| 1619 | ;; Example modifications: | ||
| 1620 | ;; | ||
| 1621 | ;; (setq ffap-alist ; remove a feature in `ffap-alist' | ||
| 1622 | ;; (delete (assoc 'c-mode ffap-alist) ffap-alist)) | ||
| 1623 | ;; | ||
| 1624 | ;; (setq ffap-alist ; add something to `ffap-alist' | ||
| 1625 | ;; (cons | ||
| 1626 | ;; (cons "^YSN[0-9]+$" | ||
| 1627 | ;; (defun ffap-ysn (name) | ||
| 1628 | ;; (concat | ||
| 1629 | ;; "http://www.physics.uiuc.edu/" | ||
| 1630 | ;; "ysn/httpd/htdocs/ysnarchive/issuefiles/" | ||
| 1631 | ;; (substring name 3) ".html"))) | ||
| 1632 | ;; ffap-alist)) | ||
| 1633 | |||
| 1634 | 1653 | ||
| 1635 | ;;; ffap.el ends here | 1654 | ;;; ffap.el ends here |