comparison lisp/progmodes/idlw-help.el @ 94672:0e2d838cfad2

Switch to recommended form of GPLv3 permissions notice. Delete trailing whitespace.
author Glenn Morris <rgm@gnu.org>
date Tue, 06 May 2008 07:14:39 +0000
parents 107ccd98fa12
children a9dc0e7c3f2b
comparison
equal deleted inserted replaced
94671:f3ab0c2464f5 94672:0e2d838cfad2
8 ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu> 8 ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu>
9 ;; Version: 6.1_em22 9 ;; Version: 6.1_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 ;; GNU Emacs 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
15 ;; the Free Software Foundation; either version 3, or (at your option) 15 ;; the Free Software Foundation, either version 3 of the License, or
16 ;; any later version. 16 ;; (at your option) any later version.
17 17
18 ;; This file is distributed in the hope that it will be useful, 18 ;; GNU Emacs is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details. 21 ;; GNU General Public License for more details.
22 22
23 ;; You should have received a copy of the GNU General Public License 23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the 24 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26 ;; Boston, MA 02110-1301, USA.
27 25
28 ;;; Commentary: 26 ;;; Commentary:
29 27
30 ;; The help link information for IDLWAVE's online help feature for 28 ;; The help link information for IDLWAVE's online help feature for
31 ;; system routines is extracted automatically from the IDL 29 ;; system routines is extracted automatically from the IDL
34 ;; themselves are not distributable with Emacs, but are available, 32 ;; themselves are not distributable with Emacs, but are available,
35 ;; along with new versions of IDLWAVE, documentation, and more 33 ;; along with new versions of IDLWAVE, documentation, and more
36 ;; information, at: 34 ;; information, at:
37 ;; 35 ;;
38 ;; http://idlwave.org 36 ;; http://idlwave.org
39 ;; 37 ;;
40 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 38 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
41 39
42 40
43 41
44 ;;; Code: 42 ;;; Code:
54 (defcustom idlwave-html-help-pre-v6 nil 52 (defcustom idlwave-html-help-pre-v6 nil
55 "Whether pre or post-v6.0 IDL help documents are being used." 53 "Whether pre or post-v6.0 IDL help documents are being used."
56 :group 'idlwave-online-help 54 :group 'idlwave-online-help
57 :type 'boolean) 55 :type 'boolean)
58 56
59 (defvar idlwave-html-link-sep 57 (defvar idlwave-html-link-sep
60 (if idlwave-html-help-pre-v6 "#" "#wp")) 58 (if idlwave-html-help-pre-v6 "#" "#wp"))
61 59
62 (defcustom idlwave-html-system-help-location "help/online_help/" 60 (defcustom idlwave-html-system-help-location "help/online_help/"
63 "The directory, relative to idlwave-system-directory, where the idl 61 "The directory, relative to idlwave-system-directory, where the idl
64 HTML help files live, for IDL 6.2 and later. This location, if found, 62 HTML help files live, for IDL 6.2 and later. This location, if found,
65 is used in preference to the old idlwave-html-help-location." 63 is used in preference to the old idlwave-html-help-location."
66 :group 'idlwave-online-help 64 :group 'idlwave-online-help
67 :type 'directory) 65 :type 'directory)
68 66
69 (defcustom idlwave-html-help-location 67 (defcustom idlwave-html-help-location
70 (if (memq system-type '(ms-dos windows-nt)) 68 (if (memq system-type '(ms-dos windows-nt))
71 nil 69 nil
72 "/usr/local/etc/") 70 "/usr/local/etc/")
73 "The directory where the idl_html_help/ dir lives. Obsolete for IDL 71 "The directory where the idl_html_help/ dir lives. Obsolete for IDL
74 6.2 or later (see idlwave-html-system-help-location)." 72 6.2 or later (see idlwave-html-system-help-location)."
75 :group 'idlwave-online-help 73 :group 'idlwave-online-help
76 :type 'directory) 74 :type 'directory)
77 75
78 (defvar idlwave-help-use-hh nil 76 (defvar idlwave-help-use-hh nil
79 "Obsolete variable.") 77 "Obsolete variable.")
80 78
81 (defcustom idlwave-help-use-assistant t 79 (defcustom idlwave-help-use-assistant t
82 "Whether to use the IDL Assistant as the help browser." 80 "Whether to use the IDL Assistant as the help browser."
83 :group 'idlwave-online-help 81 :group 'idlwave-online-help
84 :type 'boolean) 82 :type 'boolean)
94 :group 'idlwave-online-help 92 :group 'idlwave-online-help
95 :type 'string) 93 :type 'string)
96 94
97 (defvar browse-url-generic-args) 95 (defvar browse-url-generic-args)
98 96
99 (defcustom idlwave-help-browser-generic-args 97 (defcustom idlwave-help-browser-generic-args
100 (if (boundp 'browse-url-generic-args) 98 (if (boundp 'browse-url-generic-args)
101 browse-url-generic-args "") 99 browse-url-generic-args "")
102 "Program args to use if using browse-url-generic-program." 100 "Program args to use if using browse-url-generic-program."
103 :group 'idlwave-online-help 101 :group 'idlwave-online-help
104 :type 'string) 102 :type 'string)
201 "Face for highlighting links into IDLWAVE online help." 199 "Face for highlighting links into IDLWAVE online help."
202 :group 'idlwave-online-help) 200 :group 'idlwave-online-help)
203 201
204 (defvar idlwave-help-activate-links-aggressively nil 202 (defvar idlwave-help-activate-links-aggressively nil
205 "Obsolete variable.") 203 "Obsolete variable.")
206 204
207 (defvar idlwave-completion-help-info) 205 (defvar idlwave-completion-help-info)
208 206
209 (defvar idlwave-help-frame nil 207 (defvar idlwave-help-frame nil
210 "The frame for display of IDL online help.") 208 "The frame for display of IDL online help.")
211 (defvar idlwave-help-frame-width 102 209 (defvar idlwave-help-frame-width 102
329 (set (make-local-variable 'idlwave-help-in-header) nil) 327 (set (make-local-variable 'idlwave-help-in-header) nil)
330 (run-hooks 'idlwave-help-mode-hook)) 328 (run-hooks 'idlwave-help-mode-hook))
331 329
332 (defun idlwave-html-help-location () 330 (defun idlwave-html-help-location ()
333 "Return the help directory where HTML files are, or nil if that is unknown." 331 "Return the help directory where HTML files are, or nil if that is unknown."
334 (let ((syshelp-dir (expand-file-name 332 (let ((syshelp-dir (expand-file-name
335 idlwave-html-system-help-location (idlwave-sys-dir))) 333 idlwave-html-system-help-location (idlwave-sys-dir)))
336 (help-dir (or (and (stringp idlwave-html-help-location) 334 (help-dir (or (and (stringp idlwave-html-help-location)
337 (> (length idlwave-html-help-location) 0) 335 (> (length idlwave-html-help-location) 0)
338 idlwave-html-help-location) 336 idlwave-html-help-location)
339 (getenv "IDLWAVE_HELP_LOCATION")))) 337 (getenv "IDLWAVE_HELP_LOCATION"))))
340 (if (and syshelp-dir (file-directory-p syshelp-dir)) 338 (if (and syshelp-dir (file-directory-p syshelp-dir))
341 syshelp-dir 339 syshelp-dir
342 (if help-dir 340 (if help-dir
343 (progn 341 (progn
344 (setq help-dir (expand-file-name "idl_html_help" help-dir)) 342 (setq help-dir (expand-file-name "idl_html_help" help-dir))
345 (if (file-directory-p help-dir) help-dir)))))) 343 (if (file-directory-p help-dir) help-dir))))))
346 344
347 (defvar idlwave-help-assistant-available nil) 345 (defvar idlwave-help-assistant-available nil)
348 346
349 (defun idlwave-help-check-locations () 347 (defun idlwave-help-check-locations ()
350 ;; Check help locations and assistant. 348 ;; Check help locations and assistant.
351 (let ((sys-dir (idlwave-sys-dir)) 349 (let ((sys-dir (idlwave-sys-dir))
352 (help-loc (idlwave-html-help-location))) 350 (help-loc (idlwave-html-help-location)))
382 (idlwave-help-select-help-frame) 380 (idlwave-help-select-help-frame)
383 ;; Do the real thing. 381 ;; Do the real thing.
384 (setq idlwave-last-context-help-pos marker) 382 (setq idlwave-last-context-help-pos marker)
385 (idlwave-do-context-help1 arg) 383 (idlwave-do-context-help1 arg)
386 (if idlwave-help-diagnostics 384 (if idlwave-help-diagnostics
387 (message "%s" (mapconcat 'identity 385 (message "%s" (mapconcat 'identity
388 (nreverse idlwave-help-diagnostics) 386 (nreverse idlwave-help-diagnostics)
389 "; ")))))) 387 "; "))))))
390 388
391 (defvar idlwave-help-do-class-struct-tag nil) 389 (defvar idlwave-help-do-class-struct-tag nil)
392 (defvar idlwave-structtag-struct-location) 390 (defvar idlwave-structtag-struct-location)
395 (defvar idlwave-executive-commands-alist) 393 (defvar idlwave-executive-commands-alist)
396 (defvar idlwave-system-class-info) 394 (defvar idlwave-system-class-info)
397 (defun idlwave-do-context-help1 (&optional arg) 395 (defun idlwave-do-context-help1 (&optional arg)
398 "The work-horse version of `idlwave-context-help', which see." 396 "The work-horse version of `idlwave-context-help', which see."
399 (save-excursion 397 (save-excursion
400 (if (equal (char-after) ?/) 398 (if (equal (char-after) ?/)
401 (forward-char 1) 399 (forward-char 1)
402 (if (equal (char-before) ?=) 400 (if (equal (char-before) ?=)
403 (backward-char 1))) 401 (backward-char 1)))
404 (let* ((idlwave-query-class nil) 402 (let* ((idlwave-query-class nil)
405 (idlwave-force-class-query (equal arg '(4))) 403 (idlwave-force-class-query (equal arg '(4)))
413 (< beg (- end 4)))) 411 (< beg (- end 4))))
414 (structtag (and (fboundp 'idlwave-complete-structure-tag) 412 (structtag (and (fboundp 'idlwave-complete-structure-tag)
415 (string-match "\\`\\([^.]+\\)\\." this-word) 413 (string-match "\\`\\([^.]+\\)\\." this-word)
416 (< beg (- end 4)))) 414 (< beg (- end 4))))
417 module keyword cw mod1 mod2 mod3) 415 module keyword cw mod1 mod2 mod3)
418 (if (or arg 416 (if (or arg
419 (and (not classtag) 417 (and (not classtag)
420 (not structtag) 418 (not structtag)
421 (not (member (string-to-char this-word) '(?! ?.))))) 419 (not (member (string-to-char this-word) '(?! ?.)))))
422 ;; Need the module information 420 ;; Need the module information
423 (progn 421 (progn
431 (str (buffer-substring bos (point)))) 429 (str (buffer-substring bos (point))))
432 (if (string-match "OBJ_NEW([ \t]*['\"]\\([a-zA-Z][a-zA-Z0-9$_]+\\)['\"]" str) 430 (if (string-match "OBJ_NEW([ \t]*['\"]\\([a-zA-Z][a-zA-Z0-9$_]+\\)['\"]" str)
433 (setq module (list "init" 'fun (match-string 1 str)) 431 (setq module (list "init" 'fun (match-string 1 str))
434 idlwave-current-obj_new-class (match-string 1 str)) 432 idlwave-current-obj_new-class (match-string 1 str))
435 ))))) 433 )))))
436 (cond 434 (cond
437 (arg (setq mod1 module)) 435 (arg (setq mod1 module))
438 436
439 ;; A special topic -- only system help 437 ;; A special topic -- only system help
440 ((and st-ass (not (memq cw '(function-keyword procedure-keyword)))) 438 ((and st-ass (not (memq cw '(function-keyword procedure-keyword))))
441 (setq mod1 (list (cdr st-ass)))) 439 (setq mod1 (list (cdr st-ass))))
442 440
443 ;; A system variable -- only system help 441 ;; A system variable -- only system help
444 ((string-match 442 ((string-match
445 "\\`!\\([a-zA-Z0-9_]+\\)\\(\.\\([A-Za-z0-9_]+\\)\\)?" 443 "\\`!\\([a-zA-Z0-9_]+\\)\\(\.\\([A-Za-z0-9_]+\\)\\)?"
446 this-word) 444 this-word)
447 (let* ((word (match-string-no-properties 1 this-word)) 445 (let* ((word (match-string-no-properties 1 this-word))
448 (entry (assq (idlwave-sintern-sysvar word) 446 (entry (assq (idlwave-sintern-sysvar word)
449 idlwave-system-variables-alist)) 447 idlwave-system-variables-alist))
450 (tag (match-string-no-properties 3 this-word)) 448 (tag (match-string-no-properties 3 this-word))
452 (cdr 450 (cdr
453 (assq (idlwave-sintern-sysvartag tag) 451 (assq (idlwave-sintern-sysvartag tag)
454 (cdr (assq 'tags entry)))))) 452 (cdr (assq 'tags entry))))))
455 (link (nth 1 (assq 'link entry)))) 453 (link (nth 1 (assq 'link entry))))
456 (if tag-target 454 (if tag-target
457 (setq link (idlwave-substitute-link-target link 455 (setq link (idlwave-substitute-link-target link
458 tag-target))) 456 tag-target)))
459 (setq mod1 (list link)))) 457 (setq mod1 (list link))))
460 458
461 ;; An executive command -- only system help 459 ;; An executive command -- only system help
462 ((string-match "^\\.\\([A-Z_]+\\)" this-word) 460 ((string-match "^\\.\\([A-Z_]+\\)" this-word)
463 (let* ((word (match-string 1 this-word)) 461 (let* ((word (match-string 1 this-word))
464 (link (cdr (assoc-string 462 (link (cdr (assoc-string
465 word 463 word
466 idlwave-executive-commands-alist t)))) 464 idlwave-executive-commands-alist t))))
467 (setq mod1 (list link)))) 465 (setq mod1 (list link))))
468 466
469 ;; A class -- system OR in-text help (via class__define). 467 ;; A class -- system OR in-text help (via class__define).
470 ((and (eq cw 'class) 468 ((and (eq cw 'class)
471 (or (idlwave-in-quote) ; e.g. obj_new 469 (or (idlwave-in-quote) ; e.g. obj_new
472 (re-search-backward "\\<inherits[ \t]+[A-Za-z0-9_]*\\=" 470 (re-search-backward "\\<inherits[ \t]+[A-Za-z0-9_]*\\="
473 (max (point-min) (- (point) 40)) t))) 471 (max (point-min) (- (point) 40)) t)))
477 (idlwave-sintern-class this-word) 475 (idlwave-sintern-class this-word)
478 idlwave-system-class-info)) 476 idlwave-system-class-info))
479 (name (concat (downcase this-word) "__define")) 477 (name (concat (downcase this-word) "__define"))
480 (link (nth 1 (assq 'link entry)))) 478 (link (nth 1 (assq 'link entry))))
481 (setq mod1 (list link name 'pro)))) 479 (setq mod1 (list link name 'pro))))
482 480
483 ;; A class structure tag (self.BLAH) -- only in-text help available 481 ;; A class structure tag (self.BLAH) -- only in-text help available
484 (classtag 482 (classtag
485 (let ((tag (substring this-word (match-end 0))) 483 (let ((tag (substring this-word (match-end 0)))
486 class-with found-in) 484 class-with found-in)
487 (when (setq class-with 485 (when (setq class-with
488 (idlwave-class-or-superclass-with-tag 486 (idlwave-class-or-superclass-with-tag
489 (nth 2 (idlwave-current-routine)) 487 (nth 2 (idlwave-current-routine))
490 tag)) 488 tag))
491 (setq found-in (idlwave-class-found-in class-with)) 489 (setq found-in (idlwave-class-found-in class-with))
492 (if (assq (idlwave-sintern-class class-with) 490 (if (assq (idlwave-sintern-class class-with)
493 idlwave-system-class-info) 491 idlwave-system-class-info)
494 (error "No help available for system class tags")) 492 (error "No help available for system class tags"))
495 (setq idlwave-help-do-class-struct-tag t) 493 (setq idlwave-help-do-class-struct-tag t)
496 (setq mod1 (list nil 494 (setq mod1 (list nil
497 (if found-in 495 (if found-in
498 (cons (concat found-in "__define") class-with) 496 (cons (concat found-in "__define") class-with)
499 (concat class-with "__define")) 497 (concat class-with "__define"))
500 'pro 498 'pro
501 nil ; no class.... it's a procedure! 499 nil ; no class.... it's a procedure!
502 tag))))) 500 tag)))))
503 501
504 ;; A regular structure tag -- only in text, and if 502 ;; A regular structure tag -- only in text, and if
505 ;; optional `complete-structtag' loaded. 503 ;; optional `complete-structtag' loaded.
506 (structtag 504 (structtag
507 (let ((var (match-string 1 this-word)) 505 (let ((var (match-string 1 this-word))
508 (tag (substring this-word (match-end 0)))) 506 (tag (substring this-word (match-end 0))))
509 ;; Check if we need to update the "current" structure 507 ;; Check if we need to update the "current" structure
510 (idlwave-prepare-structure-tag-completion var) 508 (idlwave-prepare-structure-tag-completion var)
511 (setq idlwave-help-do-struct-tag 509 (setq idlwave-help-do-struct-tag
512 idlwave-structtag-struct-location 510 idlwave-structtag-struct-location
513 mod1 (list nil nil nil nil tag)))) 511 mod1 (list nil nil nil nil tag))))
514 512
515 ;; A routine keyword -- in text or system help 513 ;; A routine keyword -- in text or system help
516 ((and (memq cw '(function-keyword procedure-keyword)) 514 ((and (memq cw '(function-keyword procedure-keyword))
517 (stringp this-word) 515 (stringp this-word)
518 (string-match "\\S-" this-word) 516 (string-match "\\S-" this-word)
519 (not (string-match "!" this-word))) 517 (not (string-match "!" this-word)))
551 (setq keyword (idlwave-expand-keyword this-word module)) 549 (setq keyword (idlwave-expand-keyword this-word module))
552 (if (consp keyword) (setq keyword (car keyword))) 550 (if (consp keyword) (setq keyword (car keyword)))
553 (setq mod1 (append (list t) module (list keyword)) 551 (setq mod1 (append (list t) module (list keyword))
554 mod2 (list t this-word 'fun nil) 552 mod2 (list t this-word 'fun nil)
555 mod3 (append (list t) module))))) 553 mod3 (append (list t) module)))))
556 554
557 ;; Everything else 555 ;; Everything else
558 (t 556 (t
559 (setq mod1 (append (list t) module)))) 557 (setq mod1 (append (list t) module))))
560 (if mod3 558 (if mod3
561 (condition-case nil 559 (condition-case nil
584 (kwd (nth 4 info)) 582 (kwd (nth 4 info))
585 (sclasses (nth 5 info)) 583 (sclasses (nth 5 info))
586 word link) 584 word link)
587 (mouse-set-point ev) 585 (mouse-set-point ev)
588 586
589 587
590 ;; See if we can also find help somewhere, e.g. for multiple classes 588 ;; See if we can also find help somewhere, e.g. for multiple classes
591 (setq word (idlwave-this-word)) 589 (setq word (idlwave-this-word))
592 (if (string= word "") 590 (if (string= word "")
593 (error "No help item selected")) 591 (error "No help item selected"))
594 (setq link (get-text-property 0 'link word)) 592 (setq link (get-text-property 0 'link word))
595 (select-window cw) 593 (select-window cw)
596 (cond 594 (cond
597 ;; Routine name 595 ;; Routine name
598 ((memq what '(procedure function routine)) 596 ((memq what '(procedure function routine))
599 (setq name word) 597 (setq name word)
600 (if (or (eq class t) 598 (if (or (eq class t)
601 (and (stringp class) sclasses)) 599 (and (stringp class) sclasses))
602 (let* ((classes (idlwave-all-method-classes 600 (let* ((classes (idlwave-all-method-classes
603 (idlwave-sintern-method name) 601 (idlwave-sintern-method name)
604 type))) 602 type)))
605 (setq link t) ; No specific link valid yet 603 (setq link t) ; No specific link valid yet
606 (if sclasses 604 (if sclasses
607 (setq classes (idlwave-members-only 605 (setq classes (idlwave-members-only
608 classes (cons class sclasses)))) 606 classes (cons class sclasses))))
609 (setq class (idlwave-popup-select ev classes 607 (setq class (idlwave-popup-select ev classes
610 "Select Class" 'sort)))) 608 "Select Class" 'sort))))
611 609
612 ;; XXX is this necessary, given all-method-classes? 610 ;; XXX is this necessary, given all-method-classes?
613 (if (stringp class) 611 (if (stringp class)
614 (setq class (idlwave-find-inherited-class 612 (setq class (idlwave-find-inherited-class
624 (idlwave-sintern-method name) 622 (idlwave-sintern-method name)
625 (idlwave-sintern-keyword kwd) 623 (idlwave-sintern-keyword kwd)
626 type))) 624 type)))
627 (setq link t) ; Link can't be correct yet 625 (setq link t) ; Link can't be correct yet
628 (if sclasses 626 (if sclasses
629 (setq classes (idlwave-members-only 627 (setq classes (idlwave-members-only
630 classes (cons class sclasses)))) 628 classes (cons class sclasses))))
631 (setq class (idlwave-popup-select ev classes 629 (setq class (idlwave-popup-select ev classes
632 "Select Class" 'sort)) 630 "Select Class" 'sort))
633 ;; XXX is this necessary, given all-method-keyword-classes? 631 ;; XXX is this necessary, given all-method-keyword-classes?
634 (if (stringp class) 632 (if (stringp class)
636 (idlwave-sintern-routine-or-method name class) 634 (idlwave-sintern-routine-or-method name class)
637 type (idlwave-sintern-class class))))) 635 type (idlwave-sintern-class class)))))
638 (if (string= (downcase name) "obj_new") 636 (if (string= (downcase name) "obj_new")
639 (setq class idlwave-current-obj_new-class 637 (setq class idlwave-current-obj_new-class
640 name "Init")))) 638 name "Init"))))
641 639
642 ;; Class name 640 ;; Class name
643 ((eq what 'class) 641 ((eq what 'class)
644 (setq class word 642 (setq class word
645 word nil)) 643 word nil))
646 644
647 ;; A special named function to call which sets some of our variables 645 ;; A special named function to call which sets some of our variables
648 ((and (symbolp what) 646 ((and (symbolp what)
649 (fboundp what)) 647 (fboundp what))
650 (funcall what 'set word)) 648 (funcall what 'set word))
651 649
652 (t (error "Cannot help with this item"))) 650 (t (error "Cannot help with this item")))
653 (if (and need-class (not class) (not (and link (not (eq link t))))) 651 (if (and need-class (not class) (not (and link (not (eq link t)))))
658 (defvar idlwave-completion-help-links) 656 (defvar idlwave-completion-help-links)
659 (defun idlwave-highlight-linked-completions () 657 (defun idlwave-highlight-linked-completions ()
660 "Highlight all completions for which help is available and attach link. 658 "Highlight all completions for which help is available and attach link.
661 Those words in `idlwave-completion-help-links' have links. The 659 Those words in `idlwave-completion-help-links' have links. The
662 `idlwave-help-link' face is used for this." 660 `idlwave-help-link' face is used for this."
663 (if idlwave-highlight-help-links-in-completion 661 (if idlwave-highlight-help-links-in-completion
664 (with-current-buffer (get-buffer "*Completions*") 662 (with-current-buffer (get-buffer "*Completions*")
665 (save-excursion 663 (save-excursion
666 (let* ((case-fold-search t) 664 (let* ((case-fold-search t)
667 (props (list 'face 'idlwave-help-link)) 665 (props (list 'face 'idlwave-help-link))
668 (info idlwave-completion-help-info) ; global passed in 666 (info idlwave-completion-help-info) ; global passed in
674 (while (re-search-forward "\\s-\\([A-Za-z0-9_.]+\\)\\(\\s-\\|\\'\\)" 672 (while (re-search-forward "\\s-\\([A-Za-z0-9_.]+\\)\\(\\s-\\|\\'\\)"
675 nil t) 673 nil t)
676 (setq beg (match-beginning 1) end (match-end 1) 674 (setq beg (match-beginning 1) end (match-end 1)
677 word (match-string 1) doit nil) 675 word (match-string 1) doit nil)
678 ;; Call special completion function test 676 ;; Call special completion function test
679 (if (and (symbolp what) 677 (if (and (symbolp what)
680 (fboundp what)) 678 (fboundp what))
681 (setq doit (funcall what 'test word)) 679 (setq doit (funcall what 'test word))
682 ;; Look for special link property passed in help-links 680 ;; Look for special link property passed in help-links
683 (if idlwave-completion-help-links 681 (if idlwave-completion-help-links
684 (setq doit (assoc-string 682 (setq doit (assoc-string
705 (if (and idlwave-experimental 703 (if (and idlwave-experimental
706 (frame-live-p idlwave-help-return-frame)) 704 (frame-live-p idlwave-help-return-frame))
707 ;; Try to select the return frame. 705 ;; Try to select the return frame.
708 ;; This can crash on slow network connections, obviously when 706 ;; This can crash on slow network connections, obviously when
709 ;; we kill the help frame before the return-frame is selected. 707 ;; we kill the help frame before the return-frame is selected.
710 ;; To protect the workings, we wait for up to one second 708 ;; To protect the workings, we wait for up to one second
711 ;; and check if the return-frame *is* now selected. 709 ;; and check if the return-frame *is* now selected.
712 ;; This is marked "eperimental" since we are not sure when its OK. 710 ;; This is marked "eperimental" since we are not sure when its OK.
713 (let ((maxtime 1.0) (time 0.) (step 0.1)) 711 (let ((maxtime 1.0) (time 0.) (step 0.1))
714 (select-frame idlwave-help-return-frame) 712 (select-frame idlwave-help-return-frame)
715 (while (and (sit-for step) 713 (while (and (sit-for step)
716 (not (eq (selected-frame) 714 (not (eq (selected-frame)
717 idlwave-help-return-frame)) 715 idlwave-help-return-frame))
718 (< (setq time (+ time step)) maxtime))))) 716 (< (setq time (+ time step)) maxtime)))))
719 (delete-frame idlwave-help-frame)) 717 (delete-frame idlwave-help-frame))
720 ((window-configuration-p idlwave-help-window-configuration) 718 ((window-configuration-p idlwave-help-window-configuration)
721 (set-window-configuration idlwave-help-window-configuration) 719 (set-window-configuration idlwave-help-window-configuration)
724 722
725 723
726 (defvar default-toolbar-visible-p) 724 (defvar default-toolbar-visible-p)
727 725
728 (defun idlwave-help-display-help-window (&optional pos-or-func) 726 (defun idlwave-help-display-help-window (&optional pos-or-func)
729 "Display the help window. 727 "Display the help window.
730 Move window start to POS-OR-FUNC, if passed as a position, or call it 728 Move window start to POS-OR-FUNC, if passed as a position, or call it
731 if passed as a function. See `idlwave-help-use-dedicated-frame'." 729 if passed as a function. See `idlwave-help-use-dedicated-frame'."
732 (let ((cw (selected-window)) 730 (let ((cw (selected-window))
733 (buf (idlwave-help-get-help-buffer))) 731 (buf (idlwave-help-get-help-buffer)))
734 (if (and window-system idlwave-help-use-dedicated-frame) 732 (if (and window-system idlwave-help-use-dedicated-frame)
735 (progn 733 (progn
736 (idlwave-help-show-help-frame) 734 (idlwave-help-show-help-frame)
737 (switch-to-buffer buf)) 735 (switch-to-buffer buf))
738 ;; Do it in this frame and save the window configuration 736 ;; Do it in this frame and save the window configuration
739 (if (not (get-buffer-window buf nil)) 737 (if (not (get-buffer-window buf nil))
740 (setq idlwave-help-window-configuration 738 (setq idlwave-help-window-configuration
741 (current-window-configuration))) 739 (current-window-configuration)))
742 (display-buffer buf nil (selected-frame)) 740 (display-buffer buf nil (selected-frame))
743 (select-window (get-buffer-window buf))) 741 (select-window (get-buffer-window buf)))
744 (raise-frame) 742 (raise-frame)
745 (if pos-or-func 743 (if pos-or-func
746 (if (functionp pos-or-func) 744 (if (functionp pos-or-func)
747 (funcall pos-or-func) 745 (funcall pos-or-func)
748 (goto-char pos-or-func) 746 (goto-char pos-or-func)
749 (recenter 0))) 747 (recenter 0)))
750 (select-window cw))) 748 (select-window cw)))
751 749
763 (if (and (frame-live-p idlwave-help-return-frame) 761 (if (and (frame-live-p idlwave-help-return-frame)
764 (not (eq (selected-frame) idlwave-help-return-frame))) 762 (not (eq (selected-frame) idlwave-help-return-frame)))
765 (select-frame idlwave-help-return-frame))) 763 (select-frame idlwave-help-return-frame)))
766 764
767 (defun idlwave-online-help (link &optional name type class keyword) 765 (defun idlwave-online-help (link &optional name type class keyword)
768 "Display HTML or other special help on a certain topic. 766 "Display HTML or other special help on a certain topic.
769 Either loads an HTML link, if LINK is non-nil, or gets special-help on 767 Either loads an HTML link, if LINK is non-nil, or gets special-help on
770 the optional arguments, if any special help is defined. If LINK is 768 the optional arguments, if any special help is defined. If LINK is
771 `t', first look up the optional arguments in the routine info list to 769 `t', first look up the optional arguments in the routine info list to
772 see if a link is set for it. Try extra help functions if necessary." 770 see if a link is set for it. Try extra help functions if necessary."
773 ;; Lookup link 771 ;; Lookup link
774 (if (eq link t) 772 (if (eq link t)
775 (let ((entry (idlwave-best-rinfo-assoc name type class 773 (let ((entry (idlwave-best-rinfo-assoc name type class
776 (idlwave-routines) nil t))) 774 (idlwave-routines) nil t)))
777 (if entry 775 (if entry
778 (cond 776 (cond
779 ;; Try keyword link 777 ;; Try keyword link
780 ((and keyword 778 ((and keyword
781 (setq link (cdr 779 (setq link (cdr
782 (idlwave-entry-find-keyword entry keyword))))) 780 (idlwave-entry-find-keyword entry keyword)))))
783 ;; Default, regular entry link 781 ;; Default, regular entry link
784 (t (setq link (idlwave-entry-has-help entry)))) 782 (t (setq link (idlwave-entry-has-help entry))))
785 (if (and 783 (if (and
786 class 784 class
787 ;; Check for system class help 785 ;; Check for system class help
788 (setq entry (assq (idlwave-sintern-class class) 786 (setq entry (assq (idlwave-sintern-class class)
789 idlwave-system-class-info) 787 idlwave-system-class-info)
790 link (nth 1 (assq 'link entry)))) 788 link (nth 1 (assq 'link entry))))
791 (message 789 (message
792 (concat "No routine info for %s" 790 (concat "No routine info for %s"
793 ", falling back on class help.") 791 ", falling back on class help.")
794 (idlwave-make-full-name class name)))))) 792 (idlwave-make-full-name class name))))))
795 793
796 (cond 794 (cond
797 ;; An explicit link 795 ;; An explicit link
798 ((stringp link) 796 ((stringp link)
799 (idlwave-help-html-link link)) 797 (idlwave-help-html-link link))
800 798
801 ;; Any extra help 799 ;; Any extra help
802 (idlwave-extra-help-function 800 (idlwave-extra-help-function
803 (idlwave-help-get-special-help name type class keyword)) 801 (idlwave-help-get-special-help name type class keyword))
804 802
805 ;; Nothing worked 803 ;; Nothing worked
806 (t (idlwave-help-error name type class keyword)))) 804 (t (idlwave-help-error name type class keyword))))
807 805
808 806
809 (defun idlwave-help-get-special-help (name type class keyword) 807 (defun idlwave-help-get-special-help (name type class keyword)
810 "Call the function given by `idlwave-extra-help-function'." 808 "Call the function given by `idlwave-extra-help-function'."
811 (let* ((cw (selected-window)) 809 (let* ((cw (selected-window))
812 (help-pos (save-excursion 810 (help-pos (save-excursion
813 (set-buffer (idlwave-help-get-help-buffer)) 811 (set-buffer (idlwave-help-get-help-buffer))
814 (let ((buffer-read-only nil)) 812 (let ((buffer-read-only nil))
815 (funcall idlwave-extra-help-function 813 (funcall idlwave-extra-help-function
816 name type class keyword))))) 814 name type class keyword)))))
817 (if help-pos 815 (if help-pos
818 (idlwave-help-display-help-window help-pos) 816 (idlwave-help-display-help-window help-pos)
819 (idlwave-help-error name type class keyword)) 817 (idlwave-help-error name type class keyword))
820 (select-window cw))) 818 (select-window cw)))
868 (class-only (and (stringp class) (not (stringp name)))) 866 (class-only (and (stringp class) (not (stringp name))))
869 file header-pos def-pos in-buf) 867 file header-pos def-pos in-buf)
870 (if class-only ;Help with class? Using "Init" as source. 868 (if class-only ;Help with class? Using "Init" as source.
871 (setq name "Init" 869 (setq name "Init"
872 type 'fun)) 870 type 'fun))
873 (if (not struct-tag) 871 (if (not struct-tag)
874 (setq file 872 (setq file
875 (idlwave-routine-source-file 873 (idlwave-routine-source-file
876 (nth 3 (idlwave-best-rinfo-assoc 874 (nth 3 (idlwave-best-rinfo-assoc
877 name (or type t) class (idlwave-routines)))))) 875 name (or type t) class (idlwave-routines))))))
878 (setq idlwave-help-def-pos nil 876 (setq idlwave-help-def-pos nil
881 idlwave-help-do-struct-tag nil 879 idlwave-help-do-struct-tag nil
882 idlwave-help-do-class-struct-tag nil) 880 idlwave-help-do-class-struct-tag nil)
883 (if (or struct-tag (stringp file)) 881 (if (or struct-tag (stringp file))
884 (progn 882 (progn
885 (setq in-buf ; structure-tag completion is always in current buffer 883 (setq in-buf ; structure-tag completion is always in current buffer
886 (if struct-tag 884 (if struct-tag
887 idlwave-current-tags-buffer 885 idlwave-current-tags-buffer
888 (idlwave-get-buffer-visiting file))) 886 (idlwave-get-buffer-visiting file)))
889 ;; see if file is in a visited buffer, insert those contents 887 ;; see if file is in a visited buffer, insert those contents
890 (if in-buf 888 (if in-buf
891 (progn 889 (progn
892 (setq file (buffer-file-name in-buf)) 890 (setq file (buffer-file-name in-buf))
893 (erase-buffer) 891 (erase-buffer)
894 (insert-buffer-substring in-buf)) 892 (insert-buffer-substring in-buf))
895 (if (file-exists-p file) ;; otherwise just load the file 893 (if (file-exists-p file) ;; otherwise just load the file
896 (progn 894 (progn
897 (erase-buffer) 895 (erase-buffer)
898 (insert-file-contents file nil nil nil 'replace)) 896 (insert-file-contents file nil nil nil 'replace))
904 (setq idlwave-help-mode-line-indicator file) 902 (setq idlwave-help-mode-line-indicator file)
905 903
906 ;; Try to find a good place to display 904 ;; Try to find a good place to display
907 (setq def-pos 905 (setq def-pos
908 ;; Find the class structure tag if that's what we're after 906 ;; Find the class structure tag if that's what we're after
909 (cond 907 (cond
910 ;; Class structure tags: find the class or named structure 908 ;; Class structure tags: find the class or named structure
911 ;; definition 909 ;; definition
912 (class-struct-tag 910 (class-struct-tag
913 (save-excursion 911 (save-excursion
914 (setq class 912 (setq class
915 (if (string-match "[a-zA-Z0-9]\\(__\\)" name) 913 (if (string-match "[a-zA-Z0-9]\\(__\\)" name)
916 (substring name 0 (match-beginning 1)) 914 (substring name 0 (match-beginning 1))
917 idlwave-current-tags-class)) 915 idlwave-current-tags-class))
918 (and 916 (and
919 (idlwave-find-class-definition class nil real-class) 917 (idlwave-find-class-definition class nil real-class)
920 (idlwave-find-struct-tag keyword)))) 918 (idlwave-find-struct-tag keyword))))
921 919
922 ;; Generic structure tags: the structure definition 920 ;; Generic structure tags: the structure definition
923 ;; location within the file has been recorded in 921 ;; location within the file has been recorded in
924 ;; `struct-tag' 922 ;; `struct-tag'
925 (struct-tag 923 (struct-tag
926 (save-excursion 924 (save-excursion
927 (and 925 (and
928 (integerp struct-tag) 926 (integerp struct-tag)
929 (goto-char struct-tag) 927 (goto-char struct-tag)
930 (idlwave-find-struct-tag keyword)))) 928 (idlwave-find-struct-tag keyword))))
931 929
932 ;; Just find the routine definition 930 ;; Just find the routine definition
933 (t 931 (t
934 (if class-only (point-min) 932 (if class-only (point-min)
935 (idlwave-help-find-routine-definition name type class keyword)))) 933 (idlwave-help-find-routine-definition name type class keyword))))
936 idlwave-help-def-pos def-pos) 934 idlwave-help-def-pos def-pos)
937 935
938 (if (and idlwave-help-source-try-header 936 (if (and idlwave-help-source-try-header
939 (not (or struct-tag class-struct-tag))) 937 (not (or struct-tag class-struct-tag)))
940 ;; Check if we can find the header 938 ;; Check if we can find the header
941 (save-excursion 939 (save-excursion
942 (goto-char (or def-pos (point-max))) 940 (goto-char (or def-pos (point-max)))
943 (setq header-pos (idlwave-help-find-in-doc-header 941 (setq header-pos (idlwave-help-find-in-doc-header
944 name type class keyword 'exact) 942 name type class keyword 'exact)
945 idlwave-help-in-header header-pos))) 943 idlwave-help-in-header header-pos)))
946 944
947 (if (or header-pos def-pos) 945 (if (or header-pos def-pos)
948 (progn 946 (progn
949 (if (boundp 'idlwave-help-min-frame-width) 947 (if (boundp 'idlwave-help-min-frame-width)
950 (setq idlwave-help-min-frame-width 80)) 948 (setq idlwave-help-min-frame-width 80))
951 (goto-char (or header-pos def-pos))) 949 (goto-char (or header-pos def-pos)))
952 (idlwave-help-error name type class keyword)) 950 (idlwave-help-error name type class keyword))
953 951
957 (defun idlwave-help-find-routine-definition (name type class keyword) 955 (defun idlwave-help-find-routine-definition (name type class keyword)
958 "Find the definition of routine CLASS::NAME in current buffer. 956 "Find the definition of routine CLASS::NAME in current buffer.
959 KEYWORD is ignored. Returns the point of match if successful, nil otherwise." 957 KEYWORD is ignored. Returns the point of match if successful, nil otherwise."
960 (save-excursion 958 (save-excursion
961 (goto-char (point-max)) 959 (goto-char (point-max))
962 (if (re-search-backward 960 (if (re-search-backward
963 (concat "^[ \t]*" 961 (concat "^[ \t]*"
964 (if (eq type 'pro) "pro" 962 (if (eq type 'pro) "pro"
965 (if (eq type 'fun) "function" 963 (if (eq type 'fun) "function"
966 "\\(pro\\|function\\)")) 964 "\\(pro\\|function\\)"))
967 "[ \t]+" 965 "[ \t]+"
1003 1001
1004 with spaces allowed between the keyword and the following dash or equal sign. 1002 with spaces allowed between the keyword and the following dash or equal sign.
1005 If there is a match, we assume it is the keyword description." 1003 If there is a match, we assume it is the keyword description."
1006 (let* ((case-fold-search t) 1004 (let* ((case-fold-search t)
1007 (rname (if (stringp class) 1005 (rname (if (stringp class)
1008 (concat 1006 (concat
1009 "\\(" 1007 "\\("
1010 ;; Traditional name or class::name 1008 ;; Traditional name or class::name
1011 "\\(" 1009 "\\("
1012 "\\(" (regexp-quote (downcase class)) "::\\)?" 1010 "\\(" (regexp-quote (downcase class)) "::\\)?"
1013 (regexp-quote (downcase name)) 1011 (regexp-quote (downcase name))
1014 "\\>\\)" 1012 "\\>\\)"
1015 (concat 1013 (concat
1016 "\\|" 1014 "\\|"
1017 ;; class__define or just class 1015 ;; class__define or just class
1018 (regexp-quote (downcase class)) "\\(__define\\)?") 1016 (regexp-quote (downcase class)) "\\(__define\\)?")
1019 "\\)") 1017 "\\)")
1020 (regexp-quote (downcase name)))) 1018 (regexp-quote (downcase name))))
1021 1019
1022 ;; NAME tag plus the routine name. The new version is from JD. 1020 ;; NAME tag plus the routine name. The new version is from JD.
1023 (name-re (concat 1021 (name-re (concat
1024 "\\(^;+\\*?[ \t]*" 1022 "\\(^;+\\*?[ \t]*"
1025 idlwave-help-doclib-name 1023 idlwave-help-doclib-name
1026 "\\([ \t]*:\\|[ \t]*$\\)[ \t]*\\(\n;+[ \t]*\\)*" 1024 "\\([ \t]*:\\|[ \t]*$\\)[ \t]*\\(\n;+[ \t]*\\)*"
1027 rname 1025 rname
1028 "\\|" 1026 "\\|"
1053 (concat 1051 (concat
1054 "^;+[ \t]+" 1052 "^;+[ \t]+"
1055 (regexp-quote (upcase keyword)) 1053 (regexp-quote (upcase keyword))
1056 "\\>"))) 1054 "\\>")))
1057 dstart dend name-pos kwds-pos kwd-pos) 1055 dstart dend name-pos kwds-pos kwd-pos)
1058 (catch 'exit 1056 (catch 'exit
1059 (save-excursion 1057 (save-excursion
1060 (goto-char (point-min)) 1058 (goto-char (point-min))
1061 (while (and (setq dstart (re-search-forward idlwave-doclib-start nil t)) 1059 (while (and (setq dstart (re-search-forward idlwave-doclib-start nil t))
1062 (setq dend (re-search-forward idlwave-doclib-end nil t))) 1060 (setq dend (re-search-forward idlwave-doclib-end nil t)))
1063 ;; found a routine header 1061 ;; found a routine header
1064 (goto-char dstart) 1062 (goto-char dstart)
1065 (if (setq name-pos (re-search-forward name-re dend t)) 1063 (if (setq name-pos (re-search-forward name-re dend t))
1066 (progn 1064 (progn
1067 (if keyword 1065 (if keyword
1068 ;; We do need a keyword 1066 ;; We do need a keyword
1069 (progn 1067 (progn
1070 ;; Try to find a keyword section, but don't force it. 1068 ;; Try to find a keyword section, but don't force it.
1071 (goto-char name-pos) 1069 (goto-char name-pos)
1143 (interactive "P") 1141 (interactive "P")
1144 (if arg 1142 (if arg
1145 (idlwave-help-find-first-header nil) 1143 (idlwave-help-find-first-header nil)
1146 (setq idlwave-help-in-header nil) 1144 (setq idlwave-help-in-header nil)
1147 (idlwave-help-toggle-header-match-and-def arg 'top))) 1145 (idlwave-help-toggle-header-match-and-def arg 'top)))
1148 1146
1149 (defun idlwave-help-toggle-header-match-and-def (arg &optional top) 1147 (defun idlwave-help-toggle-header-match-and-def (arg &optional top)
1150 (interactive "P") 1148 (interactive "P")
1151 (let ((args idlwave-help-args) 1149 (let ((args idlwave-help-args)
1152 pos) 1150 pos)
1153 (if idlwave-help-in-header 1151 (if idlwave-help-in-header
1155 (progn 1153 (progn
1156 (setq idlwave-help-in-header nil) 1154 (setq idlwave-help-in-header nil)
1157 (setq pos idlwave-help-def-pos)) 1155 (setq pos idlwave-help-def-pos))
1158 ;; Try to display header 1156 ;; Try to display header
1159 (setq pos (apply 'idlwave-help-find-in-doc-header 1157 (setq pos (apply 'idlwave-help-find-in-doc-header
1160 (if top 1158 (if top
1161 (list (car args) (nth 1 args) (nth 2 args) nil) 1159 (list (car args) (nth 1 args) (nth 2 args) nil)
1162 args))) 1160 args)))
1163 (if pos 1161 (if pos
1164 (setq idlwave-help-in-header t) 1162 (setq idlwave-help-in-header t)
1165 (error "Cannot find doclib header for routine %s" 1163 (error "Cannot find doclib header for routine %s"
1189 (set (make-local-variable 'font-lock-defaults) 1187 (set (make-local-variable 'font-lock-defaults)
1190 idlwave-font-lock-defaults) 1188 idlwave-font-lock-defaults)
1191 (font-lock-fontify-buffer)) 1189 (font-lock-fontify-buffer))
1192 (set-syntax-table syntax-table))))) 1190 (set-syntax-table syntax-table)))))
1193 1191
1194 1192
1195 (defun idlwave-help-error (name type class keyword) 1193 (defun idlwave-help-error (name type class keyword)
1196 (error "Can't find help on %s%s %s" 1194 (error "Can't find help on %s%s %s"
1197 (or (and (or class name) (idlwave-make-full-name class name)) 1195 (or (and (or class name) (idlwave-make-full-name class name))
1198 "<unknown>") 1196 "<unknown>")
1199 (if keyword (format ", keyword %s" (upcase keyword)) "") 1197 (if keyword (format ", keyword %s" (upcase keyword)) "")
1252 (defvar idlwave-help-assistant-socket nil) 1250 (defvar idlwave-help-assistant-socket nil)
1253 1251
1254 ;; The Windows version does not have a !DIR/bin/* set of front-end 1252 ;; The Windows version does not have a !DIR/bin/* set of front-end
1255 ;; scripts, but instead only links directly to bin.x86. As a result, 1253 ;; scripts, but instead only links directly to bin.x86. As a result,
1256 ;; we must pass the -profile argument as well. 1254 ;; we must pass the -profile argument as well.
1257 (defvar idlwave-help-assistant-command 1255 (defvar idlwave-help-assistant-command
1258 (if (memq system-type '(ms-dos windows-nt)) 1256 (if (memq system-type '(ms-dos windows-nt))
1259 "bin/bin.x86/idl_assistant.exe" 1257 "bin/bin.x86/idl_assistant.exe"
1260 "bin/idl_assistant") 1258 "bin/idl_assistant")
1261 "The command, rooted at idlwave-system-directory, which invokes the 1259 "The command, rooted at idlwave-system-directory, which invokes the
1262 IDL assistant.") 1260 IDL assistant.")
1276 "Start the IDL Assistant, loading link FULL-LINK, if passed." 1274 "Start the IDL Assistant, loading link FULL-LINK, if passed."
1277 (when (or (not idlwave-help-assistant-socket) 1275 (when (or (not idlwave-help-assistant-socket)
1278 (not (eq (process-status idlwave-help-assistant-socket) 'open))) 1276 (not (eq (process-status idlwave-help-assistant-socket) 'open)))
1279 (let* ((help-loc (idlwave-html-help-location)) 1277 (let* ((help-loc (idlwave-html-help-location))
1280 (command (idlwave-help-assistant-command)) 1278 (command (idlwave-help-assistant-command))
1281 (extra-args 1279 (extra-args
1282 (nconc 1280 (nconc
1283 (if (memq system-type '(ms-dos windows-nt)) 1281 (if (memq system-type '(ms-dos windows-nt))
1284 `("-profile" ,(expand-file-name "idl.adp" help-loc))) 1282 `("-profile" ,(expand-file-name "idl.adp" help-loc)))
1285 (if full-link `("-file" ,full-link)))) 1283 (if full-link `("-file" ,full-link))))
1286 port) 1284 port)
1287 (if idlwave-help-assistant-socket 1285 (if idlwave-help-assistant-socket
1288 (delete-process idlwave-help-assistant-socket)) 1286 (delete-process idlwave-help-assistant-socket))
1289 1287
1290 (setq idlwave-help-assistant-process 1288 (setq idlwave-help-assistant-process
1291 (apply 'start-process 1289 (apply 'start-process
1292 "IDL_ASSISTANT_PROC" nil command "-server" extra-args)) 1290 "IDL_ASSISTANT_PROC" nil command "-server" extra-args))
1293 1291
1294 (set-process-filter idlwave-help-assistant-process 1292 (set-process-filter idlwave-help-assistant-process
1295 (lambda (proc string) 1293 (lambda (proc string)
1296 (setq port (string-to-number string)))) 1294 (setq port (string-to-number string))))
1297 (unless (accept-process-output idlwave-help-assistant-process 15) 1295 (unless (accept-process-output idlwave-help-assistant-process 15)
1298 (error "Failed binding IDL_ASSISTANT socket")) 1296 (error "Failed binding IDL_ASSISTANT socket"))
1299 (if (not port) 1297 (if (not port)
1300 (error "Unable to open IDL_ASSISTANT.") 1298 (error "Unable to open IDL_ASSISTANT.")
1301 (set-process-filter idlwave-help-assistant-process nil) 1299 (set-process-filter idlwave-help-assistant-process nil)
1302 (setq idlwave-help-assistant-socket 1300 (setq idlwave-help-assistant-socket
1303 (open-network-stream "IDL_ASSISTANT_SOCK" 1301 (open-network-stream "IDL_ASSISTANT_SOCK"
1304 nil "localhost" port)) 1302 nil "localhost" port))
1305 (if (eq (process-status idlwave-help-assistant-socket) 'open) 1303 (if (eq (process-status idlwave-help-assistant-socket) 'open)
1306 (progn 1304 (progn
1307 (process-send-string idlwave-help-assistant-socket 1305 (process-send-string idlwave-help-assistant-socket
1308 (concat "setHelpPath " help-loc "\n")) 1306 (concat "setHelpPath " help-loc "\n"))
1316 1314
1317 (defun idlwave-help-assistant-open-link (&optional link) 1315 (defun idlwave-help-assistant-open-link (&optional link)
1318 ;; Open a link (file name with anchor, no leading path) in the assistant. 1316 ;; Open a link (file name with anchor, no leading path) in the assistant.
1319 (let ((help-loc (idlwave-html-help-location)) 1317 (let ((help-loc (idlwave-html-help-location))
1320 topic anchor file just-started exists full-link) 1318 topic anchor file just-started exists full-link)
1321 1319
1322 (if (string-match "\.html" link) 1320 (if (string-match "\.html" link)
1323 (setq topic (substring link 0 (match-beginning 0)) 1321 (setq topic (substring link 0 (match-beginning 0))
1324 anchor (substring link (match-end 0))) 1322 anchor (substring link (match-end 0)))
1325 (error "Malformed help link.")) 1323 (error "Malformed help link."))
1326 1324
1327 (setq file (expand-file-name (concat topic ".html") help-loc)) 1325 (setq file (expand-file-name (concat topic ".html") help-loc))
1328 (if (file-exists-p file) 1326 (if (file-exists-p file)
1329 (setq exists t) 1327 (setq exists t)
1330 (setq file (expand-file-name 1328 (setq file (expand-file-name
1331 (concat (upcase topic) ".html") help-loc)) 1329 (concat (upcase topic) ".html") help-loc))
1332 (setq exists (file-exists-p file))) 1330 (setq exists (file-exists-p file)))
1333 1331
1334 (setq full-link (concat file anchor) 1332 (setq full-link (concat file anchor)
1335 just-started (idlwave-help-assistant-start (if exists full-link))) 1333 just-started (idlwave-help-assistant-start (if exists full-link)))
1336 (if exists 1334 (if exists
1337 (progn 1335 (progn
1338 (if (not just-started) 1336 (if (not just-started)
1360 idlwave-system-routines) 1358 idlwave-system-routines)
1361 (mapcar (lambda (x) 1359 (mapcar (lambda (x)
1362 (concat "." (car x))) 1360 (concat "." (car x)))
1363 idlwave-executive-commands-alist) 1361 idlwave-executive-commands-alist)
1364 idlwave-system-class-info)) 1362 idlwave-system-class-info))
1365 (setq topic 1363 (setq topic
1366 (idlwave-completing-read 1364 (idlwave-completing-read
1367 "Help Topic: " list 1365 "Help Topic: " list
1368 nil nil nil 1366 nil nil nil
1369 'idlwave-help-assistant-help-with-topic-history))) 1367 'idlwave-help-assistant-help-with-topic-history)))
1370 (if (and topic (not (string= topic ""))) 1368 (if (and topic (not (string= topic "")))
1371 (idlwave-help-assistant-open-link (concat topic ".html"))))) 1369 (idlwave-help-assistant-open-link (concat topic ".html")))))
1372 1370
1373 (defun idlwave-help-assistant-close () 1371 (defun idlwave-help-assistant-close ()
1374 (when (and idlwave-help-assistant-process 1372 (when (and idlwave-help-assistant-process
1375 (eq (process-status idlwave-help-assistant-process) 'run)) 1373 (eq (process-status idlwave-help-assistant-process) 'run))
1376 (when idlwave-help-assistant-socket 1374 (when idlwave-help-assistant-socket
1377 (process-send-string idlwave-help-assistant-socket "quit\n") 1375 (process-send-string idlwave-help-assistant-socket "quit\n")