comparison lisp/progmodes/idlw-help.el @ 69821:5baeec79c0cd

Update to IDLWAVE version 6.0; see idlwave.org.
author J.D. Smith <jdsmith@as.arizona.edu>
date Thu, 06 Apr 2006 18:46:56 +0000
parents dc49655f57ae
children 9b44ad1b998d
comparison
equal deleted inserted replaced
69820:a26627fd2df2 69821:5baeec79c0cd
1 ;;; idlw-help.el --- HTML Help code for IDLWAVE 1 ;;; idlw-help.el --- HTML Help code for IDLWAVE
2 ;; Copyright (c) 2000 Carsten Dominik 2 ;; Copyright (c) 2000 Carsten Dominik
3 ;; Copyright (c) 2001, 2002 J.D. Smith 3 ;; Copyright (c) 2001, 2002 J.D. Smith
4 ;; Copyright (c) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 4 ;; Copyright (c) 2003,2004,2005,2006 Free Software Foundation
5 ;; 5 ;;
6 ;; Authors: J.D. Smith <jdsmith@as.arizona.edu> 6 ;; Authors: J.D. Smith <jdsmith@as.arizona.edu>
7 ;; Carsten Dominik <dominik@science.uva.nl> 7 ;; Carsten Dominik <dominik@science.uva.nl>
8 ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu> 8 ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu>
9 ;; Version: 5.7_22 9 ;; Version: 6.0_em22
10 10
11 ;; This file is part of GNU Emacs. 11 ;; This file is part of GNU Emacs.
12 12
13 ;; This file is free software; you can redistribute it and/or modify 13 ;; This file is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by 14 ;; it under the terms of the GNU General Public License as published by
34 ;; themselves are not distributable with Emacs, but are available, 34 ;; themselves are not distributable with Emacs, but are available,
35 ;; along with new versions of IDLWAVE, documentation, and more 35 ;; along with new versions of IDLWAVE, documentation, and more
36 ;; information, at: 36 ;; information, at:
37 ;; 37 ;;
38 ;; http://idlwave.org 38 ;; http://idlwave.org
39 ;; 39 ;;
40 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 40 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
41 41
42 42
43 (require 'idlwave)
44
43 ;;; Code: 45 ;;; Code:
44 (defvar browse-url-generic-args)
45
46 (defvar idlwave-help-browse-url-available nil 46 (defvar idlwave-help-browse-url-available nil
47 "Whether browse-url is available") 47 "Whether browse-url is available")
48 48
49 (setq idlwave-help-browse-url-available 49 (setq idlwave-help-browse-url-available
50 (condition-case nil 50 (condition-case nil
58 (defcustom idlwave-html-help-pre-v6 nil 58 (defcustom idlwave-html-help-pre-v6 nil
59 "Whether pre or post-v6.0 IDL help documents are being used." 59 "Whether pre or post-v6.0 IDL help documents are being used."
60 :group 'idlwave-online-help 60 :group 'idlwave-online-help
61 :type 'boolean) 61 :type 'boolean)
62 62
63 (defvar idlwave-html-link-sep 63 (defvar idlwave-html-link-sep
64 (if idlwave-html-help-pre-v6 "#" "#wp")) 64 (if idlwave-html-help-pre-v6 "#" "#wp"))
65 65
66 (defcustom idlwave-html-help-location 66 (defcustom idlwave-html-system-help-location "help/online_help/"
67 (if (memq system-type '(ms-dos windows-nt)) 67 "The directory, relative to idlwave-system-directory, where the idl
68 HTML help files live, for IDL 6.2 and later. This location, if found,
69 is used in preference to the old idlwave-html-help-location."
70 :group 'idlwave-online-help
71 :type 'directory)
72
73 (defcustom idlwave-html-help-location
74 (if (memq system-type '(ms-dos windows-nt))
68 nil 75 nil
69 "/usr/local/etc/") 76 "/usr/local/etc/")
70 "The directory where the idl_html_help/ dir or idl.chm help file 77 "The directory where the idl_html_help/ dir lives. Obsolete for IDL
71 (Windows only) lives." 78 6.2 or later (see idlwave-html-system-help-location)."
72 :group 'idlwave-online-help 79 :group 'idlwave-online-help
73 :type 'directory) 80 :type 'directory)
74 81
75 (defcustom idlwave-help-use-hh nil 82 (defvar idlwave-help-use-hh nil
76 "Whether to use the HTMLHelp viewer with idl.chm (Windows only)." 83 "Obsolete variable.")
77 :group 'idlwave-online-help 84
78 :type '(choice :tag "use help viewer" 85 (defcustom idlwave-help-use-assistant t
79 (const :tag "<none>" nil) 86 "Whether to use the IDL Assistant as the help browser."
80 (const :tag "hh" 'hh) 87 :group 'idlwave-online-help
81 (const :tag "keyhh" 'keyhh))) 88 :type 'boolean)
82 89
83 (defcustom idlwave-help-browser-function browse-url-browser-function 90 (defcustom idlwave-help-browser-function browse-url-browser-function
84 "Function to use to display html help. 91 "Function to use to display html help.
85 Defaults to `browse-url-browser-function', which see." 92 Defaults to `browse-url-browser-function', which see."
86 :group 'idlwave-online-help 93 :group 'idlwave-online-help
89 (defcustom idlwave-help-browser-generic-program browse-url-generic-program 96 (defcustom idlwave-help-browser-generic-program browse-url-generic-program
90 "Program to run if using browse-url-generic-program." 97 "Program to run if using browse-url-generic-program."
91 :group 'idlwave-online-help 98 :group 'idlwave-online-help
92 :type 'string) 99 :type 'string)
93 100
94 (defcustom idlwave-help-browser-generic-args 101 (defvar browse-url-generic-args)
102
103 (defcustom idlwave-help-browser-generic-args
95 (if (boundp 'browse-url-generic-args) 104 (if (boundp 'browse-url-generic-args)
96 browse-url-generic-args "") 105 browse-url-generic-args "")
97 "Program args to use if using browse-url-generic-program." 106 "Program args to use if using browse-url-generic-program."
98 :group 'idlwave-online-help 107 :group 'idlwave-online-help
99 :type 'string) 108 :type 'string)
196 "Face for highlighting links into IDLWAVE online help." 205 "Face for highlighting links into IDLWAVE online help."
197 :group 'idlwave-online-help) 206 :group 'idlwave-online-help)
198 207
199 (defvar idlwave-help-activate-links-aggressively nil 208 (defvar idlwave-help-activate-links-aggressively nil
200 "Obsolete variable.") 209 "Obsolete variable.")
201 210
202 (defvar idlwave-completion-help-info) 211 (defvar idlwave-completion-help-info)
203 212
204 (defvar idlwave-help-frame nil 213 (defvar idlwave-help-frame nil
205 "The frame for display of IDL online help.") 214 "The frame for display of IDL online help.")
206 (defvar idlwave-help-frame-width 102 215 (defvar idlwave-help-frame-width 102
287 " -%-")) 296 " -%-"))
288 (setq buffer-read-only t) 297 (setq buffer-read-only t)
289 (set (make-local-variable 'idlwave-help-def-pos) nil) 298 (set (make-local-variable 'idlwave-help-def-pos) nil)
290 (set (make-local-variable 'idlwave-help-args) nil) 299 (set (make-local-variable 'idlwave-help-args) nil)
291 (set (make-local-variable 'idlwave-help-in-header) nil) 300 (set (make-local-variable 'idlwave-help-in-header) nil)
292 (run-mode-hooks 'idlwave-help-mode-hook)) 301 (run-hooks 'idlwave-help-mode-hook))
293 302
294 (defvar idlwave-system-directory)
295 (defun idlwave-html-help-location () 303 (defun idlwave-html-help-location ()
296 "Return the help directory where HTML files are, or nil if that is unknown." 304 "Return the help directory where HTML files are, or nil if that is unknown."
297 (or (and (stringp idlwave-html-help-location) 305 (let ((syshelp-dir (expand-file-name
298 (> (length idlwave-html-help-location) 0) 306 idlwave-html-system-help-location (idlwave-sys-dir)))
299 (file-directory-p idlwave-html-help-location) 307 (help-dir (or (and (stringp idlwave-html-help-location)
300 idlwave-html-help-location) 308 (> (length idlwave-html-help-location) 0)
301 (getenv "IDLWAVE_HELP_LOCATION") 309 idlwave-html-help-location)
302 (and (memq system-type '(ms-dos windows-nt)) ; Base it on sysdir 310 (getenv "IDLWAVE_HELP_LOCATION"))))
303 idlwave-help-use-hh 311 (if (file-directory-p syshelp-dir)
304 (stringp idlwave-system-directory) 312 syshelp-dir
305 (> (length idlwave-system-directory) 0) 313 (setq help-dir (expand-file-name "idl_html_help" help-dir))
306 (file-directory-p idlwave-system-directory) 314 (if (file-directory-p help-dir) help-dir))))
307 (expand-file-name "HELP" idlwave-system-directory)))) 315
316 (defvar idlwave-help-assistant-available nil)
317
318 (defun idlwave-help-check-locations ()
319 ;; Check help locations and assistant.
320 (let ((sys-dir (idlwave-sys-dir))
321 (help-loc (idlwave-html-help-location)))
322 (if (or (not (file-directory-p sys-dir))
323 (not (file-directory-p help-loc)))
324 (message
325 "HTML help location not found: try setting `idlwave-system-directory' and/or `idlwave-html-help-location'."))
326 ;; see if we have the assistant
327 (when (and idlwave-help-use-assistant
328 (not (eq (idlwave-help-assistant-available) t)))
329 (message "Cannot locate IDL Assistant, enabling default browser.")
330 (setq idlwave-help-use-assistant nil)
331 (unless idlwave-help-browse-url-available
332 (error "browse-url is not available; install it or IDL Assistant to use HTML help.")))))
333
308 334
309 (defvar idlwave-current-obj_new-class) 335 (defvar idlwave-current-obj_new-class)
310 (defvar idlwave-help-diagnostics) 336 (defvar idlwave-help-diagnostics)
311 (defvar idlwave-experimental) 337 (defvar idlwave-experimental)
312 (defvar idlwave-last-context-help-pos) 338 (defvar idlwave-last-context-help-pos)
324 (idlwave-help-select-help-frame) 350 (idlwave-help-select-help-frame)
325 ;; Do the real thing. 351 ;; Do the real thing.
326 (setq idlwave-last-context-help-pos marker) 352 (setq idlwave-last-context-help-pos marker)
327 (idlwave-do-context-help1 arg) 353 (idlwave-do-context-help1 arg)
328 (if idlwave-help-diagnostics 354 (if idlwave-help-diagnostics
329 (message "%s" (mapconcat 'identity 355 (message "%s" (mapconcat 'identity
330 (nreverse idlwave-help-diagnostics) 356 (nreverse idlwave-help-diagnostics)
331 "; ")))))) 357 "; "))))))
332 358
333 (defvar idlwave-help-do-class-struct-tag nil) 359 (defvar idlwave-help-do-class-struct-tag nil)
334 (defvar idlwave-structtag-struct-location) 360 (defvar idlwave-structtag-struct-location)
337 (defvar idlwave-executive-commands-alist) 363 (defvar idlwave-executive-commands-alist)
338 (defvar idlwave-system-class-info) 364 (defvar idlwave-system-class-info)
339 (defun idlwave-do-context-help1 (&optional arg) 365 (defun idlwave-do-context-help1 (&optional arg)
340 "The work-horse version of `idlwave-context-help', which see." 366 "The work-horse version of `idlwave-context-help', which see."
341 (save-excursion 367 (save-excursion
342 (if (equal (char-after) ?/) 368 (if (equal (char-after) ?/)
343 (forward-char 1) 369 (forward-char 1)
344 (if (equal (char-before) ?=) 370 (if (equal (char-before) ?=)
345 (backward-char 1))) 371 (backward-char 1)))
346 (let* ((idlwave-query-class nil) 372 (let* ((idlwave-query-class nil)
347 (idlwave-force-class-query (equal arg '(4))) 373 (idlwave-force-class-query (equal arg '(4)))
348 (chars "a-zA-Z0-9_$.!") 374 (chars "a-zA-Z0-9_$.!")
349 (beg (save-excursion (skip-chars-backward chars) (point))) 375 (beg (save-excursion (skip-chars-backward chars) (point)))
350 (end (save-excursion (skip-chars-forward chars) (point))) 376 (end (save-excursion (skip-chars-forward chars) (point)))
351 (this-word (buffer-substring-no-properties beg end)) 377 (this-word (buffer-substring-no-properties beg end))
352 (st-ass (assoc (downcase this-word) 378 (st-ass (assoc-string this-word
353 idlwave-help-special-topic-words)) 379 idlwave-help-special-topic-words t))
354 (classtag (and (string-match "self\\." this-word) 380 (classtag (and (string-match "self\\." this-word)
355 (< beg (- end 4)))) 381 (< beg (- end 4))))
356 (structtag (and (fboundp 'idlwave-complete-structure-tag) 382 (structtag (and (fboundp 'idlwave-complete-structure-tag)
357 (string-match "\\`\\([^.]+\\)\\." this-word) 383 (string-match "\\`\\([^.]+\\)\\." this-word)
358 (< beg (- end 4)))) 384 (< beg (- end 4))))
359 module keyword cw mod1 mod2 mod3) 385 module keyword cw mod1 mod2 mod3)
360 (if (or arg 386 (if (or arg
361 (and (not st-ass) 387 (and (not st-ass)
362 (not classtag) 388 (not classtag)
363 (not structtag) 389 (not structtag)
364 (not (member (string-to-char this-word) '(?! ?.))))) 390 (not (member (string-to-char this-word) '(?! ?.)))))
365 ;; Need the module information 391 ;; Need the module information
374 (str (buffer-substring bos (point)))) 400 (str (buffer-substring bos (point))))
375 (if (string-match "OBJ_NEW([ \t]*['\"]\\([a-zA-Z][a-zA-Z0-9$_]+\\)['\"]" str) 401 (if (string-match "OBJ_NEW([ \t]*['\"]\\([a-zA-Z][a-zA-Z0-9$_]+\\)['\"]" str)
376 (setq module (list "init" 'fun (match-string 1 str)) 402 (setq module (list "init" 'fun (match-string 1 str))
377 idlwave-current-obj_new-class (match-string 1 str)) 403 idlwave-current-obj_new-class (match-string 1 str))
378 ))))) 404 )))))
379 (cond 405 (cond
380 (arg (setq mod1 module)) 406 (arg (setq mod1 module))
381 407
382 ;; A special topic -- only system help 408 ;; A special topic -- only system help
383 (st-ass (setq mod1 (list (cdr st-ass)))) 409 (st-ass (setq mod1 (list (cdr st-ass))))
384 410
385 ;; A system variable -- only system help 411 ;; A system variable -- only system help
386 ((string-match 412 ((string-match
387 "\\`!\\([a-zA-Z0-9_]+\\)\\(\.\\([A-Za-z0-9_]+\\)\\)?" 413 "\\`!\\([a-zA-Z0-9_]+\\)\\(\.\\([A-Za-z0-9_]+\\)\\)?"
388 this-word) 414 this-word)
389 (let* ((word (match-string-no-properties 1 this-word)) 415 (let* ((word (match-string-no-properties 1 this-word))
390 (entry (assq (idlwave-sintern-sysvar word) 416 (entry (assq (idlwave-sintern-sysvar word)
391 idlwave-system-variables-alist)) 417 idlwave-system-variables-alist))
392 (tag (match-string-no-properties 3 this-word)) 418 (tag (match-string-no-properties 3 this-word))
394 (cdr 420 (cdr
395 (assq (idlwave-sintern-sysvartag tag) 421 (assq (idlwave-sintern-sysvartag tag)
396 (cdr (assq 'tags entry)))))) 422 (cdr (assq 'tags entry))))))
397 (link (nth 1 (assq 'link entry)))) 423 (link (nth 1 (assq 'link entry))))
398 (if tag-target 424 (if tag-target
399 (setq link (idlwave-substitute-link-target link 425 (setq link (idlwave-substitute-link-target link
400 tag-target))) 426 tag-target)))
401 (setq mod1 (list link)))) 427 (setq mod1 (list link))))
402 428
403 ;; An executive command -- only system help 429 ;; An executive command -- only system help
404 ((string-match "^\\.\\([A-Z_]+\\)" this-word) 430 ((string-match "^\\.\\([A-Z_]+\\)" this-word)
405 (let* ((word (match-string 1 this-word)) 431 (let* ((word (match-string 1 this-word))
406 (link (cdr (assoc-string 432 (link (cdr (assoc-string
407 word 433 word
408 idlwave-executive-commands-alist t)))) 434 idlwave-executive-commands-alist t))))
409 (setq mod1 (list link)))) 435 (setq mod1 (list link))))
410 436
411 ;; A class -- system OR in-text help (via class__define). 437 ;; A class -- system OR in-text help (via class__define).
412 ((and (eq cw 'class) 438 ((and (eq cw 'class)
413 (or (idlwave-in-quote) ; e.g. obj_new 439 (or (idlwave-in-quote) ; e.g. obj_new
414 (re-search-backward "\\<inherits[ \t]+[A-Za-z0-9_]*\\=" 440 (re-search-backward "\\<inherits[ \t]+[A-Za-z0-9_]*\\="
415 (max (point-min) (- (point) 40)) t))) 441 (max (point-min) (- (point) 40)) t)))
419 (idlwave-sintern-class this-word) 445 (idlwave-sintern-class this-word)
420 idlwave-system-class-info)) 446 idlwave-system-class-info))
421 (name (concat (downcase this-word) "__define")) 447 (name (concat (downcase this-word) "__define"))
422 (link (nth 1 (assq 'link entry)))) 448 (link (nth 1 (assq 'link entry))))
423 (setq mod1 (list link name 'pro)))) 449 (setq mod1 (list link name 'pro))))
424 450
425 ;; A class structure tag (self.BLAH) -- only in-text help available 451 ;; A class structure tag (self.BLAH) -- only in-text help available
426 (classtag 452 (classtag
427 (let ((tag (substring this-word (match-end 0))) 453 (let ((tag (substring this-word (match-end 0)))
428 class-with found-in) 454 class-with found-in)
429 (when (setq class-with 455 (when (setq class-with
430 (idlwave-class-or-superclass-with-tag 456 (idlwave-class-or-superclass-with-tag
431 (nth 2 (idlwave-current-routine)) 457 (nth 2 (idlwave-current-routine))
432 tag)) 458 tag))
433 (setq found-in (idlwave-class-found-in class-with)) 459 (setq found-in (idlwave-class-found-in class-with))
434 (if (assq (idlwave-sintern-class class-with) 460 (if (assq (idlwave-sintern-class class-with)
435 idlwave-system-class-info) 461 idlwave-system-class-info)
436 (error "No help available for system class tags")) 462 (error "No help available for system class tags"))
437 (setq idlwave-help-do-class-struct-tag t) 463 (setq idlwave-help-do-class-struct-tag t)
438 (setq mod1 (list nil 464 (setq mod1 (list nil
439 (if found-in 465 (if found-in
440 (cons (concat found-in "__define") class-with) 466 (cons (concat found-in "__define") class-with)
441 (concat class-with "__define")) 467 (concat class-with "__define"))
442 'pro 468 'pro
443 nil ; no class.... it's a procedure! 469 nil ; no class.... it's a procedure!
444 tag))))) 470 tag)))))
445 471
446 ;; A regular structure tag -- only in text, and if 472 ;; A regular structure tag -- only in text, and if
447 ;; optional `complete-structtag' loaded. 473 ;; optional `complete-structtag' loaded.
448 (structtag 474 (structtag
449 (let ((var (match-string 1 this-word)) 475 (let ((var (match-string 1 this-word))
450 (tag (substring this-word (match-end 0)))) 476 (tag (substring this-word (match-end 0))))
451 ;; Check if we need to update the "current" structure 477 ;; Check if we need to update the "current" structure
452 (idlwave-prepare-structure-tag-completion var) 478 (idlwave-prepare-structure-tag-completion var)
453 (setq idlwave-help-do-struct-tag 479 (setq idlwave-help-do-struct-tag
454 idlwave-structtag-struct-location 480 idlwave-structtag-struct-location
455 mod1 (list nil nil nil nil tag)))) 481 mod1 (list nil nil nil nil tag))))
456 482
457 ;; A routine keyword -- in text or system help 483 ;; A routine keyword -- in text or system help
458 ((and (memq cw '(function-keyword procedure-keyword)) 484 ((and (memq cw '(function-keyword procedure-keyword))
459 (stringp this-word) 485 (stringp this-word)
460 (string-match "\\S-" this-word) 486 (string-match "\\S-" this-word)
461 (not (string-match "!" this-word))) 487 (not (string-match "!" this-word)))
493 (setq keyword (idlwave-expand-keyword this-word module)) 519 (setq keyword (idlwave-expand-keyword this-word module))
494 (if (consp keyword) (setq keyword (car keyword))) 520 (if (consp keyword) (setq keyword (car keyword)))
495 (setq mod1 (append (list t) module (list keyword)) 521 (setq mod1 (append (list t) module (list keyword))
496 mod2 (list t this-word 'fun nil) 522 mod2 (list t this-word 'fun nil)
497 mod3 (append (list t) module))))) 523 mod3 (append (list t) module)))))
498 524
499 ;; Everything else 525 ;; Everything else
500 (t 526 (t
501 (setq mod1 (append (list t) module)))) 527 (setq mod1 (append (list t) module))))
502 (if mod3 528 (if mod3
503 (condition-case nil 529 (condition-case nil
526 (kwd (nth 4 info)) 552 (kwd (nth 4 info))
527 (sclasses (nth 5 info)) 553 (sclasses (nth 5 info))
528 word link) 554 word link)
529 (mouse-set-point ev) 555 (mouse-set-point ev)
530 556
531 557
532 ;; See if we can also find help somewhere, e.g. for multiple classes 558 ;; See if we can also find help somewhere, e.g. for multiple classes
533 (setq word (idlwave-this-word)) 559 (setq word (idlwave-this-word))
534 (if (string= word "") 560 (if (string= word "")
535 (error "No help item selected")) 561 (error "No help item selected"))
536 (setq link (get-text-property 0 'link word)) 562 (setq link (get-text-property 0 'link word))
537 (select-window cw) 563 (select-window cw)
538 (cond 564 (cond
539 ;; Routine name 565 ;; Routine name
540 ((memq what '(procedure function routine)) 566 ((memq what '(procedure function routine))
541 (setq name word) 567 (setq name word)
542 (if (or (eq class t) 568 (if (or (eq class t)
543 (and (stringp class) sclasses)) 569 (and (stringp class) sclasses))
544 (let* ((classes (idlwave-all-method-classes 570 (let* ((classes (idlwave-all-method-classes
545 (idlwave-sintern-method name) 571 (idlwave-sintern-method name)
546 type))) 572 type)))
547 (setq link t) ; No specific link valid yet 573 (setq link t) ; No specific link valid yet
548 (if sclasses 574 (if sclasses
549 (setq classes (idlwave-members-only 575 (setq classes (idlwave-members-only
550 classes (cons class sclasses)))) 576 classes (cons class sclasses))))
551 (setq class (idlwave-popup-select ev classes 577 (setq class (idlwave-popup-select ev classes
552 "Select Class" 'sort)))) 578 "Select Class" 'sort))))
553 579
554 ;; XXX is this necessary, given all-method-classes? 580 ;; XXX is this necessary, given all-method-classes?
555 (if (stringp class) 581 (if (stringp class)
556 (setq class (idlwave-find-inherited-class 582 (setq class (idlwave-find-inherited-class
566 (idlwave-sintern-method name) 592 (idlwave-sintern-method name)
567 (idlwave-sintern-keyword kwd) 593 (idlwave-sintern-keyword kwd)
568 type))) 594 type)))
569 (setq link t) ; Link can't be correct yet 595 (setq link t) ; Link can't be correct yet
570 (if sclasses 596 (if sclasses
571 (setq classes (idlwave-members-only 597 (setq classes (idlwave-members-only
572 classes (cons class sclasses)))) 598 classes (cons class sclasses))))
573 (setq class (idlwave-popup-select ev classes 599 (setq class (idlwave-popup-select ev classes
574 "Select Class" 'sort)) 600 "Select Class" 'sort))
575 ;; XXX is this necessary, given all-method-keyword-classes? 601 ;; XXX is this necessary, given all-method-keyword-classes?
576 (if (stringp class) 602 (if (stringp class)
578 (idlwave-sintern-routine-or-method name class) 604 (idlwave-sintern-routine-or-method name class)
579 type (idlwave-sintern-class class))))) 605 type (idlwave-sintern-class class)))))
580 (if (string= (downcase name) "obj_new") 606 (if (string= (downcase name) "obj_new")
581 (setq class idlwave-current-obj_new-class 607 (setq class idlwave-current-obj_new-class
582 name "Init")))) 608 name "Init"))))
583 609
584 ;; Class name 610 ;; Class name
585 ((eq what 'class) 611 ((eq what 'class)
586 (setq class word 612 (setq class word
587 word nil)) 613 word nil))
588 614
589 ;; A special named function to call which sets some of our variables 615 ;; A special named function to call which sets some of our variables
590 ((and (symbolp what) 616 ((and (symbolp what)
591 (fboundp what)) 617 (fboundp what))
592 (funcall what 'set word)) 618 (funcall what 'set word))
593 619
594 (t (error "Cannot help with this item"))) 620 (t (error "Cannot help with this item")))
595 (if (and need-class (not class) (not (and link (not (eq link t))))) 621 (if (and need-class (not class) (not (and link (not (eq link t)))))
600 (defvar idlwave-completion-help-links) 626 (defvar idlwave-completion-help-links)
601 (defun idlwave-highlight-linked-completions () 627 (defun idlwave-highlight-linked-completions ()
602 "Highlight all completions for which help is available and attach link. 628 "Highlight all completions for which help is available and attach link.
603 Those words in `idlwave-completion-help-links' have links. The 629 Those words in `idlwave-completion-help-links' have links. The
604 `idlwave-help-link' face is used for this." 630 `idlwave-help-link' face is used for this."
605 (if idlwave-highlight-help-links-in-completion 631 (if idlwave-highlight-help-links-in-completion
606 (with-current-buffer (get-buffer "*Completions*") 632 (with-current-buffer (get-buffer "*Completions*")
607 (save-excursion 633 (save-excursion
608 (let* ((case-fold-search t) 634 (let* ((case-fold-search t)
609 (props (list 'face 'idlwave-help-link)) 635 (props (list 'face 'idlwave-help-link))
610 (info idlwave-completion-help-info) ; global passed in 636 (info idlwave-completion-help-info) ; global passed in
616 (while (re-search-forward "\\s-\\([A-Za-z0-9_.]+\\)\\(\\s-\\|\\'\\)" 642 (while (re-search-forward "\\s-\\([A-Za-z0-9_.]+\\)\\(\\s-\\|\\'\\)"
617 nil t) 643 nil t)
618 (setq beg (match-beginning 1) end (match-end 1) 644 (setq beg (match-beginning 1) end (match-end 1)
619 word (match-string 1) doit nil) 645 word (match-string 1) doit nil)
620 ;; Call special completion function test 646 ;; Call special completion function test
621 (if (and (symbolp what) 647 (if (and (symbolp what)
622 (fboundp what)) 648 (fboundp what))
623 (setq doit (funcall what 'test word)) 649 (setq doit (funcall what 'test word))
624 ;; Look for special link property passed in help-links 650 ;; Look for special link property passed in help-links
625 (if idlwave-completion-help-links 651 (if idlwave-completion-help-links
626 (setq doit (assoc-string 652 (setq doit (assoc-string
647 (if (and idlwave-experimental 673 (if (and idlwave-experimental
648 (frame-live-p idlwave-help-return-frame)) 674 (frame-live-p idlwave-help-return-frame))
649 ;; Try to select the return frame. 675 ;; Try to select the return frame.
650 ;; This can crash on slow network connections, obviously when 676 ;; This can crash on slow network connections, obviously when
651 ;; we kill the help frame before the return-frame is selected. 677 ;; we kill the help frame before the return-frame is selected.
652 ;; To protect the workings, we wait for up to one second 678 ;; To protect the workings, we wait for up to one second
653 ;; and check if the return-frame *is* now selected. 679 ;; and check if the return-frame *is* now selected.
654 ;; This is marked "eperimental" since we are not sure when its OK. 680 ;; This is marked "eperimental" since we are not sure when its OK.
655 (let ((maxtime 1.0) (time 0.) (step 0.1)) 681 (let ((maxtime 1.0) (time 0.) (step 0.1))
656 (select-frame idlwave-help-return-frame) 682 (select-frame idlwave-help-return-frame)
657 (while (and (sit-for step) 683 (while (and (sit-for step)
658 (not (eq (selected-frame) 684 (not (eq (selected-frame)
659 idlwave-help-return-frame)) 685 idlwave-help-return-frame))
660 (< (setq time (+ time step)) maxtime))))) 686 (< (setq time (+ time step)) maxtime)))))
661 (delete-frame idlwave-help-frame)) 687 (delete-frame idlwave-help-frame))
662 ((window-configuration-p idlwave-help-window-configuration) 688 ((window-configuration-p idlwave-help-window-configuration)
663 (set-window-configuration idlwave-help-window-configuration) 689 (set-window-configuration idlwave-help-window-configuration)
666 692
667 693
668 (defvar default-toolbar-visible-p) 694 (defvar default-toolbar-visible-p)
669 695
670 (defun idlwave-help-display-help-window (&optional pos-or-func) 696 (defun idlwave-help-display-help-window (&optional pos-or-func)
671 "Display the help window. 697 "Display the help window.
672 Move window start to POS-OR-FUNC, if passed as a position, or call it 698 Move window start to POS-OR-FUNC, if passed as a position, or call it
673 if passed as a function. See `idlwave-help-use-dedicated-frame'." 699 if passed as a function. See `idlwave-help-use-dedicated-frame'."
674 (let ((cw (selected-window)) 700 (let ((cw (selected-window))
675 (buf (idlwave-help-get-help-buffer))) 701 (buf (idlwave-help-get-help-buffer)))
676 (if (and window-system idlwave-help-use-dedicated-frame) 702 (if (and window-system idlwave-help-use-dedicated-frame)
677 (progn 703 (progn
678 (idlwave-help-show-help-frame) 704 (idlwave-help-show-help-frame)
679 (switch-to-buffer buf)) 705 (switch-to-buffer buf))
680 ;; Do it in this frame and save the window configuration 706 ;; Do it in this frame and save the window configuration
681 (if (not (get-buffer-window buf nil)) 707 (if (not (get-buffer-window buf nil))
682 (setq idlwave-help-window-configuration 708 (setq idlwave-help-window-configuration
683 (current-window-configuration))) 709 (current-window-configuration)))
684 (display-buffer buf nil (selected-frame)) 710 (display-buffer buf nil (selected-frame))
685 (select-window (get-buffer-window buf))) 711 (select-window (get-buffer-window buf)))
686 (raise-frame) 712 (raise-frame)
687 (if pos-or-func 713 (if pos-or-func
688 (if (functionp pos-or-func) 714 (if (functionp pos-or-func)
689 (funcall pos-or-func) 715 (funcall pos-or-func)
690 (goto-char pos-or-func) 716 (goto-char pos-or-func)
691 (recenter 0))) 717 (recenter 0)))
692 (select-window cw))) 718 (select-window cw)))
693 719
705 (if (and (frame-live-p idlwave-help-return-frame) 731 (if (and (frame-live-p idlwave-help-return-frame)
706 (not (eq (selected-frame) idlwave-help-return-frame))) 732 (not (eq (selected-frame) idlwave-help-return-frame)))
707 (select-frame idlwave-help-return-frame))) 733 (select-frame idlwave-help-return-frame)))
708 734
709 (defun idlwave-online-help (link &optional name type class keyword) 735 (defun idlwave-online-help (link &optional name type class keyword)
710 "Display HTML or other special help on a certain topic. 736 "Display HTML or other special help on a certain topic.
711 Either loads an HTML link, if LINK is non-nil, or gets special-help on 737 Either loads an HTML link, if LINK is non-nil, or gets special-help on
712 the optional arguments, if any special help is defined. If LINK is 738 the optional arguments, if any special help is defined. If LINK is
713 `t', first look up the optional arguments in the routine info list to 739 `t', first look up the optional arguments in the routine info list to
714 see if a link is set for it. Try extra help functions if necessary." 740 see if a link is set for it. Try extra help functions if necessary."
715 ;; Lookup link 741 ;; Lookup link
716 (if (eq link t) 742 (if (eq link t)
717 (let ((entry (idlwave-best-rinfo-assoc name type class 743 (let ((entry (idlwave-best-rinfo-assoc name type class
718 (idlwave-routines) nil t))) 744 (idlwave-routines) nil t)))
719 (cond 745 (if entry
720 ;; Try keyword link 746 (cond
721 ((and keyword 747 ;; Try keyword link
722 (setq link (cdr (idlwave-entry-find-keyword entry keyword))))) 748 ((and keyword
723 ;; Default, regular entry link 749 (setq link (cdr
724 (t (setq link (idlwave-entry-has-help entry)))))) 750 (idlwave-entry-find-keyword entry keyword)))))
751 ;; Default, regular entry link
752 (t (setq link (idlwave-entry-has-help entry))))
753 (if (and
754 class
755 ;; Check for system class help
756 (setq entry (assq (idlwave-sintern-class class)
757 idlwave-system-class-info)
758 link (nth 1 (assq 'link entry))))
759 (message
760 (concat "No routine info for %s"
761 ", falling back on class help.")
762 (idlwave-make-full-name class name))))))
725 763
726 (cond 764 (cond
727 ;; An explicit link 765 ;; An explicit link
728 ((stringp link) 766 ((stringp link)
729 (idlwave-help-html-link link)) 767 (idlwave-help-html-link link))
730 768
731 ;; Any extra help 769 ;; Any extra help
732 (idlwave-extra-help-function 770 (idlwave-extra-help-function
733 (idlwave-help-get-special-help name type class keyword)) 771 (idlwave-help-get-special-help name type class keyword))
734 772
735 ;; Nothing worked 773 ;; Nothing worked
736 (t (idlwave-help-error name type class keyword)))) 774 (t (idlwave-help-error name type class keyword))))
737 775
738 776
739 (defun idlwave-help-get-special-help (name type class keyword) 777 (defun idlwave-help-get-special-help (name type class keyword)
740 "Call the function given by `idlwave-extra-help-function'." 778 "Call the function given by `idlwave-extra-help-function'."
741 (let* ((cw (selected-window)) 779 (let* ((cw (selected-window))
742 (help-pos (save-excursion 780 (help-pos (save-excursion
743 (set-buffer (idlwave-help-get-help-buffer)) 781 (set-buffer (idlwave-help-get-help-buffer))
744 (let ((buffer-read-only nil)) 782 (let ((buffer-read-only nil))
745 (funcall idlwave-extra-help-function 783 (funcall idlwave-extra-help-function
746 name type class keyword))))) 784 name type class keyword)))))
747 (if help-pos 785 (if help-pos
748 (idlwave-help-display-help-window help-pos) 786 (idlwave-help-display-help-window help-pos)
749 (idlwave-help-error name type class keyword)) 787 (idlwave-help-error name type class keyword))
750 (select-window cw))) 788 (select-window cw)))
755 (help-loc (idlwave-html-help-location)) 793 (help-loc (idlwave-html-help-location))
756 (browse-url-generic-program idlwave-help-browser-generic-program) 794 (browse-url-generic-program idlwave-help-browser-generic-program)
757 ;(browse-url-generic-args idlwave-help-browser-generic-args) 795 ;(browse-url-generic-args idlwave-help-browser-generic-args)
758 full-link) 796 full-link)
759 797
760 (unless idlwave-help-browse-url-available 798 ;; Just a regular file name (+ anchor name)
761 (error "browse-url is not available -- install it to use HTML help.")) 799 (unless (and (stringp help-loc)
762 800 (file-directory-p help-loc))
763 (if (and (memq system-type '(ms-dos windows-nt)) 801 (error "Invalid help location."))
764 idlwave-help-use-hh) 802 (setq full-link (browse-url-file-url (expand-file-name link help-loc)))
765 (progn 803
766 (setq browse-url-browser-function 'browse-url-generic 804 ;; Select the browser
767 full-link (concat (expand-file-name "idl.chm" help-loc) 805 (cond
768 "::/" 806 (idlwave-help-use-assistant
769 link)) 807 (idlwave-help-assistant-open-link link))
770 (if (memq 'keyhh idlwave-help-use-hh) 808
771 (setq browse-url-generic-program "KEYHH" 809 ((or idlwave-help-browser-is-local
772 browse-url-generic-args '("-IDLWAVE")) 810 (string-match "w3" (symbol-name idlwave-help-browser-function)))
773 (setq browse-url-generic-program "HH"))) 811 (idlwave-help-display-help-window '(lambda () (browse-url full-link))))
774 ;; Just a regular file name (+ anchor name) 812
775 (unless (and (stringp help-loc) 813 (t (browse-url full-link)))))
776 (file-directory-p help-loc))
777 (error
778 "Invalid help location; customize `idlwave-html-help-location'."))
779 (setq full-link (concat
780 "file://"
781 (expand-file-name
782 link
783 (expand-file-name "idl_html_help" help-loc)))))
784
785 ;; Check for a local browser
786 (if (or idlwave-help-browser-is-local
787 (string-match "w3" (symbol-name idlwave-help-browser-function)))
788 (idlwave-help-display-help-window '(lambda () (browse-url full-link)))
789 (browse-url full-link))))
790 814
791 ;; A special help routine for source-level syntax help in files. 815 ;; A special help routine for source-level syntax help in files.
792 (defvar idlwave-help-fontify-source-code) 816 (defvar idlwave-help-fontify-source-code)
793 (defvar idlwave-help-source-try-header) 817 (defvar idlwave-help-source-try-header)
794 (defvar idlwave-current-tags-buffer) 818 (defvar idlwave-current-tags-buffer)
812 (class-only (and (stringp class) (not (stringp name)))) 836 (class-only (and (stringp class) (not (stringp name))))
813 file header-pos def-pos in-buf) 837 file header-pos def-pos in-buf)
814 (if class-only ;Help with class? Using "Init" as source. 838 (if class-only ;Help with class? Using "Init" as source.
815 (setq name "Init" 839 (setq name "Init"
816 type 'fun)) 840 type 'fun))
817 (if (not struct-tag) 841 (if (not struct-tag)
818 (setq file 842 (setq file
819 (idlwave-routine-source-file 843 (idlwave-routine-source-file
820 (nth 3 (idlwave-best-rinfo-assoc 844 (nth 3 (idlwave-best-rinfo-assoc
821 name (or type t) class (idlwave-routines)))))) 845 name (or type t) class (idlwave-routines))))))
822 (setq idlwave-help-def-pos nil 846 (setq idlwave-help-def-pos nil
825 idlwave-help-do-struct-tag nil 849 idlwave-help-do-struct-tag nil
826 idlwave-help-do-class-struct-tag nil) 850 idlwave-help-do-class-struct-tag nil)
827 (if (or struct-tag (stringp file)) 851 (if (or struct-tag (stringp file))
828 (progn 852 (progn
829 (setq in-buf ; structure-tag completion is always in current buffer 853 (setq in-buf ; structure-tag completion is always in current buffer
830 (if struct-tag 854 (if struct-tag
831 idlwave-current-tags-buffer 855 idlwave-current-tags-buffer
832 (idlwave-get-buffer-visiting file))) 856 (idlwave-get-buffer-visiting file)))
833 ;; see if file is in a visited buffer, insert those contents 857 ;; see if file is in a visited buffer, insert those contents
834 (if in-buf 858 (if in-buf
835 (progn 859 (progn
836 (setq file (buffer-file-name in-buf)) 860 (setq file (buffer-file-name in-buf))
837 (erase-buffer) 861 (erase-buffer)
838 (insert-buffer-substring in-buf) 862 (insert-buffer-substring in-buf))
839 (goto-char (point-min)))
840 (if (file-exists-p file) ;; otherwise just load the file 863 (if (file-exists-p file) ;; otherwise just load the file
841 (progn 864 (progn
842 (erase-buffer) 865 (erase-buffer)
843 (insert-file-contents file nil nil nil 'replace)) 866 (insert-file-contents file nil nil nil 'replace))
844 (idlwave-help-error name type class keyword))) 867 (idlwave-help-error name type class keyword)))
848 (setq idlwave-help-mode-line-indicator file) 871 (setq idlwave-help-mode-line-indicator file)
849 872
850 ;; Try to find a good place to display 873 ;; Try to find a good place to display
851 (setq def-pos 874 (setq def-pos
852 ;; Find the class structure tag if that's what we're after 875 ;; Find the class structure tag if that's what we're after
853 (cond 876 (cond
854 ;; Class structure tags: find the class or named structure 877 ;; Class structure tags: find the class or named structure
855 ;; definition 878 ;; definition
856 (class-struct-tag 879 (class-struct-tag
857 (save-excursion 880 (save-excursion
858 (setq class 881 (setq class
859 (if (string-match "[a-zA-Z0-9]\\(__\\)" name) 882 (if (string-match "[a-zA-Z0-9]\\(__\\)" name)
860 (substring name 0 (match-beginning 1)) 883 (substring name 0 (match-beginning 1))
861 idlwave-current-tags-class)) 884 idlwave-current-tags-class))
862 (and 885 (and
863 (idlwave-find-class-definition class nil real-class) 886 (idlwave-find-class-definition class nil real-class)
864 (idlwave-find-struct-tag keyword)))) 887 (idlwave-find-struct-tag keyword))))
865 888
866 ;; Generic structure tags: the structure definition 889 ;; Generic structure tags: the structure definition
867 ;; location within the file has been recorded in 890 ;; location within the file has been recorded in
868 ;; `struct-tag' 891 ;; `struct-tag'
869 (struct-tag 892 (struct-tag
870 (save-excursion 893 (save-excursion
871 (and 894 (and
872 (integerp struct-tag) 895 (integerp struct-tag)
873 (goto-char struct-tag) 896 (goto-char struct-tag)
874 (idlwave-find-struct-tag keyword)))) 897 (idlwave-find-struct-tag keyword))))
875 898
876 ;; Just find the routine definition 899 ;; Just find the routine definition
877 (t 900 (t
878 (if class-only (point-min) 901 (if class-only (point-min)
879 (idlwave-help-find-routine-definition name type class keyword)))) 902 (idlwave-help-find-routine-definition name type class keyword))))
880 idlwave-help-def-pos def-pos) 903 idlwave-help-def-pos def-pos)
881 904
882 (if (and idlwave-help-source-try-header 905 (if (and idlwave-help-source-try-header
883 (not (or struct-tag class-struct-tag))) 906 (not (or struct-tag class-struct-tag)))
884 ;; Check if we can find the header 907 ;; Check if we can find the header
885 (save-excursion 908 (save-excursion
886 (goto-char (or def-pos (point-max))) 909 (goto-char (or def-pos (point-max)))
887 (setq header-pos (idlwave-help-find-in-doc-header 910 (setq header-pos (idlwave-help-find-in-doc-header
888 name type class keyword 'exact) 911 name type class keyword 'exact)
889 idlwave-help-in-header header-pos))) 912 idlwave-help-in-header header-pos)))
890 913
891 (if (or header-pos def-pos) 914 (if (or header-pos def-pos)
892 (progn 915 (progn
893 (if (boundp 'idlwave-help-min-frame-width) 916 (if (boundp 'idlwave-help-min-frame-width)
894 (setq idlwave-help-min-frame-width 80)) 917 (setq idlwave-help-min-frame-width 80))
895 (goto-char (or header-pos def-pos))) 918 (goto-char (or header-pos def-pos)))
896 (idlwave-help-error name type class keyword)) 919 (idlwave-help-error name type class keyword))
897 920
901 (defun idlwave-help-find-routine-definition (name type class keyword) 924 (defun idlwave-help-find-routine-definition (name type class keyword)
902 "Find the definition of routine CLASS::NAME in current buffer. 925 "Find the definition of routine CLASS::NAME in current buffer.
903 KEYWORD is ignored. Returns the point of match if successful, nil otherwise." 926 KEYWORD is ignored. Returns the point of match if successful, nil otherwise."
904 (save-excursion 927 (save-excursion
905 (goto-char (point-max)) 928 (goto-char (point-max))
906 (if (re-search-backward 929 (if (re-search-backward
907 (concat "^[ \t]*" 930 (concat "^[ \t]*"
908 (if (eq type 'pro) "pro" 931 (if (eq type 'pro) "pro"
909 (if (eq type 'fun) "function" 932 (if (eq type 'fun) "function"
910 "\\(pro\\|function\\)")) 933 "\\(pro\\|function\\)"))
911 "[ \t]+" 934 "[ \t]+"
947 970
948 with spaces allowed between the keyword and the following dash or equal sign. 971 with spaces allowed between the keyword and the following dash or equal sign.
949 If there is a match, we assume it is the keyword description." 972 If there is a match, we assume it is the keyword description."
950 (let* ((case-fold-search t) 973 (let* ((case-fold-search t)
951 (rname (if (stringp class) 974 (rname (if (stringp class)
952 (concat 975 (concat
953 "\\(" 976 "\\("
954 ;; Traditional name or class::name 977 ;; Traditional name or class::name
955 "\\(" 978 "\\("
956 "\\(" (regexp-quote (downcase class)) "::\\)?" 979 "\\(" (regexp-quote (downcase class)) "::\\)?"
957 (regexp-quote (downcase name)) 980 (regexp-quote (downcase name))
958 "\\>\\)" 981 "\\>\\)"
959 (concat 982 (concat
960 "\\|" 983 "\\|"
961 ;; class__define or just class 984 ;; class__define or just class
962 (regexp-quote (downcase class)) "\\(__define\\)?") 985 (regexp-quote (downcase class)) "\\(__define\\)?")
963 "\\)") 986 "\\)")
964 (regexp-quote (downcase name)))) 987 (regexp-quote (downcase name))))
965 988
966 ;; NAME tag plus the routine name. The new version is from JD. 989 ;; NAME tag plus the routine name. The new version is from JD.
967 (name-re (concat 990 (name-re (concat
968 "\\(^;+\\*?[ \t]*" 991 "\\(^;+\\*?[ \t]*"
969 idlwave-help-doclib-name 992 idlwave-help-doclib-name
970 "\\([ \t]*:\\|[ \t]*$\\)[ \t]*\\(\n;+[ \t]*\\)*" 993 "\\([ \t]*:\\|[ \t]*$\\)[ \t]*\\(\n;+[ \t]*\\)*"
971 rname 994 rname
972 "\\|" 995 "\\|"
997 (concat 1020 (concat
998 "^;+[ \t]+" 1021 "^;+[ \t]+"
999 (regexp-quote (upcase keyword)) 1022 (regexp-quote (upcase keyword))
1000 "\\>"))) 1023 "\\>")))
1001 dstart dend name-pos kwds-pos kwd-pos) 1024 dstart dend name-pos kwds-pos kwd-pos)
1002 (catch 'exit 1025 (catch 'exit
1003 (save-excursion 1026 (save-excursion
1004 (goto-char (point-min)) 1027 (goto-char (point-min))
1005 (while (and (setq dstart (re-search-forward idlwave-doclib-start nil t)) 1028 (while (and (setq dstart (re-search-forward idlwave-doclib-start nil t))
1006 (setq dend (re-search-forward idlwave-doclib-end nil t))) 1029 (setq dend (re-search-forward idlwave-doclib-end nil t)))
1007 ;; found a routine header 1030 ;; found a routine header
1008 (goto-char dstart) 1031 (goto-char dstart)
1009 (if (setq name-pos (re-search-forward name-re dend t)) 1032 (if (setq name-pos (re-search-forward name-re dend t))
1010 (progn 1033 (progn
1011 (if keyword 1034 (if keyword
1012 ;; We do need a keyword 1035 ;; We do need a keyword
1013 (progn 1036 (progn
1014 ;; Try to find a keyword section, but don't force it. 1037 ;; Try to find a keyword section, but don't force it.
1015 (goto-char name-pos) 1038 (goto-char name-pos)
1087 (interactive "P") 1110 (interactive "P")
1088 (if arg 1111 (if arg
1089 (idlwave-help-find-first-header nil) 1112 (idlwave-help-find-first-header nil)
1090 (setq idlwave-help-in-header nil) 1113 (setq idlwave-help-in-header nil)
1091 (idlwave-help-toggle-header-match-and-def arg 'top))) 1114 (idlwave-help-toggle-header-match-and-def arg 'top)))
1092 1115
1093 (defun idlwave-help-toggle-header-match-and-def (arg &optional top) 1116 (defun idlwave-help-toggle-header-match-and-def (arg &optional top)
1094 (interactive "P") 1117 (interactive "P")
1095 (let ((args idlwave-help-args) 1118 (let ((args idlwave-help-args)
1096 pos) 1119 pos)
1097 (if idlwave-help-in-header 1120 (if idlwave-help-in-header
1099 (progn 1122 (progn
1100 (setq idlwave-help-in-header nil) 1123 (setq idlwave-help-in-header nil)
1101 (setq pos idlwave-help-def-pos)) 1124 (setq pos idlwave-help-def-pos))
1102 ;; Try to display header 1125 ;; Try to display header
1103 (setq pos (apply 'idlwave-help-find-in-doc-header 1126 (setq pos (apply 'idlwave-help-find-in-doc-header
1104 (if top 1127 (if top
1105 (list (car args) (nth 1 args) (nth 2 args) nil) 1128 (list (car args) (nth 1 args) (nth 2 args) nil)
1106 args))) 1129 args)))
1107 (if pos 1130 (if pos
1108 (setq idlwave-help-in-header t) 1131 (setq idlwave-help-in-header t)
1109 (error "Cannot find doclib header for routine %s" 1132 (error "Cannot find doclib header for routine %s"
1133 (set (make-local-variable 'font-lock-defaults) 1156 (set (make-local-variable 'font-lock-defaults)
1134 idlwave-font-lock-defaults) 1157 idlwave-font-lock-defaults)
1135 (font-lock-fontify-buffer)) 1158 (font-lock-fontify-buffer))
1136 (set-syntax-table syntax-table))))) 1159 (set-syntax-table syntax-table)))))
1137 1160
1138 1161
1139 (defun idlwave-help-error (name type class keyword) 1162 (defun idlwave-help-error (name type class keyword)
1140 (error "Can't find help on %s%s %s" 1163 (error "Can't find help on %s%s %s"
1141 (or (and (or class name) (idlwave-make-full-name class name)) 1164 (or (and (or class name) (idlwave-make-full-name class name))
1142 "<unknown>") 1165 "<unknown>")
1143 (if keyword (format ", keyword %s" (upcase keyword)) "") 1166 (if keyword (format ", keyword %s" (upcase keyword)) "")
1189 (defun idlwave-has-help (name type class) 1212 (defun idlwave-has-help (name type class)
1190 "Does this have help associated with it?" 1213 "Does this have help associated with it?"
1191 (let ((entry (idlwave-best-rinfo-assoc name type class (idlwave-routines)))) 1214 (let ((entry (idlwave-best-rinfo-assoc name type class (idlwave-routines))))
1192 (idlwave-entry-has-help entry))) 1215 (idlwave-entry-has-help entry)))
1193 1216
1217 ;;----- Control the IDL Assistant, which shipped with IDL v6.2
1218 (defvar idlwave-help-assistant-process nil)
1219 (defvar idlwave-help-assistant-socket nil)
1220
1221 ;; The Windows version does not have a !DIR/bin/* set of front-end
1222 ;; scripts, but instead only links directly to bin.x86. As a result,
1223 ;; we must pass the -profile argument as well.
1224 (defvar idlwave-help-assistant-command
1225 (if (memq system-type '(ms-dos windows-nt))
1226 "bin/bin.x86/idl_assistant"
1227 "bin/idl_assistant")
1228 "The command, rooted at idlwave-system-directory, which invokes the
1229 IDL assistant.")
1230
1231 (defun idlwave-help-assistant-available ()
1232 (if idlwave-help-assistant-available
1233 (eq idlwave-help-assistant-available t)
1234 (setq idlwave-help-assistant-available
1235 (if (file-executable-p (idlwave-help-assistant-command))
1236 t
1237 'not-available))))
1238
1239 (defun idlwave-help-assistant-command ()
1240 (expand-file-name idlwave-help-assistant-command (idlwave-sys-dir)))
1241
1242 (defun idlwave-help-assistant-start (&optional link)
1243 "Start the IDL Assistant, loading LINK, if passed."
1244 (when (or (not idlwave-help-assistant-socket)
1245 (not (eq (process-status idlwave-help-assistant-socket) 'open)))
1246 (let* ((help-loc (idlwave-html-help-location))
1247 (command (idlwave-help-assistant-command))
1248 (extra-args
1249 (nconc
1250 (if (memq system-type '(ms-dos windows-nt))
1251 `("-profile" ,(expand-file-name "idl.adp" help-loc)))
1252 (if link
1253 `("-file" ,(expand-file-name link help-loc)))))
1254 port)
1255 (if idlwave-help-assistant-socket
1256 (delete-process idlwave-help-assistant-socket))
1257
1258 (setq idlwave-help-assistant-process
1259 (apply 'start-process
1260 "IDL_ASSISTANT_PROC" nil command "-server" extra-args))
1261
1262 (set-process-filter idlwave-help-assistant-process
1263 (lambda (proc string)
1264 (setq port (string-to-number string))))
1265 (unless (accept-process-output idlwave-help-assistant-process 15)
1266 (error "Failed binding IDL_ASSISTANT socket"))
1267 (if (not port)
1268 (error "Unable to open IDL_ASSISTANT.")
1269 (set-process-filter idlwave-help-assistant-process nil)
1270 (setq idlwave-help-assistant-socket
1271 (open-network-stream "IDL_ASSISTANT_SOCK"
1272 nil "localhost" port))
1273 (if (eq (process-status idlwave-help-assistant-socket) 'open)
1274 (process-send-string idlwave-help-assistant-socket
1275 (concat "setHelpPath " help-loc "\n"))
1276 (idlwave-help-assistant-close)
1277 (error "Cannot communicate with IDL_ASSISTANT"))))))
1278
1279 (defun idlwave-help-assistant-raise ()
1280 (idlwave-help-assistant-start)
1281 (process-send-string idlwave-help-assistant-socket "raise\n"))
1282
1283 (defun idlwave-help-assistant-open-link (&optional link)
1284 ;; Open a link (file name with anchor, no leading path) in the assistant.
1285 (if link
1286 (let ((file (expand-file-name link (idlwave-html-help-location))))
1287 (idlwave-help-assistant-start link)
1288 (process-send-string idlwave-help-assistant-socket
1289 (concat "openLink " file "\n"))
1290 (string-match "\.html" link)
1291 (process-send-string idlwave-help-assistant-socket
1292 (concat "searchIndexNoOpen "
1293 (substring link 0 (match-beginning 0))
1294 "\n")))
1295 (idlwave-help-assistant-raise)))
1296
1297 (defun idlwave-help-assistant-close ()
1298 (when (and idlwave-help-assistant-process
1299 (eq (process-status idlwave-help-assistant-process) 'run))
1300 (when idlwave-help-assistant-socket
1301 (process-send-string idlwave-help-assistant-socket "quit\n")
1302 (delete-process idlwave-help-assistant-socket))
1303 (stop-process idlwave-help-assistant-process)
1304 (delete-process idlwave-help-assistant-process)
1305 (setq idlwave-help-assistant-socket nil
1306 idlwave-help-assistant-process nil)))
1307
1308
1194 (provide 'idlw-help) 1309 (provide 'idlw-help)
1195 (provide 'idlwave-help) 1310 (provide 'idlwave-help)
1196 1311
1197 ;; arch-tag: d27b5505-59de-497f-ba3f-f199fd4fb911 1312 ;; arch-tag: d27b5505-59de-497f-ba3f-f199fd4fb911
1198 ;;; idlw-help.el ends here 1313 ;;; idlw-help.el ends here