aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tools/emacs/erlang.el
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tools/emacs/erlang.el')
-rw-r--r--lib/tools/emacs/erlang.el122
1 files changed, 89 insertions, 33 deletions
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index c56759ebb9..3610356355 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -2444,7 +2444,10 @@ This is automagically called by the user level function `indent-region'."
;; Parse the Erlang code from the beginning of the clause to
;; the beginning of the region.
(while (< (point) indent-point)
- (setq state (erlang-partial-parse (point) indent-point state)))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse pt indent-point state))
+ (if (= pt (point))
+ (error "Illegal syntax"))))
;; Indent every line in the region
(while continue
(goto-char indent-point)
@@ -2480,8 +2483,11 @@ This is automagically called by the user level function `indent-region'."
(if (>= from-end (- (point-max) indent-point))
(setq continue nil)
(while (< (point) indent-point)
- (setq state (erlang-partial-parse
- (point) indent-point state))))))))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse
+ pt indent-point state))
+ (if (= pt (point))
+ (error "Illegal syntax")))))))))
(defun erlang-indent-current-buffer ()
@@ -2528,7 +2534,10 @@ Return nil if line starts inside string, t if in a comment."
(goto-char parse-start)
(erlang-beginning-of-clause))
(while (< (point) indent-point)
- (setq state (erlang-partial-parse (point) indent-point state)))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse pt indent-point state))
+ (if (= pt (point))
+ (error "Illegal syntax"))))
(erlang-calculate-stack-indent indent-point state))))
(defun erlang-show-syntactic-information ()
@@ -2698,12 +2707,13 @@ Value is list (stack token-start token-type in-what)."
(erlang-push (list '|| token (current-column)) stack)
(forward-char 2))
- ;; Bit-syntax open paren
- ((looking-at "<<")
+ ;; Bit-syntax open. Note that map syntax allows "<<" to follow ":="
+ ;; or "=>" without intervening whitespace, so handle that case here
+ ((looking-at "\\(:=\\|=>\\)?<<")
(erlang-push (list '<< token (current-column)) stack)
- (forward-char 2))
+ (forward-char (- (match-end 0) (match-beginning 0))))
- ;; Bbit-syntax close paren
+ ;; Bit-syntax close
((looking-at ">>")
(while (memq (car (car stack)) '(|| ->))
(erlang-pop stack))
@@ -4188,7 +4198,10 @@ This function is designed to be a member of a criteria list."
;; Do not return `stop' when inside a list comprehension
;; construction. (The point must be after `||').
(while (< (point) orig-point)
- (setq state (erlang-partial-parse (point) orig-point state)))
+ (let ((pt (point)))
+ (setq state (erlang-partial-parse pt orig-point state))
+ (if (= pt (point))
+ (error "Illegal syntax"))))
(if (and (car state) (eq (car (car (car state))) '||))
nil
'stop)))
@@ -4743,6 +4756,23 @@ for a tag on the form `module:tag'."
;;; `module:tag'.
+(when (and (fboundp 'etags-tags-completion-table)
+ (fboundp 'tags-lazy-completion-table)) ; Emacs 23.1+
+ (if (fboundp 'advice-add)
+ ;; Emacs 24.4+
+ (advice-add 'etags-tags-completion-table :around
+ (lambda (oldfun)
+ (if (eq find-tag-default-function 'erlang-find-tag-for-completion)
+ (erlang-etags-tags-completion-table)
+ (funcall oldfun)))
+ (list :name 'erlang-replace-tags-table))
+ ;; Emacs 23.1-24.3
+ (defadvice etags-tags-completion-table (around erlang-replace-tags-table activate)
+ (if (eq find-tag-default-function 'erlang-find-tag-for-completion)
+ (setq ad-return-value (erlang-etags-tags-completion-table))
+ ad-do-it))))
+
+
(defun erlang-complete-tag ()
"Perform tags completion on the text around point.
Completes to the set of names listed in the current tags table.
@@ -4754,7 +4784,17 @@ about Erlang modules."
(require 'etags)
(error nil))
(cond ((and erlang-tags-installed
- (fboundp 'complete-tag)) ; Emacs 19
+ (fboundp 'etags-tags-completion-table)
+ (fboundp 'tags-lazy-completion-table)) ; Emacs 23.1+
+ ;; This depends on the advice called erlang-replace-tags-table
+ ;; above. It is not enough to let-bind
+ ;; tags-completion-table-function since that will not override
+ ;; the buffer-local value in the TAGS buffer.
+ (let ((find-tag-default-function 'erlang-find-tag-for-completion))
+ (complete-tag)))
+ ((and erlang-tags-installed
+ (fboundp 'complete-tag)
+ (fboundp 'tags-complete-tag)) ; Emacs 19
(let ((orig-tags-complete-tag (symbol-function 'tags-complete-tag)))
(fset 'tags-complete-tag
(symbol-function 'erlang-tags-complete-tag))
@@ -4769,6 +4809,15 @@ about Erlang modules."
(error "This version of Emacs can't complete tags"))))
+(defun erlang-find-tag-for-completion ()
+ (let ((start (save-excursion
+ (skip-chars-backward "[:word:][:digit:]_:'")
+ (point))))
+ (unless (eq start (point))
+ (buffer-substring-no-properties start (point)))))
+
+
+
;; Based on `tags-complete-tag', but this one uses
;; `erlang-tags-completion-table' instead of `tags-completion-table'.
;;
@@ -4816,7 +4865,12 @@ about Erlang modules."
;; the only format supported by Emacs, so far.)
(defun erlang-etags-tags-completion-table ()
(let ((table (make-vector 511 0))
- (file nil))
+ (file nil)
+ (progress-reporter
+ (when (fboundp 'make-progress-reporter)
+ (make-progress-reporter
+ (format "Making erlang tags completion table for %s..." buffer-file-name)
+ (point-min) (point-max)))))
(save-excursion
(goto-char (point-min))
;; This monster regexp matches an etags tag line.
@@ -4828,31 +4882,33 @@ about Erlang modules."
;; \6 is the line to start searching at;
;; \7 is the char to start searching at.
(while (progn
- (while (and
- (eq (following-char) ?\f)
- (looking-at "\f\n\\([^,\n]*\\),.*\n"))
- (setq file (buffer-substring
- (match-beginning 1) (match-end 1)))
- (goto-char (match-end 0)))
- (re-search-forward
- "\
+ (while (and
+ (eq (following-char) ?\f)
+ (looking-at "\f\n\\([^,\n]*\\),.*\n"))
+ (setq file (buffer-substring
+ (match-beginning 1) (match-end 1)))
+ (goto-char (match-end 0)))
+ (re-search-forward
+ "\
^\\(\\([^\177]+[^-a-zA-Z0-9_$\177]+\\)?\\([-a-zA-Z0-9_$?:]+\\)\
\[^-a-zA-Z0-9_$?:\177]*\\)\177\\(\\([^\n\001]+\\)\001\\)?\
\\([0-9]+\\)?,\\([0-9]+\\)?\n"
- nil t))
- (let ((tag (if (match-beginning 5)
- ;; There is an explicit tag name.
- (buffer-substring (match-beginning 5) (match-end 5))
- ;; No explicit tag name. Best guess.
- (buffer-substring (match-beginning 3) (match-end 3))))
- (module (and file
- (erlang-get-module-from-file-name file))))
- (intern tag table)
- (if (stringp module)
- (progn
- (intern (concat module ":" tag) table)
- ;; Only the first one will be stored in the table.
- (intern (concat module ":") table))))))
+ nil t))
+ (let ((tag (if (match-beginning 5)
+ ;; There is an explicit tag name.
+ (buffer-substring (match-beginning 5) (match-end 5))
+ ;; No explicit tag name. Best guess.
+ (buffer-substring (match-beginning 3) (match-end 3))))
+ (module (and file
+ (erlang-get-module-from-file-name file))))
+ (intern tag table)
+ (when (stringp module)
+ (intern (concat module ":" tag) table)
+ ;; Only the first ones will be stored in the table.
+ (intern (concat module ":") table)
+ (intern (concat module ":module_info") table))
+ (when progress-reporter
+ (progress-reporter-update progress-reporter (point))))))
table))
;;;