branch: externals/idlwave commit b0920b8d8ac275f01cc925ab45364a72c85091f9 Author: JD Smith <jdsm...@rain.mhr.utoledo.edu> Commit: JD Smith <jdsm...@rain.mhr.utoledo.edu>
Attempt to deal with "." and "->" Method invocation operator IDL8 introduced obj.Method syntax. This shadows structure dereference. Now try both file-local structure tags or shell-determined tags (e.g. self tags, or widget_info tags, etc.) and if that fails, fall back on method lookup (procedure or function). Probably some corner cases that need visiting. --- idlw-complete-structtag.el | 9 +++++-- idlw-complete.el | 12 ++++++---- idlw-help.el | 23 +++++++++--------- idlw-routine.el | 59 ++++++++++++++++++++++++++-------------------- idlw-variables.el | 2 +- idlwave.el | 4 ++-- 6 files changed, 62 insertions(+), 47 deletions(-) diff --git a/idlw-complete-structtag.el b/idlw-complete-structtag.el index d719060c42..b3699091f9 100644 --- a/idlw-complete-structtag.el +++ b/idlw-complete-structtag.el @@ -24,6 +24,11 @@ ;;; Commentary: +;; NOTA BENE!!! As of IDL v8, a method invocation operator of "." was +;; introduced (in addition to "->"). As a result, it is no longer +;; clear if you are completing an implicit structure tag, or a +;; method procedure. + ;; Completion of structure tags can be done automatically in the ;; shell, since the list of tags can be determined dynamically through ;; interaction with IDL. @@ -102,7 +107,7 @@ (defvar idlwave-current-struct-tags nil) (defvar idlwave-sint-structtags nil) -;; Create the sintern type for structure talks +;; Create the sintern type for structure tags (add-hook 'idlwave-load-hook (lambda () (idlwave-new-sintern-type 'structtag))) @@ -147,7 +152,7 @@ an up-to-date completion list." (if (or (not (string= var (or idlwave-current-tags-var "@"))) (not (eq (current-buffer) idlwave-current-tags-buffer)) (not (equal start idlwave-current-tags-completion-pos))) - (idlwave-prepare-structure-tag-completion var )) + (idlwave-prepare-structure-tag-completion var)) (setq idlwave-current-tags-completion-pos start) (setq idlwave-completion-help-info (list 'idlwave-complete-structure-tag-help)) diff --git a/idlw-complete.el b/idlw-complete.el index d512be1028..6db531d9d1 100644 --- a/idlw-complete.el +++ b/idlw-complete.el @@ -110,7 +110,7 @@ When we force a method or a method keyword, CLASS can specify the class." module (substring module (match-end 0)))) (cond - + ;; Just scroll the completions list on repeat commands ((and (null arg) (eq (car-safe last-command) 'idlwave-display-completion-list) (get-buffer-window "*Completions*")) @@ -124,12 +124,14 @@ When we force a method or a method keyword, CLASS can specify the class." ;; Check for any special completion functions ((and idlwave-complete-special - (idlwave-call-special idlwave-complete-special))) - + (condition-case nil + (idlwave-call-special idlwave-complete-special) + (error nil)))) + ((null what) (error "Nothing to complete here")) - ;; Complete a class + ;; Complete a class name ((eq what 'class) (setq idlwave-completion-help-info '(class)) (idlwave-complete-class)) @@ -182,7 +184,7 @@ When we force a method or a method keyword, CLASS can specify the class." ((and (memq what '(procedure-keyword function-keyword)) ; Special Case (equal arg '(4))) - (idlwave-complete 3)) + (idlwave-complete 3)) ;force function completion ((eq what 'procedure-keyword) ;; Complete a procedure keyword diff --git a/idlw-help.el b/idlw-help.el index 3fd1dcab8f..4ebf1b713a 100644 --- a/idlw-help.el +++ b/idlw-help.el @@ -165,9 +165,8 @@ It collects and prints the diagnostics messages." module keyword cw mod1 mod2 mod3) (if (or arg (and (not classtag) - (not structtag) - (not (member (string-to-char this-word) '(?! ?.))))) - ;; Need the module information + (not (member (string-to-char this-word) '(?!))))) + ;; Get the module information (progn ;; MODULE is (name type class), for this or any inheriting class (setq module (idlwave-what-module-find-class) @@ -251,14 +250,16 @@ It collects and prints the diagnostics messages." ;; A regular structure tag -- only in text, and if ;; `complete-structtag' loaded. - (structtag - (let ((var (match-string 1 this-word)) - (tag (substring this-word (match-end 0)))) - ;; Check if we need to update the "current" structure - (idlwave-prepare-structure-tag-completion var) - (setq idlwave-help-do-struct-tag - idlwave-structtag-struct-location - mod1 (list nil nil nil nil tag)))) + ((and structtag + (let ((var (match-string 1 this-word)) + (tag (substring this-word (match-end 0)))) + ;; Check if we need to update the "current" structure + (condition-case nil + (idlwave-prepare-structure-tag-completion var) + (error nil)))) + (setq idlwave-help-do-struct-tag + idlwave-structtag-struct-location + mod1 (list nil nil nil nil tag))) ;; A routine keyword -- in text or system help ((and (memq cw '(function-keyword procedure-keyword)) diff --git a/idlw-routine.el b/idlw-routine.el index 3ba32f825e..7ea2881862 100644 --- a/idlw-routine.el +++ b/idlw-routine.el @@ -45,17 +45,18 @@ this arrow, if any (see `idlwave-store-inquired-class'). With a prefix arg, the class property is cleared out." (interactive "P") (idlwave-routines) - (if (string-match "->" (buffer-substring - (max (point-min) (1- (point))) - (min (+ 2 (point)) (point-max)))) - ;; Cursor is on an arrow + (if (or (string-match "->" (buffer-substring + (max (point-min) (1- (point))) + (min (+ 2 (point)) (point-max)))) + (looking-at "\\.")) + ;; Cursor is on an arrow/dot (if (get-text-property (point) 'idlwave-class) ;; arrow has class property (if arg ;; Remove property (save-excursion (backward-char 1) - (when (looking-at ".?\\(->\\)") + (when (looking-at ".?\\(->\\|\\.\\)") (remove-text-properties (match-beginning 1) (match-end 1) '(idlwave-class nil face nil)) (message "Class property removed from arrow"))) @@ -527,7 +528,7 @@ When TYPE is not specified, both procedures and functions will be considered." ;; this structure is the class. When nil, we return nil. When t, ;; try to get the class from text properties at the method call ;; arrow. When the object is "self", we use the class of the - ;; current (enclosing) routine. otherwise prompt the user for a + ;; current (enclosing) routine. Otherwise, we prompt the user for a ;; class name. Also stores the selected class as a text property at ;; the arrow. TYPE is 'fun or 'pro. (let* ((class (nth 2 cw-list)) @@ -541,7 +542,13 @@ When TYPE is not specified, both procedures and functions will be considered." (query (cond (nassoc (cdr nassoc)) (dassoc (cdr dassoc)) (t t))) - (arrow (and apos (string= (buffer-substring apos (+ 2 apos)) "->"))) + arrow-len + (arrow (and apos (or (and (string= (buffer-substring apos (min (point-max) + (+ 2 apos))) "->") + (setq arrow-len 2)) + (and (string= (buffer-substring apos (min (point-max) + (+ 1 apos))) ".") + (setq arrow-len 1))))) (is-self (and arrow (save-excursion (goto-char apos) @@ -599,7 +606,7 @@ When TYPE is not specified, both procedures and functions will be considered." (when (and store arrow) (condition-case () (add-text-properties - apos (+ apos 2) + apos (+ apos arrow-len) `(idlwave-class ,class face ,idlwave-class-arrow-face rear-nonsticky t)) (error nil))) @@ -676,7 +683,7 @@ ARROW: Location of the arrow for method calls" cw-point pro-point cw-arrow pro-arrow)) - ;; Complete class inside obj_new statement + ;; Complete class name inside obj_new statement ((string-match "OBJ_NEW([ \t]*['\"]\\([a-zA-Z0-9$_]*\\)?\\'" match-string) (setq cw 'class)) @@ -714,7 +721,7 @@ ARROW: Location of the arrow for method calls" (t (setq cw 'function) (save-excursion - (if (re-search-backward "->[ \t]*\\(\\$[ \t]*\\(;.*\\)?\n\\s-*\\)?\\(\\([$a-zA-Z0-9_]+\\)::\\)?[$a-zA-Z0-9_]*\\=" bos t) + (if (re-search-backward "\\(->\\|\\.\\)[ \t]*\\(\\$[ \t]*\\(;.*\\)?\n\\s-*\\)?\\(\\([$a-zA-Z0-9_]+\\)::\\)?[$a-zA-Z0-9_]*\\=" bos t) (setq cw-arrow (copy-marker (match-beginning 0)) cw-class (if (match-end 4) (idlwave-sintern-class (match-string 4)) @@ -751,13 +758,13 @@ ARROW: Location of the arrow for method calls" (incf cnt) (when (and (= (following-char) ?\() (re-search-backward - "\\(::\\|\\<\\)\\([a-zA-Z][a-zA-Z0-9$_]*\\)[ \t]*\\=" + "\\(::\\|\\<\\|\\.\\)\\([a-zA-Z][a-zA-Z0-9$_]*\\)[ \t]*\\=" bound t)) (setq func (match-string 2) func-point (goto-char (match-beginning 2)) pos func-point) (if (re-search-backward - "->[ \t]*\\(\\([a-zA-Z][a-zA-Z0-9$_]*\\)::\\)?\\=" bound t) + "\\(->\\|\\.\\)[ \t]*\\(\\([a-zA-Z][a-zA-Z0-9$_]*\\)::\\)?\\=" bound t) (setq arrow-start (copy-marker (match-beginning 0)) class (or (match-string 2) t))) (throw @@ -788,7 +795,7 @@ ARROW: Location of the arrow for method calls" (if (and (idlwave-skip-object) (setq string (buffer-substring (point) pos)) (string-match - "\\`[ \t]*\\(->\\)[ \t]*\\(\\([a-zA-Z][a-zA-Z0-9$_]*\\)::\\)?\\([a-zA-Z][a-zA-Z0-9$_]*\\)?[ \t]*\\(,\\|\\(\\$\\s *\\(;.*\\)?\\)?$\\)" + "\\`[ \t]*\\(->\\|\\.\\)[ \t]*\\(\\([a-zA-Z][a-zA-Z0-9$_]*\\)::\\)?\\([a-zA-Z][a-zA-Z0-9$_]*\\)?[ \t]*\\(,\\|\\(\\$\\s *\\(;.*\\)?\\)?$\\)" string)) (setq pro (if (match-beginning 4) (match-string 4 string)) @@ -815,19 +822,19 @@ ARROW: Location of the arrow for method calls" ((eq (following-char) ?\() nil) (t (throw 'exit nil))) - (catch 'endwhile - (while t - (cond ((eq (following-char) ?.) - (forward-char 1) - (if (not (looking-at idlwave-identifier)) - (throw 'exit nil)) - (goto-char (match-end 0))) - ((memq (following-char) '(?\( ?\[)) - (condition-case nil - (forward-list 1) - (error (throw 'exit nil)))) - (t (throw 'endwhile t))))) - (if (looking-at "[ \t]*->") + ;; (catch 'endwhile ; Can't skip dots anymore, they are used for method invocation! + ;; (while t + ;; (cond ((eq (following-char) ?.) + ;; (forward-char 1) + ;; (if (not (looking-at idlwave-identifier)) + ;; (throw 'exit nil)) + ;; (goto-char (match-end 0))) + ;; ((memq (following-char) '(?\( ?\[)) + ;; (condition-case nil + ;; (forward-list 1) + ;; (error (throw 'exit nil)))) + ;; (t (throw 'endwhile t))))) + (if (looking-at "[ \t]*\\(->\\|\\.\\)") (throw 'exit (setq pos (match-beginning 0))) (throw 'exit nil)))) (goto-char pos) diff --git a/idlw-variables.el b/idlw-variables.el index d54ac3bbcc..6f6114b27f 100644 --- a/idlw-variables.el +++ b/idlw-variables.el @@ -1286,7 +1286,7 @@ blocks starting with a BEGIN statement. The matches must have associations (defconst idlwave-label (concat idlwave-identifier ":") "Regular expression matching IDL labels.") -(defconst idlwave-method-call (concat idlwave-identifier "\\s *->" +(defconst idlwave-method-call (concat idlwave-identifier "\\s *\\(->\\|\\.\\)" "\\(\\s *" idlwave-identifier "::\\)?" )) diff --git a/idlwave.el b/idlwave.el index 55e28c637b..face890f91 100644 --- a/idlwave.el +++ b/idlwave.el @@ -1336,7 +1336,7 @@ INFO is as returned by `idlwave-what-function' or `-procedure'." (let ((apos (nth 3 info))) (if apos (save-excursion (goto-char apos) - (looking-at "->[a-zA-Z][a-zA-Z0-9$_]*::"))))) + (looking-at "\\(->|\\.\\)[a-zA-Z][a-zA-Z0-9$_]*::"))))) ;;---------------------------------------------------- ;; Indent and indent action @@ -1715,7 +1715,7 @@ routine definitions, and parenthetical groupings, are treated separately." ;; A continued Procedure call or definition ((progn (idlwave-look-at "^[ \t]*\\(pro\\|function\\)") ;skip over - (looking-at "[ \t]*\\([a-zA-Z0-9.$_]+[ \t]*->[ \t]*\\)?[a-zA-Z][:a-zA-Z0-9$_]*[ \t]*\\(,\\)[ \t]*")) + (looking-at "[ \t]*\\([a-zA-Z0-9.$_]+[ \t]*\\(->|\\.\\)[ \t]*\\)?[a-zA-Z][:a-zA-Z0-9$_]*[ \t]*\\(,\\)[ \t]*")) (goto-char (match-end 0)) ;; Comment only, or blank line with "$"? Basic indent. (if (save-match-data (looking-at "[ \t$]*\\(;.*\\)?$"))