Function: idlwave-do-context-help1
idlwave-do-context-help1 is a byte-compiled function defined in
idlw-help.el.gz.
Signature
(idlwave-do-context-help1 &optional ARG)
Documentation
The work-horse version of idlwave-context-help, which see.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/idlw-help.el.gz
(defun idlwave-do-context-help1 (&optional arg)
"The work-horse version of `idlwave-context-help', which see."
(save-excursion
(if (equal (char-after) ?/)
(forward-char 1)
(if (equal (char-before) ?=)
(backward-char 1)))
(let* ((idlwave-query-class nil)
(idlwave-force-class-query (equal arg '(4)))
(chars "a-zA-Z0-9_$.!")
(beg (save-excursion (skip-chars-backward chars) (point)))
(end (save-excursion (skip-chars-forward chars) (point)))
(this-word (buffer-substring-no-properties beg end))
(st-ass (assoc-string this-word
idlwave-help-special-topic-words t))
(classtag (and (string-match "self\\." this-word)
(< beg (- end 4))))
(structtag (and (fboundp 'idlwave-complete-structure-tag)
(string-match "\\`\\([^.]+\\)\\." this-word)
(< beg (- end 4))))
module keyword cw mod1 mod2 mod3)
(if (or arg
(and (not classtag)
(not structtag)
(not (member (string-to-char this-word) '(?! ?.)))))
;; Need the module information
(progn
;; MODULE is (name type class), for this or any inheriting class
(setq module (idlwave-what-module-find-class)
cw (nth 2 (idlwave-where))) ;what would we complete here?
;; Correct for OBJ_NEW, we may need an INIT method instead.
(if (equal (idlwave-downcase-safe (car module)) "obj_new")
(let* ((bos (save-excursion (idlwave-beginning-of-statement)
(point)))
(str (buffer-substring bos (point))))
(if (string-match "OBJ_NEW([ \t]*['\"]\\([a-zA-Z][a-zA-Z0-9$_]+\\)['\"]" str)
(setq module (list "init" 'fun (match-string 1 str))
idlwave-current-obj_new-class (match-string 1 str))
)))))
(cond
(arg (setq mod1 module))
;; A special topic -- only system help
((and st-ass (not (memq cw '(function-keyword procedure-keyword))))
(setq mod1 (list (cdr st-ass))))
;; A system variable -- only system help
((string-match
"\\`!\\([a-zA-Z0-9_]+\\)\\(\\.\\([A-Za-z0-9_]+\\)\\)?"
this-word)
(let* ((word (match-string-no-properties 1 this-word))
(entry (assq (idlwave-sintern-sysvar word)
idlwave-system-variables-alist))
(tag (match-string-no-properties 3 this-word))
(tag-target (if tag
(cdr
(assq (idlwave-sintern-sysvartag tag)
(cdr (assq 'tags entry))))))
(link (nth 1 (assq 'link entry))))
(if tag-target
(setq link (idlwave-substitute-link-target link
tag-target)))
(setq mod1 (list link))))
;; An executive command -- only system help
((string-match "^\\.\\([A-Z_]+\\)" this-word)
(let* ((word (match-string 1 this-word))
(link (cdr (assoc-string
word
idlwave-executive-commands-alist t))))
(setq mod1 (list link))))
;; A class -- system OR in-text help (via class__define).
((and (eq cw 'class)
(or (idlwave-in-quote) ; e.g. obj_new
(re-search-backward "\\<inherits[ \t]+[A-Za-z0-9_]*\\="
(max (point-min) (- (point) 40)) t)))
;; Class completion inside string delimiters must be
;; the class inside OBJ_NEW.
(let* ((entry (assq
(idlwave-sintern-class this-word)
idlwave-system-class-info))
(name (concat (downcase this-word) "__define"))
(link (nth 1 (assq 'link entry))))
(setq mod1 (list link name 'pro))))
;; A class structure tag (self.BLAH) -- only in-text help available
(classtag
(let ((tag (substring this-word (match-end 0)))
class-with found-in)
(when (setq class-with
(idlwave-class-or-superclass-with-tag
(nth 2 (idlwave-current-routine))
tag))
(setq found-in (idlwave-class-found-in class-with))
(if (assq (idlwave-sintern-class class-with)
idlwave-system-class-info)
(error "No help available for system class tags"))
(setq idlwave-help-do-class-struct-tag t)
(setq mod1 (list nil
(if found-in
(cons (concat found-in "__define") class-with)
(concat class-with "__define"))
'pro
nil ; no class.... it's a procedure!
tag)))))
;; A regular structure tag -- only in text, and if
;; optional `complete-structtag' loaded.
(structtag
(let ((var (match-string 1 this-word))
(tag (substring this-word (match-end 0))))
;; Check if we need to update the "current" structure
(idlwave-prepare-structure-tag-completion var)
(setq idlwave-help-do-struct-tag
idlwave-structtag-struct-location
mod1 (list nil nil nil nil tag))))
;; A routine keyword -- in text or system help
((and (memq cw '(function-keyword procedure-keyword))
(stringp this-word)
(string-match "\\S-" this-word)
(not (string-search "!" this-word)))
(cond ((or (= (char-before beg) ?/)
(save-excursion (goto-char end)
(looking-at "[ \t]*=")))
;; Certainly a keyword. Check for abbreviation etc.
(setq keyword (idlwave-expand-keyword this-word module))
(cond
((null keyword)
(idlwave-help-diagnostics
(format "%s does not accept `%s' kwd"
(idlwave-make-full-name (nth 2 module)
(car module))
(upcase this-word))
'ding))
((consp keyword)
(idlwave-help-diagnostics
(format "%d matches for kwd abbrev `%s'"
(length keyword) this-word)
'ding)
;; We continue anyway with the first match...
(setq keyword (car keyword))))
;; Keyword, or just module
(setq mod1 (append (list t) module (list keyword)))
(setq mod2 (append (list t) module)))
((equal (char-after end) ?\()
;; A function - what-module will have caught this
(setq mod1 (append (list t) module)))
(t
;; undecided - try function, keyword, then enclosing mod.
;; Check for keyword abbreviations, but do not report
;; errors, because it might be something else.
;; FIXME: is this a good way to handle this?
(setq keyword (idlwave-expand-keyword this-word module))
(if (consp keyword) (setq keyword (car keyword)))
(setq mod1 (append (list t) module (list keyword))
mod2 (list t this-word 'fun nil)
mod3 (append (list t) module)))))
;; Everything else
(t
(setq mod1 (append (list t) module))))
(if mod3
(condition-case nil
(apply #'idlwave-online-help mod1)
(error (condition-case nil
(apply #'idlwave-online-help mod2)
(error (apply #'idlwave-online-help mod3)))))
(if mod2
(condition-case nil
(apply #'idlwave-online-help mod1)
(error (apply #'idlwave-online-help mod2)))
(if mod1
(apply #'idlwave-online-help mod1)
(error "Don't know which item to show help for")))))))