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.el150
1 files changed, 106 insertions, 44 deletions
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index c56759ebb9..466bf139b9 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -9,16 +9,17 @@
;;
;; Copyright Ericsson AB 1996-2014. All Rights Reserved.
;;
-;; The contents of this file are subject to the Erlang Public License,
-;; Version 1.1, (the "License"); you may not use this file except in
-;; compliance with the License. You should have received a copy of the
-;; Erlang Public License along with this software. If not, it can be
-;; retrieved online at http://www.erlang.org/.
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
;;
-;; Software distributed under the License is distributed on an "AS IS"
-;; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-;; the License for the specific language governing rights and limitations
-;; under the License.
+;; http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS,
+;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;; See the License for the specific language governing permissions and
+;; limitations under the License.
;;
;; %CopyrightEnd%
;;
@@ -880,10 +881,10 @@ resulting regexp is surrounded by \\_< and \\_>."
"dt_restore_tag"
"dt_spread_tag"
"dunlink"
+ "convert_time_unit"
"external_size"
"finish_after_on_load"
"finish_loading"
- "flush_monitor_message"
"format_cpu_topology"
"fun_info"
"fun_info_mfa"
@@ -913,6 +914,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"memory"
"module_info"
"monitor_node"
+ "monotonic_time"
"nif_error"
"phash"
"phash2"
@@ -946,13 +948,17 @@ resulting regexp is surrounded by \\_< and \\_>."
"system_info"
"system_monitor"
"system_profile"
+ "system_time"
"trace"
"trace_delivered"
"trace_info"
"trace_pattern"
+ "time_offset"
+ "timestamp"
"universaltime"
"universaltime_to_localtime"
"universaltime_to_posixtime"
+ "unique_integer"
"yield")
"Erlang built-in functions (BIFs) that needs erlang: prefix"))
@@ -2444,7 +2450,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 +2489,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 +2540,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 +2713,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 +4204,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)))
@@ -4217,7 +4236,7 @@ This function is designed to be a member of a criteria list."
This function is designed to be a member of a criteria list."
(save-excursion
(beginning-of-line)
- (when (save-match-data (looking-at "-\\(spec\\|type\\)"))
+ (when (save-match-data (looking-at "-\\(spec\\|type\\|callback\\)"))
'stop)))
@@ -4743,6 +4762,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 +4790,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 +4815,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 +4871,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 +4888,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))
;;;