Skip to content

Commit

Permalink
Attempt to deal with "." and "->" Method invocation operator
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
JD Smith committed May 11, 2017
1 parent aed73d4 commit b0920b8
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 47 deletions.
9 changes: 7 additions & 2 deletions idlw-complete-structtag.el
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)))

Expand Down Expand Up @@ -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))
Expand Down
12 changes: 7 additions & 5 deletions idlw-complete.el
Original file line number Diff line number Diff line change
Expand Up @@ -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*"))
Expand All @@ -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))
Expand Down Expand Up @@ -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
Expand Down
23 changes: 12 additions & 11 deletions idlw-help.el
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
59 changes: 33 additions & 26 deletions idlw-routine.el
Original file line number Diff line number Diff line change
Expand Up @@ -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")))
Expand Down Expand Up @@ -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))
Expand All @@ -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)
Expand Down Expand Up @@ -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)))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion idlw-variables.el
Original file line number Diff line number Diff line change
Expand Up @@ -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 "::\\)?"
))

Expand Down
4 changes: 2 additions & 2 deletions idlwave.el
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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$]*\\(;.*\\)?$"))
Expand Down

0 comments on commit b0920b8

Please sign in to comment.