diff --git a/lisp/ffap.el b/lisp/ffap.el index bb4c4612c83..647e52bb5fb 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -107,12 +107,14 @@ ;; This function is used inside defvars: -(defun ffap-soft-value (name &optional default) +(defmacro ffap-soft-value (name &optional default) "Return value of symbol with NAME, if it is interned. Otherwise return nil (or the optional DEFAULT value)." ;; Bug: (ffap-soft-value "nil" 5) --> 5 (let ((sym (intern-soft name))) - (if (and sym (boundp sym)) (symbol-value sym) default))) + (if (and sym (boundp sym)) + sym + `(quote ,default)))) (defcustom ffap-ftp-regexp @@ -142,10 +144,7 @@ This is ignored if `ffap-ftp-regexp' is nil." :group 'ffap) (defcustom ffap-ftp-default-user - (if (or (equal (ffap-soft-value "ange-ftp-default-user") "anonymous") - (equal (ffap-soft-value "efs-default-user") "anonymous")) - nil - "anonymous") + "anonymous" "*User name in ftp paths generated by `ffap-host-to-path'. nil to rely on `efs-default-user' or `ange-ftp-default-user'." :type '(choice (const :tag "Default" nil) @@ -252,7 +251,12 @@ For a fancier alternative, get ffap-url.el." :type 'regexp :group 'ffap) -(defvar ffap-next-guess nil "Last value returned by `ffap-next-guess'.") +(defvar ffap-next-guess nil + "Last value returned by `ffap-next-guess'.") + +(defvar ffap-string-at-point-region '(1 1) + "List (BEG END), last region returned by `ffap-string-at-point'.") + (defun ffap-next-guess (&optional back lim) "Move point to next file or URL, and return it as a string. If nothing is found, leave point at limit and return nil. @@ -360,8 +364,6 @@ What `ffap-machine-p' does with hostnames that have an unknown domain (defun ffap-what-domain (domain) ;; Like what-domain in mail-extr.el, returns string or nil. (require 'mail-extr) - (defvar mail-extr-all-top-level-domains - (ffap-soft-value "all-top-level-domains" obarray)) ; XEmacs, old Emacs (get (intern-soft (downcase domain) mail-extr-all-top-level-domains) 'domain-name)) @@ -477,6 +479,12 @@ Looks at `ffap-ftp-default-user', returns \"\" for \"localhost\"." (ffap-ftp-regexp (ffap-host-to-path mach)) )) +(defvar ffap-newsgroup-regexp "^[a-z]+\\.[-+a-z_0-9.]+$" + "Strings not matching this fail `ffap-newsgroup-p'.") +(defvar ffap-newsgroup-heads ; entirely inadequate + '("alt" "comp" "gnu" "misc" "news" "sci" "soc" "talk") + "Used by `ffap-newsgroup-p' if gnus is not running.") + (defun ffap-newsgroup-p (string) "Return STRING if it looks like a newsgroup name, else nil." (and @@ -502,11 +510,6 @@ Looks at `ffap-ftp-default-user', returns \"\" for \"localhost\"." (setq ret string)))) ;; Is there ever a need to modify string as a newsgroup name? ret))) -(defvar ffap-newsgroup-regexp "^[a-z]+\\.[-+a-z_0-9.]+$" - "Strings not matching this fail `ffap-newsgroup-p'.") -(defvar ffap-newsgroup-heads ; entirely inadequate - '("alt" "comp" "gnu" "misc" "news" "sci" "soc" "talk") - "Used by `ffap-newsgroup-p' if gnus is not running.") (defsubst ffap-url-p (string) "If STRING looks like an url, return it (maybe improved), else nil." @@ -603,135 +606,27 @@ Uses `path-separator' to separate the path into directories." (defvar ffap-alist ;; A big mess! Parts are probably useless. - (list - (cons "\\.info\\'" - (defun ffap-info (name) - (locate-library - name '("" ".info") - (or (ffap-soft-value "Info-directory-list") - (ffap-soft-value "Info-default-directory-list") - ;; v18: - (list (ffap-soft-value "Info-directory" "~/info/")))))) - ;; Since so many info files do not have .info extension, also do this: - (cons "\\`info/" - (defun ffap-info-2 (name) (ffap-info (substring name 5)))) - (cons "\\`[-a-z]+\\'" - ;; This ignores the node! "(emacs)Top" same as "(emacs)Intro" - (defun ffap-info-3 (name) - (and (equal (ffap-string-around) "()") (ffap-info name)))) - (cons "\\.elc?\\'" - (defun ffap-el (name) (locate-library name t))) - (cons 'emacs-lisp-mode - (defun ffap-el-mode (name) - ;; We do not bother with "" here, since it was considered above. - ;; Also ignore "elc", for speed (who else reads elc files?) - (and (not (string-match "\\.el\\'" name)) - (locate-library name '(".el"))))) - '(finder-mode . ffap-el-mode) ; v19: {C-h p} - '(help-mode . ffap-el-mode) ; v19.29 - (cons 'c-mode - (progn - ;; Need better defaults here! - (defvar ffap-c-path '("/usr/include" "/usr/local/include")) - (defun ffap-c-mode (name) - (locate-library name t ffap-c-path)))) - '(c++-mode . ffap-c-mode) - '(cc-mode . ffap-c-mode) - '("\\.\\([chCH]\\|cc\\|hh\\)\\'" . ffap-c-mode) - (cons 'tex-mode - ;; Complicated because auctex may not be loaded yet. - (progn - (defvar ffap-tex-path - t ; delayed initialization - "Path where `ffap-tex-mode' looks for tex files. -If t, `ffap-tex-init' will initialize this when needed.") - (defun ffap-tex-init nil - ;; Compute ffap-tex-path if it is now t. - (and (eq t ffap-tex-path) - (message "Initializing ffap-tex-path ...") - (setq ffap-tex-path - (ffap-reduce-path - (append - (list ".") - (ffap-list-env "TEXINPUTS") - ;; (ffap-list-env "BIBINPUTS") - (ffap-add-subdirs - (ffap-list-env "TEXINPUTS_SUBDIR" - (ffap-soft-value - "TeX-macro-global" - '("/usr/local/lib/tex/macros" - "/usr/local/lib/tex/inputs") - )))))))) - (defun ffap-tex-mode (name) - (ffap-tex-init) - (locate-library name '(".tex" "") ffap-tex-path)))) - (cons 'latex-mode - (defun ffap-latex-mode (name) - (ffap-tex-init) - ;; Any real need for "" here? - (locate-library name '(".cls" ".sty" ".tex" "") - ffap-tex-path))) - (cons "\\.\\(tex\\|sty\\|doc\\|cls\\)\\'" - (defun ffap-tex (name) - (ffap-tex-init) - (locate-library name t ffap-tex-path))) - (cons "\\.bib\\'" - (defun ffap-bib (name) - (locate-library - name t - (ffap-list-env "BIBINPUTS" '("/usr/local/lib/tex/macros/bib"))))) - (cons 'math-mode - (defun ffap-math-mode (name) - (while (string-match "`" name) - (setq name (concat (substring name 0 (match-beginning 0)) - "/" - (substring name (match-end 0))))) - (locate-library - name '(".m" "") (ffap-soft-value "Mathematica-search-path")))) - (cons "\\`\\." (defun ffap-home (name) (locate-library name t '("~")))) - (cons "\\`~/" - ;; Maybe a "Lisp Code Directory" reference: - (defun ffap-lcd (name) - (and - (or - ;; lisp-dir-apropos output buffer: - (string-match "Lisp Code Dir" (buffer-name)) - ;; Inside an LCD entry like |~/misc/ffap.el.Z|, - ;; or maybe the holy LCD-Datafile itself: - (member (ffap-string-around) '("||" "|\n"))) - (concat - ;; lispdir.el may not be loaded yet: - (ffap-host-to-path - (ffap-soft-value "elisp-archive-host" - "archive.cis.ohio-state.edu")) - (file-name-as-directory - (ffap-soft-value "elisp-archive-directory" - "/pub/gnu/emacs/elisp-archive/")) - (substring name 2))))) - (cons "^[Rr][Ff][Cc][- #]?\\([0-9]+\\)" ; no $ - (progn - (defvar ffap-rfc-path - (concat (ffap-host-to-path "ds.internic.net") "/rfc/rfc%s.txt")) - (defun ffap-rfc (name) - (format ffap-rfc-path - (substring name (match-beginning 1) (match-end 1)))))) - (cons "\\`[^/]*\\'" - (defun ffap-dired (name) - (let ((pt (point)) dir try) - (save-excursion - (and (progn - (beginning-of-line) - (looking-at " *[-d]r[-w][-x][-r][-w][-x][-r][-w][-x] ")) - (re-search-backward "^ *$" nil t) - (re-search-forward "^ *\\([^ \t\n:]*\\):\n *total " pt t) - (file-exists-p - (setq try - (expand-file-name - name - (buffer-substring - (match-beginning 1) (match-end 1))))) - try))))) - ) + '( + ("\\.info\\'" . ffap-info) + ;; Since so many info files do not have .info extension, also do this: + ("\\`info/" . ffap-info-2) + ("\\`[-a-z]+\\'" . ffap-info-3) + ("\\.elc?\\'" . ffap-el) + (emacs-lisp-mode . ffap-el-mode) + (finder-mode . ffap-el-mode) ; v19: {C-h p} + (help-mode . ffap-el-mode) ; v19.29 + (c++-mode . ffap-c-mode) + (cc-mode . ffap-c-mode) + ("\\.\\([chCH]\\|cc\\|hh\\)\\'" . ffap-c-mode) + (tex-mode . ffap-tex-mode) + (latex-mode . ffap-latex-mode) + ("\\.\\(tex\\|sty\\|doc\\|cls\\)\\'" . ffap-tex) + ("\\.bib\\'" . ffap-bib) + ("\\`\\." . ffap-home) + ("\\`~/" . ffap-lcd) + ("^[Rr][Ff][Cc][- #]?\\([0-9]+\\)" ; no $ + . ffap-rfc) + ("\\`[^/]*\\'" . ffap-dired)) "Alist of \(KEY . FUNCTION\) pairs parsed by `ffap-file-at-point'. If string NAME at point (maybe \"\") is not a file or url, these pairs specify actions to try creating such a string. A pair matches if either @@ -741,7 +636,120 @@ On a match, \(FUNCTION NAME\) is called and should return a file, an url, or nil. If nil, search the alist for further matches.") (put 'ffap-alist 'risky-local-variable t) + +(defun ffap-home (name) (locate-library name t '("~"))) +(defun ffap-info (name) + (locate-library + name '("" ".info") + (or (ffap-soft-value "Info-directory-list") + (ffap-soft-value "Info-default-directory-list") + ;; v18: + (list (ffap-soft-value "Info-directory" "~/info/"))))) + +(defun ffap-info-2 (name) (ffap-info (substring name 5))) + +;; This ignores the node! "(emacs)Top" same as "(emacs)Intro" +(defun ffap-info-3 (name) + (and (equal (ffap-string-around) "()") (ffap-info name))) + +(defun ffap-el (name) (locate-library name t)) + +;; Need better defaults here! +(defvar ffap-c-path '("/usr/include" "/usr/local/include")) +(defun ffap-c-mode (name) + (locate-library name t ffap-c-path)) + +(defun ffap-el-mode (name) + ;; We do not bother with "" here, since it was considered above. + ;; Also ignore "elc", for speed (who else reads elc files?) + (and (not (string-match "\\.el\\'" name)) + (locate-library name '(".el")))) + +;; Complicated because auctex may not be loaded yet. +(defvar ffap-tex-path + t ; delayed initialization + "Path where `ffap-tex-mode' looks for tex files. +If t, `ffap-tex-init' will initialize this when needed.") + +(defun ffap-tex-init nil + ;; Compute ffap-tex-path if it is now t. + (and (eq t ffap-tex-path) + (message "Initializing ffap-tex-path ...") + (setq ffap-tex-path + (ffap-reduce-path + (append + (list ".") + (ffap-list-env "TEXINPUTS") + ;; (ffap-list-env "BIBINPUTS") + (ffap-add-subdirs + (ffap-list-env "TEXINPUTS_SUBDIR" + (ffap-soft-value + "TeX-macro-global" + '("/usr/local/lib/tex/macros" + "/usr/local/lib/tex/inputs") + )))))))) + +(defun ffap-tex-mode (name) + (ffap-tex-init) + (locate-library name '(".tex" "") ffap-tex-path)) + +(defun ffap-latex-mode (name) + (ffap-tex-init) + ;; Any real need for "" here? + (locate-library name '(".cls" ".sty" ".tex" "") + ffap-tex-path)) + +(defun ffap-tex (name) + (ffap-tex-init) + (locate-library name t ffap-tex-path)) + +(defun ffap-bib (name) + (locate-library + name t + (ffap-list-env "BIBINPUTS" '("/usr/local/lib/tex/macros/bib")))) + +(defun ffap-dired (name) + (let ((pt (point)) dir try) + (save-excursion + (and (progn + (beginning-of-line) + (looking-at " *[-d]r[-w][-x][-r][-w][-x][-r][-w][-x] ")) + (re-search-backward "^ *$" nil t) + (re-search-forward "^ *\\([^ \t\n:]*\\):\n *total " pt t) + (file-exists-p + (setq try + (expand-file-name + name + (buffer-substring + (match-beginning 1) (match-end 1))))) + try)))) + +;; Maybe a "Lisp Code Directory" reference: +(defun ffap-lcd (name) + (and + (or + ;; lisp-dir-apropos output buffer: + (string-match "Lisp Code Dir" (buffer-name)) + ;; Inside an LCD entry like |~/misc/ffap.el.Z|, + ;; or maybe the holy LCD-Datafile itself: + (member (ffap-string-around) '("||" "|\n"))) + (concat + ;; lispdir.el may not be loaded yet: + (ffap-host-to-path + (ffap-soft-value "elisp-archive-host" + "archive.cis.ohio-state.edu")) + (file-name-as-directory + (ffap-soft-value "elisp-archive-directory" + "/pub/gnu/emacs/elisp-archive/")) + (substring name 2)))) + +(defvar ffap-rfc-path + (concat (ffap-host-to-path "ds.internic.net") "/rfc/rfc%s.txt")) + +(defun ffap-rfc (name) + (format ffap-rfc-path + (substring name (match-beginning 1) (match-end 1)))) ;;; At-Point Functions: @@ -769,9 +777,6 @@ possibly a `major-mode' or some symbol internal to ffap 2. strip BEG chars before point from the beginning, 3. Strip END chars after point from the end.") -(defvar ffap-string-at-point-region '(1 1) - "List (BEG END), last region returned by `ffap-string-at-point'.") - (defvar ffap-string-at-point nil ;; Added at suggestion of RHOGEE (for ff-paths), 7/24/95. "Last string returned by `ffap-string-at-point'.")