branch: externals/idlwave
commit b0920b8d8ac275f01cc925ab45364a72c85091f9
Author: JD Smith <[email protected]>
Commit: JD Smith <[email protected]>
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$]*\\(;.*\\)?$"))