aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tools')
-rw-r--r--lib/tools/doc/src/erlang_mode.xml9
-rw-r--r--lib/tools/doc/src/notes.xml98
-rw-r--r--lib/tools/doc/src/xref_chapter.xml6
-rw-r--r--lib/tools/emacs/Makefile2
-rw-r--r--lib/tools/emacs/erlang-edoc.el172
-rw-r--r--lib/tools/emacs/erlang-skels.el169
-rw-r--r--lib/tools/emacs/erlang-start.el15
-rw-r--r--lib/tools/emacs/erlang-test.el106
-rw-r--r--lib/tools/emacs/erlang.el3636
-rw-r--r--lib/tools/emacs/erldoc.el508
-rw-r--r--lib/tools/emacs/test.erl.indented810
-rw-r--r--lib/tools/emacs/test.erl.orig210
-rw-r--r--lib/tools/examples/xref_examples.erl2
-rw-r--r--lib/tools/src/fprof.erl17
-rw-r--r--lib/tools/src/make.erl2
-rw-r--r--lib/tools/src/tags.erl2
-rw-r--r--lib/tools/src/tools.app.src4
-rw-r--r--lib/tools/src/xref_base.erl4
-rw-r--r--lib/tools/test/cover_SUITE.erl33
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f1.erl15
-rw-r--r--lib/tools/test/cover_SUITE_data/otp_6115/f2.erl14
-rw-r--r--lib/tools/test/make_SUITE_data/test1.erl2
-rw-r--r--lib/tools/test/xref_SUITE.erl17
-rw-r--r--lib/tools/vsn.mk2
24 files changed, 3422 insertions, 2433 deletions
diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml
index 00cf5196b4..7fef74813b 100644
--- a/lib/tools/doc/src/erlang_mode.xml
+++ b/lib/tools/doc/src/erlang_mode.xml
@@ -252,7 +252,14 @@
behavior</item>
<item>gen_event - skeleton for the OTP gen_event behavior</item>
<item>gen_fsm - skeleton for the OTP gen_fsm behavior</item>
- <item>gen_statem - skeleton for the OTP gen_statem behavior</item>
+ <item>
+ gen_statem (StateName/3) - skeleton for the OTP gen_statem behavior
+ using state name functions
+ </item>
+ <item>
+ gen_statem (handle_event/4) - skeleton for the OTP gen_statem behavior
+ using one state function
+ </item>
<item>Library module - skeleton for a module that does not
implement a process.</item>
<item>Corba callback - skeleton for a Corba callback module.</item>
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 0b8a2be715..af20200d49 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -31,6 +31,104 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.9.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved edoc support in emacs mode.</p>
+ <p>
+ Own Id: OTP-14217 Aux Id: PR-1282 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix unhandled trace event send_to_non_existing_process in
+ fprof.</p>
+ <p>
+ Own Id: OTP-13998</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved edoc support in emacs erlang-mode.</p>
+ <p>
+ Own Id: OTP-13945 Aux Id: PR-1157 </p>
+ </item>
+ <item>
+ <p>
+ Added erldoc to emacs mode which opens html documentation
+ in browser from emacs. For example <c>M-x erldoc-browse
+ RET lists:foreach/2</c>.</p>
+ <p>
+ Own Id: OTP-14018 Aux Id: PR-1197 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.8.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Errors in type specification and Emacs template
+ generation for <c>gen_statem:code_change/4</c> has been
+ fixed from bugs.erlang.org's Jira cases ERL-172 and
+ ERL-187.</p>
+ <p>
+ Own Id: OTP-13746 Aux Id: ERL-172, ERL-187 </p>
+ </item>
+ <item>
+ <p>
+ Fix gc_start/gc_end in fprof tags when parsing old trace
+ logs.</p>
+ <p>
+ Own Id: OTP-13778 Aux Id: PR-1136 </p>
+ </item>
+ <item>
+ <p><c>make</c> (tools) and <c>ct_make</c> (common_test)
+ would crash if an Erlang source file contained a
+ <c>-warning()</c> directive.</p>
+ <p>
+ Own Id: OTP-13855</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.8.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Correct a bug when adding multiple modules to an Xref
+ server. The bug was introduced in OTP-19.0. </p>
+ <p>
+ Own Id: OTP-13708 Aux Id: ERL-173 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.8.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/doc/src/xref_chapter.xml b/lib/tools/doc/src/xref_chapter.xml
index 8b14e03064..872793bdcb 100644
--- a/lib/tools/doc/src/xref_chapter.xml
+++ b/lib/tools/doc/src/xref_chapter.xml
@@ -234,7 +234,7 @@
operand of the intersection operator <c>*</c> is implicitly
converted to the more special type of the second operand.</item>
<tag><c>xref:q(s, "(Mod) tools").</c></tag>
- <item>All modules of the <c>tools</c> application.</item>
+ <item>All modules of the Tools application.</item>
<tag><c>xref:q(s, '"xref_.*" : Mod').</c></tag>
<item>All modules with a name beginning with <c>xref_</c>.</item>
<tag><c>xref:q(s, "# E&nbsp;|&nbsp;X&nbsp;").</c></tag>
@@ -252,9 +252,9 @@
<tag><c>xref:q(s, "XC * (ME - strict ME)").</c></tag>
<item>External calls within some module.</item>
<tag><c>xref:q(s, "E&nbsp;|||&nbsp;kernel").</c></tag>
- <item>All calls within the <c>kernel</c> application. </item>
+ <item>All calls within the Kernel application. </item>
<tag><c>xref:q(s, "closure&nbsp;E&nbsp;|&nbsp;kernel&nbsp;||&nbsp;kernel").</c></tag>
- <item>All direct and indirect calls within the <c>kernel</c>
+ <item>All direct and indirect calls within the Kernel
application. Both the calling and the used functions of
indirect calls are defined in modules of the kernel
application, but it is possible that some functions outside
diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile
index 585425e5f1..35c93ba4ed 100644
--- a/lib/tools/emacs/Makefile
+++ b/lib/tools/emacs/Makefile
@@ -38,11 +38,13 @@ MAN_FILES= \
tags.3
EMACS_FILES= \
+ erldoc \
erlang-skels \
erlang-skels-old \
erlang_appwiz \
erlang-start \
erlang-eunit \
+ erlang-edoc \
erlang-flymake \
erlang
diff --git a/lib/tools/emacs/erlang-edoc.el b/lib/tools/emacs/erlang-edoc.el
new file mode 100644
index 0000000000..241590b850
--- /dev/null
+++ b/lib/tools/emacs/erlang-edoc.el
@@ -0,0 +1,172 @@
+;;; erlang-edoc.el --- EDoc support for Erlang mode -*- lexical-binding: t; -*-
+
+;; %CopyrightBegin%
+;;
+;; Copyright Ericsson AB 1996-2016. All Rights Reserved.
+;;
+;; 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
+;;
+;; 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%
+
+;;; Commentary:
+
+;; Ref: http://www.erlang.org/doc/apps/edoc/users_guide.html
+;;
+;; To use: (add-hook 'erlang-mode-hook 'erlang-edoc-mode)
+
+;;; Code:
+
+(defcustom erlang-edoc-indent-level 2
+ "Indentation level of xhtml in Erlang edoc."
+ :safe 'integerp
+ :group 'erlang)
+
+(defvar erlang-edoc-generic-tags
+ '("clear" "docfile" "end" "headerfile" "todo" "TODO" "type")
+ "Tags that can be used anywhere within a module.")
+
+(defvar erlang-edoc-overview-tags
+ '("author" "copyright" "doc" "reference" "see" "since" "title" "version")
+ "Tags that can be used in an overview file.")
+
+(defvar erlang-edoc-module-tags
+ '("author" "copyright" "deprecated" "doc" "hidden" "private" "reference"
+ "see" "since" "version")
+ "Tags that can be used before a module declaration.")
+
+(defvar erlang-edoc-function-tags
+ '("deprecated" "doc" "equiv" "hidden" "param" "private" "returns"
+ "see" "since" "spec" "throws" "type")
+ "Tags that can be used before a function definition.")
+
+(defvar erlang-edoc-predefined-macros
+ '("date" "docRoot" "link" "module" "package" "section" "time"
+ "type" "version"))
+
+(defface erlang-edoc-tag '((t (:inherit font-lock-constant-face)))
+ "Face used to highlight edoc tags."
+ :group 'erlang)
+
+(defface erlang-edoc-macro '((t (:inherit font-lock-preprocessor-face)))
+ "Face used to highlight edoc macros."
+ :group 'erlang)
+
+(defface erlang-edoc-verbatim
+ '((t (:family "Monospace" :inherit font-lock-keyword-face)))
+ "Face used to highlight verbatim text."
+ :group 'erlang)
+
+(defface erlang-edoc-todo '((t (:inherit font-lock-warning-face)))
+ "Face used to highlight edoc macros."
+ :group 'erlang)
+
+(defface erlang-edoc-heading '((t (:inherit bold)))
+ "Face used to highlight edoc headings."
+ :group 'erlang)
+
+(defvar erlang-edoc-font-lock-keywords
+ '(("^%+\\s-*\\(@\\w+\\)\\_>" 1 'erlang-edoc-tag prepend)
+ ("^%+\\s-*" ("{\\(@\\w+\\)\\_>" nil nil (1 'erlang-edoc-macro prepend)))
+ ("^%+\\s-*" ("\\(?:@@\\)*\\(@[@{}]\\)" nil nil (1 'escape-glyph prepend)))
+ ("^%+\\s-*\\(@deprecated\\)\\_>" 1 font-lock-warning-face prepend)
+ ;; http://www.erlang.org/doc/apps/edoc/chapter.html#Wiki_notation
+ ("^%+\\s-*" ("[^`]`\\([^`]?\\|[^`].*?[^']\\)'"
+ (forward-char -1) nil (1 'erlang-edoc-verbatim prepend)))
+ ("^%+\\s-*" ("\\[\\(\\(?:https?\\|file\\|ftp\\)://[^][]+\\)\\]"
+ nil nil (1 'link prepend)))
+ ("^%+\\s-*\\(?:\\(?1:@todo\\|@TODO\\)\\_>\\|\\(?1:TODO\\):\\)"
+ 1 'erlang-edoc-todo prepend)
+ ("^%+\\s-*\\(\\(=\\{2,4\\}\\)[^=\n].*[^=\n]\\2\\)\\s-*$"
+ 1 'erlang-edoc-heading prepend)))
+
+(defun erlang-edoc-xml-context ()
+ "Parse edoc x(ht)ml context at comment start of current line."
+ (eval-and-compile (require 'xmltok))
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at "^%+\\s-*")
+ (let ((pt (match-end 0)) context)
+ (forward-comment (- (point)))
+ (while (< (point) pt)
+ (xmltok-forward)
+ (cond ((eq xmltok-type 'start-tag)
+ (push (cons xmltok-type xmltok-start) context))
+ ((eq xmltok-type 'end-tag)
+ (pop context))))
+ (goto-char pt)
+ (xmltok-forward)
+ (push (car (memq xmltok-type '(start-tag end-tag))) context)
+ context))))
+
+(defun erlang-edoc-indent-line ()
+ (let ((context (erlang-edoc-xml-context)))
+ (when context
+ (save-excursion
+ (beginning-of-line)
+ (re-search-forward "^%+\\s-*" (line-end-position))
+ (when (or (car context) (cadr context))
+ (let ((pad (when (cadr context)
+ (save-excursion
+ (goto-char (cdr (cadr context)))
+ (- (current-column)
+ (progn
+ (beginning-of-line)
+ (skip-chars-forward "%")
+ (current-column)))))))
+ (just-one-space (cond ((not pad) 1)
+ ((eq (car context) 'end-tag) pad)
+ (t (+ erlang-edoc-indent-level pad)))))))
+ (when (looking-back "^%*\\s-*" (line-beginning-position))
+ (re-search-forward "\\=%*\\s-*")))))
+
+(defun erlang-edoc-before-module-declaration-p ()
+ (save-excursion
+ (beginning-of-line)
+ (forward-comment (point-max))
+ (or (eobp) (re-search-forward "^-module\\s-*(" nil t))))
+
+(defun erlang-edoc-completion-at-point ()
+ (when (eq (syntax-ppss-context (syntax-ppss)) 'comment)
+ (save-excursion
+ (skip-syntax-backward "w_")
+ (when (= (preceding-char) ?@)
+ (let* ((is-tag (looking-back "^%+\\s-*@" (line-beginning-position)))
+ (beg (point))
+ (end (progn (skip-syntax-forward "w_") (point)))
+ (table (cond
+ ((not is-tag)
+ erlang-edoc-predefined-macros)
+ ((erlang-edoc-before-module-declaration-p)
+ (append erlang-edoc-module-tags
+ erlang-edoc-generic-tags))
+ (t (append erlang-edoc-function-tags
+ erlang-edoc-generic-tags)))))
+ (list beg end table))))))
+
+;;;###autoload
+(define-minor-mode erlang-edoc-mode nil
+ :lighter " EDoc"
+ (cond (erlang-edoc-mode
+ (add-hook 'erlang-indent-line-hook #'erlang-edoc-indent-line nil t)
+ (font-lock-add-keywords nil erlang-edoc-font-lock-keywords t)
+ (add-hook 'completion-at-point-functions
+ #'erlang-edoc-completion-at-point nil t))
+ (t
+ (remove-hook 'erlang-indent-line-hook #'erlang-edoc-indent-line t)
+ (font-lock-remove-keywords nil erlang-edoc-font-lock-keywords)
+ (remove-hook 'completion-at-point-functions
+ #'erlang-edoc-completion-at-point t)))
+ (jit-lock-refontify))
+
+(provide 'erlang-edoc)
+;;; erlang-edoc.el ends here
diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el
index ce26c83295..bdb3d9ad4a 100644
--- a/lib/tools/emacs/erlang-skels.el
+++ b/lib/tools/emacs/erlang-skels.el
@@ -1,7 +1,7 @@
;;
;; %CopyrightBegin%
;;
-;; Copyright Ericsson AB 2010-2016. All Rights Reserved.
+;; Copyright Ericsson AB 2010-2017. All Rights Reserved.
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
@@ -56,8 +56,10 @@
erlang-skel-gen-event erlang-skel-header)
("gen_fsm" "gen-fsm"
erlang-skel-gen-fsm erlang-skel-header)
- ("gen_statem" "gen-statem"
- erlang-skel-gen-statem erlang-skel-header)
+ ("gen_statem (StateName/3)" "gen-statem-StateName"
+ erlang-skel-gen-statem-StateName erlang-skel-header)
+ ("gen_statem (handle_event/4)" "gen-statem-handle-event"
+ erlang-skel-gen-statem-handle-event erlang-skel-header)
("wx_object" "wx-object"
erlang-skel-wx-object erlang-skel-header)
("Library module" "gen-lib"
@@ -497,6 +499,7 @@ Please see the function `tempo-define-template'.")
"%% {stop, Reason}" n
(erlang-skel-separator-end 2)
"init([]) ->" n>
+ "process_flag(trap_exit, true)," n>
"{ok, #state{}}." n
n
(erlang-skel-separator-start 2)
@@ -740,6 +743,7 @@ Please see the function `tempo-define-template'.")
"%% {stop, StopReason}" n
(erlang-skel-separator-end 2)
"init([]) ->" n>
+ "process_flag(trap_exit, true)," n>
"{ok, state_name, #state{}}." n
n
(erlang-skel-separator-start 2)
@@ -860,7 +864,7 @@ Please see the function `tempo-define-template'.")
"*The template of a gen_fsm.
Please see the function `tempo-define-template'.")
-(defvar erlang-skel-gen-statem
+(defvar erlang-skel-gen-statem-StateName
'((erlang-skel-include erlang-skel-large-header)
"-behaviour(gen_statem)." n n
@@ -868,9 +872,8 @@ Please see the function `tempo-define-template'.")
"-export([start_link/0])." n
n
"%% gen_statem callbacks" n
- "-export([init/1, terminate/3, code_change/4])." n
+ "-export([callback_mode/0, init/1, terminate/3, code_change/4])." n
"-export([state_name/3])." n
- "-export([handle_event/4])." n
n
"-define(SERVER, ?MODULE)." n
n
@@ -899,48 +902,149 @@ Please see the function `tempo-define-template'.")
(erlang-skel-separator-start 2)
"%% @private" n
"%% @doc" n
+ "%% Define the callback_mode() for this callback module." n
+ (erlang-skel-separator-end 2)
+ "-spec callback_mode() -> gen_statem:callback_mode_result()." n
+ "callback_mode() -> state_functions." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
"%% Whenever a gen_statem is started using gen_statem:start/[3,4] or" n
"%% gen_statem:start_link/[3,4], this function is called by the new" n
"%% process to initialize." n
(erlang-skel-separator-end 2)
- "-spec init(Args :: term()) -> " n>
- "{gen_statem:callback_mode()," n>
- "State :: term(), Data :: term()} |" n>
- "{gen_statem:callback_mode()," n>
- "State :: term(), Data :: term()," n>
- "[gen_statem:action()] | gen_statem:action()} |" n>
- "ignore |" n>
- "{stop, Reason :: term()}." n
+ "-spec init(Args :: term()) ->" n>
+ "gen_statem:init_result(atom())." n
"init([]) ->" n>
- "{state_functions, state_name, #data{}}." n
+ "process_flag(trap_exit, true)," n>
+ "{ok, state_name, #data{}}." n
n
(erlang-skel-separator-start 2)
"%% @private" n
"%% @doc" n
- "%% If the gen_statem runs with CallbackMode =:= state_functions" n
- "%% there should be one instance of this function for each possible" n
- "%% state name. Whenever a gen_statem receives an event," n
- "%% the instance of this function with the same name" n
- "%% as the current state name StateName is called to" n
- "%% handle the event." n
+ "%% There should be one function like this for each state name." n
+ "%% Whenever a gen_statem receives an event, the function " n
+ "%% with the name of the current state (StateName) " n
+ "%% is called to handle the event." n
(erlang-skel-separator-end 2)
- "-spec state_name(" n>
- "gen_statem:event_type(), Msg :: term()," n>
+ "-spec state_name('enter'," n>
+ "OldState :: atom()," n>
+ "Data :: term()) ->" n>
+ "gen_statem:state_enter_result('state_name');" n>
+ "(gen_statem:event_type()," n>
+ "Msg :: term()," n>
"Data :: term()) ->" n>
- "gen_statem:state_function_result(). " n
+ "gen_statem:event_handler_result(atom())." n
+ ;;
"state_name({call,Caller}, _Msg, Data) ->" n>
"{next_state, state_name, Data, [{reply,Caller,ok}]}." n
n
(erlang-skel-separator-start 2)
"%% @private" n
"%% @doc" n
- "%% If the gen_statem runs with CallbackMode =:= handle_event_function" n
- "%% this function is called for every event a gen_statem receives." n
+ "%% This function is called by a gen_statem when it is about to" n
+ "%% terminate. It should be the opposite of Module:init/1 and do any" n
+ "%% necessary cleaning up. When it returns, the gen_statem terminates with" n
+ "%% Reason. The return value is ignored." n
+ (erlang-skel-separator-end 2)
+ "-spec terminate(Reason :: term(), State :: term(), Data :: term()) ->" n>
+ "any()." n
+ "terminate(_Reason, _State, _Data) ->" n>
+ "void." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Convert process state when code is changed" n
+ (erlang-skel-separator-end 2)
+ "-spec code_change(" n>
+ "OldVsn :: term() | {down,term()}," n>
+ "State :: term(), Data :: term(), Extra :: term()) ->" n>
+ "{ok, NewState :: term(), NewData :: term()} |" n>
+ "(Reason :: term())." n
+ "code_change(_OldVsn, State, Data, _Extra) ->" n>
+ "{ok, State, Data}." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% Internal functions" n
+ (erlang-skel-double-separator-end 3)
+ )
+ "*The template of a gen_statem (StateName/3).
+Please see the function `tempo-define-template'.")
+
+(defvar erlang-skel-gen-statem-handle-event
+ '((erlang-skel-include erlang-skel-large-header)
+ "-behaviour(gen_statem)." n n
+
+ "%% API" n
+ "-export([start_link/0])." n
+ n
+ "%% gen_statem callbacks" n
+ "-export([callback_mode/0, init/1, terminate/3, code_change/4])." n
+ "-export([handle_event/4])." n
+ n
+ "-define(SERVER, ?MODULE)." n
+ n
+ "-record(data, {})." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% API" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @doc" n
+ "%% Creates a gen_statem process which calls Module:init/1 to" n
+ "%% initialize. To ensure a synchronized start-up procedure, this" n
+ "%% function does not return until Module:init/1 has returned." n
+ "%%" n
+ (erlang-skel-separator-end 2)
+ "-spec start_link() ->" n>
+ "{ok, Pid :: pid()} |" n>
+ "ignore |" n>
+ "{error, Error :: term()}." n
+ "start_link() ->" n>
+ "gen_statem:start_link({local, ?SERVER}, ?MODULE, [], [])." n
+ n
+ (erlang-skel-double-separator-start 3)
+ "%%% gen_statem callbacks" n
+ (erlang-skel-double-separator-end 3) n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Define the callback_mode() for this callback module." n
+ (erlang-skel-separator-end 2)
+ "-spec callback_mode() -> gen_statem:callback_mode_result()." n
+ "callback_mode() -> handle_event_function." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% Whenever a gen_statem is started using gen_statem:start/[3,4] or" n
+ "%% gen_statem:start_link/[3,4], this function is called by the new" n
+ "%% process to initialize." n
(erlang-skel-separator-end 2)
- "-spec handle_event(" n>
- "gen_statem:event_type(), Msg :: term()," n>
- "State :: term(), Data :: term()) ->" n>
- "gen_statem:handle_event_result(). " n
+ "-spec init(Args :: term()) ->" n>
+ "gen_statem:init_result(term())." n
+ "init([]) ->" n>
+ "process_flag(trap_exit, true)," n>
+ "{ok, state_name, #data{}}." n
+ n
+ (erlang-skel-separator-start 2)
+ "%% @private" n
+ "%% @doc" n
+ "%% This function is called for every event a gen_statem receives." n
+ (erlang-skel-separator-end 2)
+ "-spec handle_event('enter'," n>
+ "OldState :: term()," n>
+ "State :: term()," n>
+ "Data :: term()) ->" n>
+ "gen_statem:state_enter_result(term());" n>
+ "(gen_statem:event_type()," n>
+ "Msg :: term()," n>
+ "State :: term()," n>
+ "Data :: term()) ->" n>
+ "gen_statem:event_handler_result(term())." n
+ ;;
"handle_event({call,From}, _Msg, State, Data) ->" n>
"{next_state, State, Data, [{reply,From,ok}]}." n
n
@@ -965,7 +1069,8 @@ Please see the function `tempo-define-template'.")
"-spec code_change(" n>
"OldVsn :: term() | {down,term()}," n>
"State :: term(), Data :: term(), Extra :: term()) ->" n>
- "{ok, NewState :: term(), NewData :: term()}." n
+ "{ok, NewState :: term(), NewData :: term()} |" n>
+ "(Reason :: term())." n
"code_change(_OldVsn, State, Data, _Extra) ->" n>
"{ok, State, Data}." n
n
@@ -973,7 +1078,7 @@ Please see the function `tempo-define-template'.")
"%%% Internal functions" n
(erlang-skel-double-separator-end 3)
)
- "*The template of a gen_statem.
+ "*The template of a gen_statem (handle_event/4).
Please see the function `tempo-define-template'.")
(defvar erlang-skel-wx-object
diff --git a/lib/tools/emacs/erlang-start.el b/lib/tools/emacs/erlang-start.el
index 76e0575e68..160057e179 100644
--- a/lib/tools/emacs/erlang-start.el
+++ b/lib/tools/emacs/erlang-start.el
@@ -78,6 +78,21 @@
(autoload 'erlang-find-tag-other-window "erlang"
"Like `find-tag-other-window'. Capable of retreiving Erlang modules.")
+;;
+;; Declare functions in "erlang-edoc.el".
+;;
+
+(autoload 'erlang-edoc-mode "erlang-edoc" "Toggle Erlang-Edoc mode on or off." t)
+
+;;
+;; Declare functions in "erldoc.el".
+;;
+
+(autoload 'erldoc-browse "erldoc" "\n\n(fn MFA)" t nil)
+(autoload 'erldoc-browse-topic "erldoc" "\n\n(fn TOPIC)" t nil)
+(autoload 'erldoc-apropos "erldoc" "\n\n(fn PATTERN)" t nil)
+(autoload 'erldoc-eldoc-function "erldoc" "\
+A function suitable for `eldoc-documentation-function'.\n\n(fn)" nil nil)
;;
;; Associate files extensions ".erl" and ".hrl" with Erlang mode.
diff --git a/lib/tools/emacs/erlang-test.el b/lib/tools/emacs/erlang-test.el
index 9a146632c5..ba6190d194 100644
--- a/lib/tools/emacs/erlang-test.el
+++ b/lib/tools/emacs/erlang-test.el
@@ -52,28 +52,42 @@ concatenated to form an erlang file to test on.")
(ert-deftest erlang-test-tags ()
(let* ((dir (make-temp-file "erlang-test" t))
- (erlang-file (expand-file-name "erlang_test.erl" dir))
- (tags-file (expand-file-name "TAGS" dir))
- tags-file-name tags-table-list erlang-buffer)
- (unwind-protect
- (progn
- (erlang-test-create-erlang-file erlang-file)
- (erlang-test-compile-tags erlang-file tags-file)
- (setq erlang-buffer (find-file-noselect erlang-file))
- (with-current-buffer erlang-buffer
- (setq-local tags-file-name tags-file))
- ;; Setting global tags-file-name is a workaround for
- ;; GNU Emacs bug#23164.
- (setq tags-file-name tags-file)
- (erlang-test-completion-table)
- (erlang-test-xref-find-definitions erlang-file erlang-buffer))
- (when (buffer-live-p erlang-buffer)
- (kill-buffer erlang-buffer))
- (let ((tags-buffer (find-buffer-visiting tags-file)))
- (when (buffer-live-p tags-buffer)
- (kill-buffer tags-buffer)))
- (when (file-exists-p dir)
- (delete-directory dir t)))))
+ (erlang-file (expand-file-name "erlang_test.erl" dir))
+ (tags-file (expand-file-name "TAGS" dir))
+ (old-tags-file-name (default-value 'tags-file-name))
+ (old-tags-table-list (default-value 'tags-table-list))
+ tags-file-name
+ tags-table-list
+ tags-table-set-list
+ erlang-buffer
+ erlang-mode-hook
+ prog-mode-hook
+ erlang-shell-mode-hook
+ tags-add-tables)
+ (unwind-protect
+ (progn
+ (setq-default tags-file-name nil)
+ (setq-default tags-table-list nil)
+ (erlang-test-create-erlang-file erlang-file)
+ (erlang-test-compile-tags erlang-file tags-file)
+ (setq erlang-buffer (find-file-noselect erlang-file))
+ (with-current-buffer erlang-buffer
+ (setq-local tags-file-name tags-file))
+ ;; Setting global tags-file-name is a workaround for
+ ;; GNU Emacs bug#23164.
+ (setq tags-file-name tags-file)
+ (erlang-test-complete-at-point tags-file)
+ (erlang-test-completion-table)
+ (erlang-test-xref-find-definitions erlang-file erlang-buffer))
+ (when (buffer-live-p erlang-buffer)
+ (kill-buffer erlang-buffer))
+ (let ((tags-buffer (find-buffer-visiting tags-file)))
+ (when (buffer-live-p tags-buffer)
+ (kill-buffer tags-buffer)))
+ (when (file-exists-p dir)
+ (delete-directory dir t))
+ (setq-default tags-file-name old-tags-file-name)
+ (setq-default tags-table-list old-tags-table-list))))
(defun erlang-test-create-erlang-file (erlang-file)
(with-temp-file erlang-file
@@ -116,6 +130,54 @@ concatenated to form an erlang file to test on.")
(should (eq expected-line (line-number-at-pos)))
(should (= (point-at-bol) (point))))
+(defun erlang-test-complete-at-point (tags-file)
+ (with-temp-buffer
+ (erlang-mode)
+ (setq-local tags-file-name tags-file)
+ (insert "\nerlang_test:fun")
+ (erlang-complete-tag)
+ (should (looking-back "erlang_test:function"))
+ (insert "\nfun")
+ (erlang-complete-tag)
+ (should (looking-back "function"))
+ (insert "\nerlang_")
+ (erlang-complete-tag)
+ (should (looking-back "erlang_test:"))))
+
+
+(ert-deftest erlang-test-compile-options ()
+ (erlang-test-format-opt t
+ "t")
+ (erlang-test-format-opt nil
+ "nil")
+ (erlang-test-format-opt (cons 1 2)
+ "{1, 2}")
+ (erlang-test-format-opt (list 1)
+ "[1]")
+ (erlang-test-format-opt (list 1 2)
+ "[1, 2]")
+ (erlang-test-format-opt (list 1 2 3)
+ "[1, 2, 3]")
+ (erlang-test-format-opt 'symbol
+ "symbol")
+ (erlang-test-format-opt "string"
+ "\"string\"")
+ (erlang-test-format-opt []
+ "{}")
+ (erlang-test-format-opt [1]
+ "{1}")
+ (erlang-test-format-opt [1 2]
+ "{1, 2}")
+ (erlang-test-format-opt [1 2 (3 [4 5 6] 7)]
+ "{1, 2, [3, {4, 5, 6}, 7]}"))
+
+(defun erlang-test-format-opt (elisp &optional expected-erlang)
+ (let ((erlang (inferior-erlang-format-opt elisp)))
+ (message "%s -> %s" elisp erlang)
+ (when expected-erlang
+ (should (equal erlang expected-erlang)))
+ erlang))
+
(provide 'erlang-test)
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index a2062180f3..39c6065ce4 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -59,7 +59,7 @@
;; Please state as exactly as possible:
;; - Version number of Erlang Mode (see the menu), Emacs, Erlang,
-;; and of any other relevant software.
+;; and of any other relevant software.
;; - What the expected result was.
;; - What you did, preferably in a repeatable step-by-step form.
;; - A description of the unexpected result.
@@ -78,6 +78,10 @@
;; Variables:
+(defgroup erlang nil
+ "The Erlang programming language."
+ :group 'languages)
+
(defconst erlang-version "2.7"
"The version number of Erlang mode.")
@@ -91,20 +95,20 @@ Erlang mode menu.")
(eval-and-compile
(defconst erlang-emacs-major-version
(if (boundp 'emacs-major-version)
- emacs-major-version
+ emacs-major-version
(string-match "\\([0-9]+\\)\\.\\([0-9]+\\)" emacs-version)
(erlang-string-to-int (substring emacs-version
- (match-beginning 1) (match-end 1))))
+ (match-beginning 1) (match-end 1))))
"Major version number of Emacs."))
(eval-and-compile
(defconst erlang-emacs-minor-version
- (if (boundp 'emacs-minor-version)
- emacs-minor-version
- (string-match "\\([0-9]+\\)\\.\\([0-9]+\\)" emacs-version)
- (erlang-string-to-int (substring emacs-version
- (match-beginning 2) (match-end 2))))
- "Minor version number of Emacs."))
+ (if (boundp 'emacs-minor-version)
+ emacs-minor-version
+ (string-match "\\([0-9]+\\)\\.\\([0-9]+\\)" emacs-version)
+ (erlang-string-to-int (substring emacs-version
+ (match-beginning 2) (match-end 2))))
+ "Minor version number of Emacs."))
(defconst erlang-xemacs-p (string-match "Lucid\\|XEmacs" emacs-version)
"Non-nil when running under XEmacs or Lucid Emacs.")
@@ -119,12 +123,12 @@ buffers in Erlang mode, just like under GNU Emacs.
Never EVER set this variable!")
(defvar erlang-menu-items '(erlang-menu-base-items
- erlang-menu-skel-items
- erlang-menu-shell-items
- erlang-menu-compile-items
- erlang-menu-man-items
- erlang-menu-personal-items
- erlang-menu-version-items)
+ erlang-menu-skel-items
+ erlang-menu-shell-items
+ erlang-menu-compile-items
+ erlang-menu-man-items
+ erlang-menu-personal-items
+ erlang-menu-version-items)
"*List of menu item list to combine to create Erlang mode menu.
External programs which temporarily add menu items to the Erlang mode
@@ -170,7 +174,7 @@ variable.")
("TAGS"
(("Find Tag" find-tag)
("Find Next Tag" erlang-find-next-tag)
- ;("Find Regexp" find-tag-regexp)
+ ;("Find Regexp" find-tag-regexp)
("Complete Word" erlang-complete-tag)
("Tags Apropos" tags-apropos)
("Search Files" tags-search))))
@@ -475,6 +479,11 @@ To activate the workaround, place the following in your `~/.emacs' file:
"*Indentation of Erlang calls/clauses within blocks.")
(put 'erlang-indent-level 'safe-local-variable 'integerp)
+(defvar erlang-icr-indent nil
+ "*Indentation of Erlang if/case/receive/ patterns. `nil' means
+ keeping default behavior. When non-nil, indent to th column of
+ if/case/receive.")
+
(defvar erlang-indent-guard 2
"*Indentation of Erlang guards.")
(put 'erlang-indent-guard 'safe-local-variable 'integerp)
@@ -558,35 +567,35 @@ This is an elisp list of options. Each option can be either:
Supporting \_< and \_> This is determined by checking the version of Emacs used."))
(eval-and-compile
- (defconst erlang-atom-quoted-regexp
+ (defconst erlang-atom-quoted-regexp
"'\\(?:[^\\']\\|\\(?:\\\\.\\)\\)*'"
"Regexp describing a single-quoted atom"))
(eval-and-compile
(defconst erlang-atom-regular-regexp
(if erlang-regexp-modern-p
- "\\_<[[:lower:]]\\(?:\\sw\\|\\s_\\)*\\_>"
+ "\\_<[[:lower:]]\\(?:\\sw\\|\\s_\\)*\\_>"
"\\<[[:lower:]]\\(?:\\sw\\|\\s_\\)*\\>")
"Regexp describing a regular (non-quoted) atom"))
(eval-and-compile
- (defconst erlang-atom-regexp
- (concat "\\(" erlang-atom-quoted-regexp "\\|"
- erlang-atom-regular-regexp "\\)")
+ (defconst erlang-atom-regexp
+ (concat "\\(" erlang-atom-quoted-regexp "\\|"
+ erlang-atom-regular-regexp "\\)")
"Regexp describing an Erlang atom."))
(eval-and-compile
(defconst erlang-atom-regexp-matches 1
"Number of regexp parenthesis pairs in `erlang-atom-regexp'.
-
+
This is used to determine parenthesis matches in complex regexps which
contains `erlang-atom-regexp'."))
(eval-and-compile
- (defconst erlang-variable-regexp
- (if erlang-regexp-modern-p
- "\\_<\\([[:upper:]_]\\(?:\\sw\\|\\s_\\)*\\)\\_>"
+ (defconst erlang-variable-regexp
+ (if erlang-regexp-modern-p
+ "\\_<\\([[:upper:]_]\\(?:\\sw\\|\\s_\\)*\\)\\_>"
"\\<\\([[:upper:]_]\\(?:\\sw\\|\\s_\\)*\\)\\>")
"Regexp which should match an Erlang variable.
@@ -605,13 +614,13 @@ This is used to determine matches in complex regexps which contains
"Like `regexp-opt', except if PAREN is `symbols', then the
resulting regexp is surrounded by \\_< and \\_>."
(if (eq paren 'symbols)
- (if erlang-regexp-modern-p
- (concat "\\_<" (regexp-opt strings t) "\\_>")
- (concat "\\<" (regexp-opt strings t) "\\>"))
+ (if erlang-regexp-modern-p
+ (concat "\\_<" (regexp-opt strings t) "\\_>")
+ (concat "\\<" (regexp-opt strings t) "\\>"))
(regexp-opt strings paren))))
-(eval-and-compile
+(eval-and-compile
(defvar erlang-keywords
'("after"
"begin"
@@ -630,7 +639,7 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defconst erlang-keywords-regexp (erlang-regexp-opt erlang-keywords 'symbols)))
-
+
(eval-and-compile
(defvar erlang-operators
'("and"
@@ -653,7 +662,7 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defconst erlang-operators-regexp (erlang-regexp-opt erlang-operators 'symbols)))
-
+
(eval-and-compile
(defvar erlang-guards
@@ -676,7 +685,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"binary"
"bitstring"
"boolean"
- ;;"float" ; Not included to avoid clashes with the bif float/1
+ ;;"float" ; Not included to avoid clashes with the bif float/1
"function"
"integer"
"list"
@@ -722,7 +731,7 @@ resulting regexp is surrounded by \\_< and \\_>."
"Erlang type specs types"))
(eval-and-compile
- (defconst erlang-predefined-types-regexp
+ (defconst erlang-predefined-types-regexp
(erlang-regexp-opt erlang-predefined-types 'symbols)))
@@ -842,7 +851,7 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defconst erlang-int-bif-regexp (erlang-regexp-opt erlang-int-bifs 'symbols)))
-
+
(eval-and-compile
(defvar erlang-ext-bifs
@@ -997,8 +1006,8 @@ behaviour.")
(let ((map (make-sparse-keymap)))
(unless (boundp 'indent-line-function)
(define-key map "\t" 'erlang-indent-command))
- (define-key map ";" 'erlang-electric-semicolon)
- (define-key map "," 'erlang-electric-comma)
+ (define-key map ";" 'erlang-electric-semicolon)
+ (define-key map "," 'erlang-electric-comma)
(define-key map "<" 'erlang-electric-lt)
(define-key map ">" 'erlang-electric-gt)
(define-key map "\C-m" 'erlang-electric-newline)
@@ -1010,7 +1019,7 @@ behaviour.")
(unless (boundp 'beginning-of-defun-function)
(define-key map "\M-\C-a" 'erlang-beginning-of-function)
(define-key map "\M-\C-e" 'erlang-end-of-function)
- (define-key map '(meta control h) 'erlang-mark-function)) ; Xemacs
+ (define-key map '(meta control h) 'erlang-mark-function)) ; Xemacs
(define-key map "\M-\t" 'erlang-complete-tag)
(define-key map "\C-c\M-\t" 'tempo-complete-tag)
(define-key map "\M-+" 'erlang-find-next-tag)
@@ -1064,7 +1073,7 @@ behaviour.")
(defvar erlang-font-lock-keywords-function-header
(list
(list (concat "^" erlang-atom-regexp "\\s-*(")
- 1 'font-lock-function-name-face t))
+ 1 'font-lock-function-name-face t))
"Font lock keyword highlighting a function header.")
(defface erlang-font-lock-exported-function-name-face
@@ -1086,7 +1095,7 @@ behaviour.")
(defvar erlang-font-lock-keywords-exported-function-header
(list
(list #'erlang-match-next-exported-function
- 1 'erlang-font-lock-exported-function-name-face t))
+ 1 'erlang-font-lock-exported-function-name-face t))
"Font lock keyword highlighting an exported function header.")
(defvar erlang-font-lock-keywords-int-bifs
@@ -1098,8 +1107,8 @@ behaviour.")
(defvar erlang-font-lock-keywords-ext-bifs
(list
(list (concat "\\<\\(erlang\\)\\s-*:\\s-*" erlang-ext-bif-regexp "\\s-*(")
- '(1 'font-lock-builtin-face)
- '(2 'font-lock-builtin-face)))
+ '(1 'font-lock-builtin-face)
+ '(2 'font-lock-builtin-face)))
"Font lock keyword highlighting built in functions.")
(defvar erlang-font-lock-keywords-int-function-calls
@@ -1113,7 +1122,7 @@ behaviour.")
(list (concat erlang-atom-regexp "\\s-*:\\s-*"
erlang-atom-regexp "\\s-*(")
'(1 'font-lock-type-face)
- '(2 'font-lock-type-face)))
+ '(2 'font-lock-type-face)))
"Font lock keyword highlighting an external function call.")
(defvar erlang-font-lock-keywords-fun-n
@@ -1131,7 +1140,7 @@ behaviour.")
(defvar erlang-font-lock-keywords-dollar
(list
(list "\\(\\$\\([^\\]\\|\\\\\\([^0-7^\n]\\|[0-7]+\\|\\^[a-zA-Z]\\)\\)\\)"
- 1 'font-lock-constant-face))
+ 1 'font-lock-constant-face))
"Font lock keyword highlighting numbers in ASCII form (e.g. $A).")
(defvar erlang-font-lock-keywords-arrow
@@ -1151,18 +1160,18 @@ behaviour.")
(defvar erlang-font-lock-keywords-attr
(list
- (list (concat "^\\(-" erlang-atom-regexp "\\)\\(\\s-\\|\\.\\|(\\)")
- 1 (if (boundp 'font-lock-preprocessor-face)
- 'font-lock-preprocessor-face
- 'font-lock-constant-face)))
+ (list (concat "^\\(-" erlang-atom-regexp "\\)\\(\\s-\\|\\.\\|(\\)")
+ 1 (if (boundp 'font-lock-preprocessor-face)
+ 'font-lock-preprocessor-face
+ 'font-lock-constant-face)))
"Font lock keyword highlighting attributes.")
(defvar erlang-font-lock-keywords-quotes
(list
(list "`\\([-+a-zA-Z0-9_:*][-+a-zA-Z0-9_:*]+\\)'"
- 1
- 'font-lock-keyword-face
- t))
+ 1
+ 'font-lock-keyword-face
+ t))
"Font lock keyword highlighting words in single quotes in comments.
This is not the highlighting of Erlang strings and atoms, which
@@ -1171,27 +1180,27 @@ are highlighted by syntactic analysis.")
(defvar erlang-font-lock-keywords-guards
(list
(list (concat "[^:]" erlang-guards-regexp "\\s-*(")
- 1 'font-lock-builtin-face))
+ 1 'font-lock-builtin-face))
"Font lock keyword highlighting guards.")
(defvar erlang-font-lock-keywords-predefined-types
(list
(list (concat "[^:]" erlang-predefined-types-regexp "\\s-*(")
- 1 'font-lock-builtin-face))
+ 1 'font-lock-builtin-face))
"Font lock keyword highlighting predefined types.")
(defvar erlang-font-lock-keywords-macros
(list
(list (concat "?\\s-*\\(" erlang-atom-regexp
- "\\|" erlang-variable-regexp "\\)")
- 1 'font-lock-constant-face)
+ "\\|" erlang-variable-regexp "\\)")
+ 1 'font-lock-constant-face)
(list (concat "^\\(-\\(?:define\\|ifn?def\\)\\)\\s-*(\\s-*\\(" erlang-atom-regexp
- "\\|" erlang-variable-regexp "\\)")
- (if (boundp 'font-lock-preprocessor-face)
- (list 1 'font-lock-preprocessor-face t)
- (list 1 'font-lock-constant-face t))
- (list 3 'font-lock-type-face t t))
+ "\\|" erlang-variable-regexp "\\)")
+ (if (boundp 'font-lock-preprocessor-face)
+ (list 1 'font-lock-preprocessor-face t)
+ (list 1 'font-lock-constant-face t))
+ (list 3 'font-lock-type-face t t))
(list "^-e\\(lse\\|ndif\\)\\>" 0 'font-lock-preprocessor-face t))
"Font lock keyword highlighting macros.
This must be placed in front of `erlang-font-lock-keywords-vars'.")
@@ -1202,8 +1211,8 @@ This must be placed in front of `erlang-font-lock-keywords-vars'.")
1 'font-lock-type-face)
;; Don't highlight numerical constants.
(list (if erlang-regexp-modern-p
- "\\_<[0-9]+#\\([0-9a-zA-Z]+\\)"
- "\\<[0-9]+#\\([0-9a-zA-Z]+\\)")
+ "\\_<[0-9]+#\\([0-9a-zA-Z]+\\)"
+ "\\<[0-9]+#\\([0-9a-zA-Z]+\\)")
1 nil t)
(list (concat "^-record\\s-*(\\s-*" erlang-atom-regexp)
1 'font-lock-type-face))
@@ -1212,8 +1221,8 @@ This must be placed in front of `erlang-font-lock-keywords-vars'.")
(defvar erlang-font-lock-keywords-vars
(list
- (list (concat "[^#]" erlang-variable-regexp) ; no numerical constants
- 1 'font-lock-variable-name-face))
+ (list (concat "[^#]" erlang-variable-regexp) ; no numerical constants
+ 1 'font-lock-variable-name-face))
"Font lock keyword highlighting Erlang variables.
Must be preceded by `erlang-font-lock-keywords-macros' to work properly.")
@@ -1236,32 +1245,32 @@ Example:
(defvar erlang-font-lock-keywords-1
(append erlang-font-lock-keywords-function-header
- erlang-font-lock-keywords-dollar
- erlang-font-lock-keywords-arrow
- erlang-font-lock-keywords-keywords
- )
+ erlang-font-lock-keywords-dollar
+ erlang-font-lock-keywords-arrow
+ erlang-font-lock-keywords-keywords
+ )
;; DocStringOrig: erlang-font-lock-keywords
erlang-font-lock-descr-string)
(defvar erlang-font-lock-keywords-2
(append erlang-font-lock-keywords-1
- erlang-font-lock-keywords-int-bifs
- erlang-font-lock-keywords-ext-bifs
- erlang-font-lock-keywords-attr
- erlang-font-lock-keywords-quotes
- erlang-font-lock-keywords-guards
- )
+ erlang-font-lock-keywords-int-bifs
+ erlang-font-lock-keywords-ext-bifs
+ erlang-font-lock-keywords-attr
+ erlang-font-lock-keywords-quotes
+ erlang-font-lock-keywords-guards
+ )
;; DocStringCopy: erlang-font-lock-keywords
erlang-font-lock-descr-string)
(defvar erlang-font-lock-keywords-3
(append erlang-font-lock-keywords-2
- erlang-font-lock-keywords-operators
- erlang-font-lock-keywords-macros
- erlang-font-lock-keywords-records
- erlang-font-lock-keywords-vars
- erlang-font-lock-keywords-predefined-types
- )
+ erlang-font-lock-keywords-operators
+ erlang-font-lock-keywords-macros
+ erlang-font-lock-keywords-records
+ erlang-font-lock-keywords-vars
+ erlang-font-lock-keywords-predefined-types
+ )
;; DocStringCopy: erlang-font-lock-keywords
erlang-font-lock-descr-string)
@@ -1269,10 +1278,10 @@ Example:
(append erlang-font-lock-keywords-3
erlang-font-lock-keywords-exported-function-header
erlang-font-lock-keywords-int-function-calls
- erlang-font-lock-keywords-ext-function-calls
- erlang-font-lock-keywords-fun-n
+ erlang-font-lock-keywords-ext-function-calls
+ erlang-font-lock-keywords-fun-n
erlang-font-lock-keywords-lc
- )
+ )
;; DocStringCopy: erlang-font-lock-keywords
erlang-font-lock-descr-string)
@@ -1333,17 +1342,17 @@ replaced by `erlang-etags-tags-completion-table'.")
(eval-when-compile
(if (or (featurep 'bytecomp)
- (featurep 'byte-compile))
+ (featurep 'byte-compile))
(progn
- (cond ((string-match "Lucid\\|XEmacs" emacs-version)
- (put 'comment-indent-hook 'byte-obsolete-variable nil)
- ;; Do not warn for unused variables
- ;; when compiling under XEmacs.
- (setq byte-compile-warnings
- '(free-vars unresolved callargs redefine))))
- (require 'comint)
- (require 'tempo)
- (require 'compile))))
+ (cond ((string-match "Lucid\\|XEmacs" emacs-version)
+ (put 'comment-indent-hook 'byte-obsolete-variable nil)
+ ;; Do not warn for unused variables
+ ;; when compiling under XEmacs.
+ (setq byte-compile-warnings
+ '(free-vars unresolved callargs redefine))))
+ (require 'comint)
+ (require 'tempo)
+ (require 'compile))))
(defun erlang-version ()
@@ -1351,7 +1360,7 @@ replaced by `erlang-etags-tags-completion-table'.")
(interactive)
(if (erlang-interactive-p)
(message "Erlang mode version %s, written by Anders Lindgren"
- erlang-version))
+ erlang-version))
erlang-version)
(defun erlang-interactive-p ()
@@ -1389,7 +1398,7 @@ useful commands:
C-c C-q - Indent current function.
M-; - Create a comment at the end of the line.
M-q - Fill a comment, i.e. wrap lines so that they (hopefully)
- will look better.
+ will look better.
M-a - Goto the beginning of an Erlang clause.
M-C-a - Ditto for function.
M-e - Goto the end of an Erlang clause.
@@ -1436,8 +1445,11 @@ Other commands:
(erlang-skel-init)
(when (fboundp 'tempo-use-tag-list)
(tempo-use-tag-list 'erlang-tempo-tags))
- (when (boundp 'xref-backend-functions)
- (add-hook 'xref-backend-functions #'erlang-etags--xref-backend nil t))
+ (when (and (fboundp 'add-function) (fboundp 'erldoc-eldoc-function))
+ (or eldoc-documentation-function
+ (setq-local eldoc-documentation-function #'ignore))
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'erldoc-eldoc-function))
(run-hooks 'erlang-mode-hook)
(if (zerop (buffer-size))
(run-hooks 'erlang-new-file-hook)))
@@ -1450,35 +1462,35 @@ Other commands:
(defun erlang-syntax-table-init ()
(if (null erlang-mode-syntax-table)
(let ((table (make-syntax-table)))
- (modify-syntax-entry ?\n ">" table)
- (modify-syntax-entry ?\" "\"" table)
- (modify-syntax-entry ?# "." table)
-;; (modify-syntax-entry ?$ "\\" table) ;; Creates problems with indention afterwards
-;; (modify-syntax-entry ?$ "'" table) ;; Creates syntax highlighting and indention problems
- (modify-syntax-entry ?$ "/" table) ;; Misses the corner case "string that ends with $"
- ;; we have to live with that for now..it is the best alternative
- ;; that can be worked around with "string hat ends with \$"
- (modify-syntax-entry ?% "<" table)
- (modify-syntax-entry ?& "." table)
- (modify-syntax-entry ?\' "\"" table)
- (modify-syntax-entry ?* "." table)
- (modify-syntax-entry ?+ "." table)
- (modify-syntax-entry ?- "." table)
- (modify-syntax-entry ?/ "." table)
- (modify-syntax-entry ?: "." table)
- (modify-syntax-entry ?< "." table)
- (modify-syntax-entry ?= "." table)
- (modify-syntax-entry ?> "." table)
- (modify-syntax-entry ?\\ "\\" table)
- (modify-syntax-entry ?_ "_" table)
- (modify-syntax-entry ?| "." table)
- (modify-syntax-entry ?^ "'" table)
-
- ;; Pseudo bit-syntax: Latin1 double angle quotes as parens.
- ;;(modify-syntax-entry ?\253 "(?\273" table)
- ;;(modify-syntax-entry ?\273 ")?\253" table)
-
- (setq erlang-mode-syntax-table table)))
+ (modify-syntax-entry ?\n ">" table)
+ (modify-syntax-entry ?\" "\"" table)
+ (modify-syntax-entry ?# "." table)
+ ;; (modify-syntax-entry ?$ "\\" table) ;; Creates problems with indention afterwards
+ ;; (modify-syntax-entry ?$ "'" table) ;; Creates syntax highlighting and indention problems
+ (modify-syntax-entry ?$ "/" table) ;; Misses the corner case "string that ends with $"
+ ;; we have to live with that for now..it is the best alternative
+ ;; that can be worked around with "string hat ends with \$"
+ (modify-syntax-entry ?% "<" table)
+ (modify-syntax-entry ?& "." table)
+ (modify-syntax-entry ?\' "\"" table)
+ (modify-syntax-entry ?* "." table)
+ (modify-syntax-entry ?+ "." table)
+ (modify-syntax-entry ?- "." table)
+ (modify-syntax-entry ?/ "." table)
+ (modify-syntax-entry ?: "." table)
+ (modify-syntax-entry ?< "." table)
+ (modify-syntax-entry ?= "." table)
+ (modify-syntax-entry ?> "." table)
+ (modify-syntax-entry ?\\ "\\" table)
+ (modify-syntax-entry ?_ "_" table)
+ (modify-syntax-entry ?| "." table)
+ (modify-syntax-entry ?^ "'" table)
+
+ ;; Pseudo bit-syntax: Latin1 double angle quotes as parens.
+ ;;(modify-syntax-entry ?\253 "(?\273" table)
+ ;;(modify-syntax-entry ?\273 ")?\253" table)
+
+ (setq erlang-mode-syntax-table table)))
(set-syntax-table erlang-mode-syntax-table))
@@ -1488,12 +1500,12 @@ Other commands:
;; delsel/pending-del mode. Also, set up text properties for bit
;; syntax handling.
(mapc #'(lambda (cmd)
- (put cmd 'delete-selection t) ;for delsel (Emacs)
- (put cmd 'pending-delete t)) ;for pending-del (XEmacs)
- '(erlang-electric-semicolon
- erlang-electric-comma
- erlang-electric-gt))
-
+ (put cmd 'delete-selection t) ;for delsel (Emacs)
+ (put cmd 'pending-delete t)) ;for pending-del (XEmacs)
+ '(erlang-electric-semicolon
+ erlang-electric-comma
+ erlang-electric-gt))
+
(put 'bitsyntax-open-outer 'syntax-table '(4 . ?>))
(put 'bitsyntax-open-outer 'rear-nonsticky '(category))
(put 'bitsyntax-open-inner 'rear-nonsticky '(category))
@@ -1514,8 +1526,6 @@ Other commands:
(setq paragraph-separate paragraph-start)
(make-local-variable 'paragraph-ignore-fill-prefix)
(setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
(make-local-variable 'defun-prompt-regexp)
(setq defun-prompt-regexp erlang-defun-prompt-regexp)
(make-local-variable 'comment-start)
@@ -1548,17 +1558,15 @@ Other commands:
(set (make-local-variable 'outline-regexp) "[[:lower:]0-9_]+ *(.*) *-> *$")
(set (make-local-variable 'outline-level) (lambda () 1))
(set (make-local-variable 'add-log-current-defun-function)
- 'erlang-current-defun)
- (set (make-local-variable 'find-tag-default-function)
- 'erlang-find-tag-for-completion))
+ 'erlang-current-defun))
(defun erlang-font-lock-init ()
"Initialize Font Lock for Erlang mode."
(or erlang-font-lock-syntax-table
(setq erlang-font-lock-syntax-table
- (let ((table (copy-syntax-table erlang-mode-syntax-table)))
- (modify-syntax-entry ?_ "w" table)
- table)))
+ (let ((table (copy-syntax-table erlang-mode-syntax-table)))
+ (modify-syntax-entry ?_ "w" table)
+ table)))
(set (make-local-variable 'font-lock-syntax-table)
erlang-font-lock-syntax-table)
(set (make-local-variable (if (boundp 'syntax-begin-function)
@@ -1567,23 +1575,23 @@ Other commands:
'erlang-beginning-of-clause)
(make-local-variable 'font-lock-keywords)
(let ((level (cond ((boundp 'font-lock-maximum-decoration)
- (symbol-value 'font-lock-maximum-decoration))
- ((boundp 'font-lock-use-maximal-decoration)
- (symbol-value 'font-lock-use-maximal-decoration))
- (t nil))))
+ (symbol-value 'font-lock-maximum-decoration))
+ ((boundp 'font-lock-use-maximal-decoration)
+ (symbol-value 'font-lock-use-maximal-decoration))
+ (t nil))))
(if (consp level)
- (setq level (cdr-safe (or (assq 'erlang-mode level)
- (assq t level)))))
+ (setq level (cdr-safe (or (assq 'erlang-mode level)
+ (assq t level)))))
;; `level' can here be:
;; A number - The fontification level
;; nil - Use the default
;; t - Use maximum
(cond ((eq level nil)
- (set 'font-lock-keywords erlang-font-lock-keywords))
- ((eq level 1)
- (set 'font-lock-keywords erlang-font-lock-keywords-1))
- ((eq level 2)
- (set 'font-lock-keywords erlang-font-lock-keywords-2))
+ (set 'font-lock-keywords erlang-font-lock-keywords))
+ ((eq level 1)
+ (set 'font-lock-keywords erlang-font-lock-keywords-1))
+ ((eq level 2)
+ (set 'font-lock-keywords erlang-font-lock-keywords-2))
((eq level 3)
(set 'font-lock-keywords erlang-font-lock-keywords-3))
(t
@@ -1592,11 +1600,11 @@ Other commands:
;; Modern font-locks can handle the above much more elegantly:
(set (make-local-variable 'font-lock-defaults)
'((erlang-font-lock-keywords erlang-font-lock-keywords-1
- erlang-font-lock-keywords-2
- erlang-font-lock-keywords-3
- erlang-font-lock-keywords-4)
- nil nil ((?_ . "w")) erlang-beginning-of-clause
- (font-lock-mark-block-function . erlang-mark-clause)
+ erlang-font-lock-keywords-2
+ erlang-font-lock-keywords-3
+ erlang-font-lock-keywords-4)
+ nil nil ((?_ . "w")) erlang-beginning-of-clause
+ (font-lock-mark-block-function . erlang-mark-clause)
(font-lock-syntactic-keywords
;; A dollar sign right before the double quote that ends a
;; string is not a character escape.
@@ -1610,8 +1618,8 @@ Other commands:
;; know whether matching started inside a string: limiting
;; search to a single line keeps things sane.
. (("\\(?:^\\|[^$]\\)\"\\(?:[^\"\n]\\|\\\\\"\\)*\\(\\$\\)\"" 1 "w")
- ;; Likewise for atoms
- ("\\(?:^\\|[^$]\\)'\\(?:[^'\n]\\|\\\\'\\)*\\(\\$\\)'" 1 "w")
+ ;; Likewise for atoms
+ ("\\(?:^\\|[^$]\\)'\\(?:[^'\n]\\|\\\\'\\)*\\(\\$\\)'" 1 "w")
;; And the dollar sign in $\" or $\' escapes two
;; characters, not just one.
("\\(\\$\\)\\\\[\"']" 1 "'"))))))
@@ -1657,17 +1665,17 @@ For a more elaborate example, please see the beginning of the file
(let ((res '()))
(while ks
(let* ((regexp (car (car ks)))
- (number (car (cdr (car ks))))
- (new-face (if (and faces (car faces))
- (car faces)
- (car (cdr (cdr (car ks))))))
- (overwrite (car (cdr (cdr (cdr (car ks))))))
- (new-keyword (list regexp number new-face)))
- (if overwrite (nconc new-keyword (list overwrite)))
- (setq res (cons new-keyword res))
- (setq ks (cdr ks))
- (if (and faces (cdr faces))
- (setq faces (cdr faces)))))
+ (number (car (cdr (car ks))))
+ (new-face (if (and faces (car faces))
+ (car faces)
+ (car (cdr (cdr (car ks))))))
+ (overwrite (car (cdr (cdr (cdr (car ks))))))
+ (new-keyword (list regexp number new-face)))
+ (if overwrite (nconc new-keyword (list overwrite)))
+ (setq res (cons new-keyword res))
+ (setq ks (cdr ks))
+ (if (and faces (cdr faces))
+ (setq faces (cdr faces)))))
(nreverse res)))
@@ -1759,57 +1767,57 @@ variable, i.e. it will popup when pressing the right mouse button.
Please see the variable `erlang-menu-base-items'."
(cond (erlang-xemacs-p
- (let ((menu (erlang-menu-xemacs name items keymap)))
- ;; We add the menu to the global menubar.
- ;;(funcall (symbol-function 'set-buffer-menubar)
- ;; (symbol-value 'current-menubar))
- (funcall (symbol-function 'add-submenu) nil menu)
- (setcdr erlang-xemacs-popup-menu (cdr menu))
- (if (and popup (boundp 'mode-popup-menu))
- (funcall (symbol-function 'set)
- 'mode-popup-menu erlang-xemacs-popup-menu))))
- ((>= erlang-emacs-major-version 19)
- (define-key keymap (vector 'menu-bar (intern name))
- (erlang-menu-make-keymap name items)))
- (t nil)))
+ (let ((menu (erlang-menu-xemacs name items keymap)))
+ ;; We add the menu to the global menubar.
+ ;;(funcall (symbol-function 'set-buffer-menubar)
+ ;; (symbol-value 'current-menubar))
+ (funcall (symbol-function 'add-submenu) nil menu)
+ (setcdr erlang-xemacs-popup-menu (cdr menu))
+ (if (and popup (boundp 'mode-popup-menu))
+ (funcall (symbol-function 'set)
+ 'mode-popup-menu erlang-xemacs-popup-menu))))
+ ((>= erlang-emacs-major-version 19)
+ (define-key keymap (vector 'menu-bar (intern name))
+ (erlang-menu-make-keymap name items)))
+ (t nil)))
(defun erlang-menu-make-keymap (name items)
"Build a menu for Emacs 19."
(let ((menumap (funcall (symbol-function 'make-sparse-keymap)
- name))
- (count 0)
- id def first second third)
+ name))
+ (count 0)
+ id def first second third)
(setq items (reverse items))
(while items
;; Replace any occurrence of atoms by their value.
(while (and items (atom (car items)) (not (null (car items))))
- (if (and (boundp (car items))
- (listp (symbol-value (car items))))
- (setq items (append (reverse (symbol-value (car items)))
- (cdr items)))
- (setq items (cdr items))))
+ (if (and (boundp (car items))
+ (listp (symbol-value (car items))))
+ (setq items (append (reverse (symbol-value (car items)))
+ (cdr items)))
+ (setq items (cdr items))))
(setq first (car-safe (car items)))
(setq second (car-safe (cdr-safe (car items))))
(setq third (car-safe (cdr-safe (cdr-safe (car items)))))
(cond ((null first)
- (setq count (+ count 1))
- (setq id (intern (format "separator-%d" count)))
- (setq def '("--" . nil)))
- ((and (consp second) (eq (car second) 'lambda))
- (setq count (+ count 1))
- (setq id (intern (format "lambda-%d" count)))
- (setq def (cons first second)))
- ((symbolp second)
- (setq id second)
- (setq def (cons first second)))
- (t
- (setq count (+ count 1))
- (setq id (intern (format "submenu-%d" count)))
- (setq def (erlang-menu-make-keymap first second))))
+ (setq count (+ count 1))
+ (setq id (intern (format "separator-%d" count)))
+ (setq def '("--" . nil)))
+ ((and (consp second) (eq (car second) 'lambda))
+ (setq count (+ count 1))
+ (setq id (intern (format "lambda-%d" count)))
+ (setq def (cons first second)))
+ ((symbolp second)
+ (setq id second)
+ (setq def (cons first second)))
+ (t
+ (setq count (+ count 1))
+ (setq id (intern (format "submenu-%d" count)))
+ (setq def (erlang-menu-make-keymap first second))))
(define-key menumap (vector id) def)
(if third
- (put id 'menu-enable third))
+ (put id 'menu-enable third))
(setq items (cdr items)))
(cons name menumap)))
@@ -1817,30 +1825,30 @@ Please see the variable `erlang-menu-base-items'."
(defun erlang-menu-xemacs (name items &optional keymap)
"Build a menu for XEmacs."
(let ((res '())
- first second third entry)
+ first second third entry)
(while items
;; Replace any occurrence of atoms by their value.
(while (and items (atom (car items)) (not (null (car items))))
- (if (and (boundp (car items))
- (listp (symbol-value (car items))))
- (setq items (append (reverse (symbol-value (car items)))
- (cdr items)))
- (setq items (cdr items))))
+ (if (and (boundp (car items))
+ (listp (symbol-value (car items))))
+ (setq items (append (reverse (symbol-value (car items)))
+ (cdr items)))
+ (setq items (cdr items))))
(setq first (car-safe (car items)))
(setq second (car-safe (cdr-safe (car items))))
(setq third (car-safe (cdr-safe (cdr-safe (car items)))))
(cond ((null first)
- (setq res (cons "------" res)))
- ((symbolp second)
- (setq res (cons (vector first second (or third t)) res)))
- ((and (consp second) (eq (car second) 'lambda))
- (setq res (cons (vector first (list 'call-interactively second)
- (or third t)) res)))
- (t
- (setq res (cons (cons first
- (cdr (erlang-menu-xemacs
- first second)))
- res))))
+ (setq res (cons "------" res)))
+ ((symbolp second)
+ (setq res (cons (vector first second (or third t)) res)))
+ ((and (consp second) (eq (car second) 'lambda))
+ (setq res (cons (vector first (list 'call-interactively second)
+ (or third t)) res)))
+ (t
+ (setq res (cons (cons first
+ (cdr (erlang-menu-xemacs
+ first second)))
+ res))))
(setq items (cdr items)))
(setq res (reverse res))
;; When adding a menu to a minor-mode keymap under Emacs,
@@ -1849,15 +1857,15 @@ Please see the variable `erlang-menu-base-items'."
;; (This could be expressed much clearer using backquotes,
;; but I don't want to pull in every package.)
(if keymap
- (let ((expr (list 'or
- (list 'eq keymap 'global-map)
- (list 'eq keymap (list 'current-local-map))
- (list 'symbol-value
- (list 'car-safe
- (list 'rassq
- keymap
- 'minor-mode-map-alist))))))
- (setq res (cons ':included (cons expr res)))))
+ (let ((expr (list 'or
+ (list 'eq keymap 'global-map)
+ (list 'eq keymap (list 'current-local-map))
+ (list 'symbol-value
+ (list 'car-safe
+ (list 'rassq
+ keymap
+ 'minor-mode-map-alist))))))
+ (setq res (cons ':included (cons expr res)))))
(cons name res)))
@@ -1872,13 +1880,13 @@ ALIST is list of pairs where the car is the old function and cdr the new."
(setq first (car-safe (car items)))
(setq second (car-safe (cdr-safe (car items))))
(cond ((null first))
- ((symbolp second)
- (setq pair (and second (assq second alist)))
- (if pair
- (setcar (cdr (car items)) (cdr pair))))
- ((and (consp second) (eq (car second) 'lambda)))
- (t
- (erlang-menu-substitute second alist)))
+ ((symbolp second)
+ (setq pair (and second (assq second alist)))
+ (if pair
+ (setcar (cdr (car items)) (cdr pair))))
+ ((and (consp second) (eq (car second) 'lambda)))
+ (t
+ (erlang-menu-substitute second alist)))
(setq items (cdr items)))))
@@ -1913,27 +1921,27 @@ Example:
\(setq erlang-menu-items
(erlang-menu-add-below 'my-erlang-menu-items
- 'erlang-menu-base-items
+ 'erlang-menu-base-items
erlang-menu-items))"
(if (memq entry items)
- items ; Return the original menu.
+ items ; Return the original menu.
(let ((head '())
- (done nil)
- res)
+ (done nil)
+ res)
(while (not done)
- (cond ((null items)
- (setq res (append head (list entry)))
- (setq done t))
- ((eq below (car items))
- (setq res
- (if above-p
- (append head (cons entry items))
- (append head (cons (car items)
- (cons entry (cdr items))))))
- (setq done t))
- (t
- (setq head (append head (list (car items))))
- (setq items (cdr items)))))
+ (cond ((null items)
+ (setq res (append head (list entry)))
+ (setq done t))
+ ((eq below (car items))
+ (setq res
+ (if above-p
+ (append head (cons entry items))
+ (append head (cons (car items)
+ (cons entry (cdr items))))))
+ (setq done t))
+ (t
+ (setq head (append head (list (car items))))
+ (setq items (cdr items)))))
res)))
(defun erlang-menu-delete (entry items)
@@ -1954,16 +1962,16 @@ the location of the manual pages."
(if erlang-man-inhibit
()
(setq erlang-menu-man-items
- '(nil
- ("Man - Function" erlang-man-function)))
+ '(nil
+ ("Man - Function" erlang-man-function)))
(if erlang-man-dirs
- (setq erlang-menu-man-items
- (append erlang-menu-man-items
- (erlang-man-make-top-menu erlang-man-dirs))))
+ (setq erlang-menu-man-items
+ (append erlang-menu-man-items
+ (erlang-man-make-top-menu erlang-man-dirs))))
(setq erlang-menu-items
- (erlang-menu-add-above 'erlang-menu-man-items
- 'erlang-menu-version-items
- erlang-menu-items))
+ (erlang-menu-add-above 'erlang-menu-man-items
+ 'erlang-menu-version-items
+ erlang-menu-items))
(erlang-menu-init)))
@@ -1971,7 +1979,7 @@ the location of the manual pages."
"Remove the man pages from the Erlang mode."
(interactive)
(setq erlang-menu-items
- (erlang-menu-delete 'erlang-menu-man-items erlang-menu-items))
+ (erlang-menu-delete 'erlang-menu-man-items erlang-menu-items))
(erlang-menu-init))
@@ -1985,28 +1993,28 @@ the location of the manual pages."
"Create one menu entry per element of DIR-LIST.
The format is described in the documentation of `erlang-man-dirs'."
(let ((menu '())
- dir)
+ dir)
(while dir-list
(setq dir (cond ((nth 2 (car dir-list))
- ;; Relative to `erlang-root-dir'.
- (and (stringp erlang-root-dir)
- (concat erlang-root-dir (nth 1 (car dir-list)))))
- (t
- ;; Absolute
- (nth 1 (car dir-list)))))
+ ;; Relative to `erlang-root-dir'.
+ (and (stringp erlang-root-dir)
+ (concat erlang-root-dir (nth 1 (car dir-list)))))
+ (t
+ ;; Absolute
+ (nth 1 (car dir-list)))))
(if (and dir
- (file-readable-p dir))
- (setq menu (cons (list (car (car dir-list))
- (erlang-man-make-middle-menu
- (erlang-man-get-files dir)))
- menu)))
+ (file-readable-p dir))
+ (setq menu (cons (list (car (car dir-list))
+ (erlang-man-make-middle-menu
+ (erlang-man-get-files dir)))
+ menu)))
(setq dir-list (cdr dir-list)))
;; Should no menus be found, generate a menu item which
;; will display a help text, when selected.
(if menu
- (nreverse menu)
+ (nreverse menu)
'(("Man Pages"
- (("Error! Why?" erlang-man-describe-error)))))))
+ (("Error! Why?" erlang-man-describe-error)))))))
;; Should the menu be to long, let's split it into a number of
@@ -2020,32 +2028,32 @@ menus is created."
(if (<= (length filelist) erlang-man-max-menu-size)
(erlang-man-make-menu filelist)
(let ((menu '())
- (filelist (copy-sequence filelist))
- segment submenu pair)
+ (filelist (copy-sequence filelist))
+ segment submenu pair)
(while filelist
- (setq pair (nthcdr (- erlang-man-max-menu-size 1) filelist))
- (setq segment filelist)
- (if (null pair)
- (setq filelist nil)
- (setq filelist (cdr pair))
- (setcdr pair nil))
- (setq submenu (erlang-man-make-menu segment))
- (setq menu (cons (list (concat (car (car submenu))
- " -- "
- (car (car (reverse submenu))))
- submenu)
- menu)))
+ (setq pair (nthcdr (- erlang-man-max-menu-size 1) filelist))
+ (setq segment filelist)
+ (if (null pair)
+ (setq filelist nil)
+ (setq filelist (cdr pair))
+ (setcdr pair nil))
+ (setq submenu (erlang-man-make-menu segment))
+ (setq menu (cons (list (concat (car (car submenu))
+ " -- "
+ (car (car (reverse submenu))))
+ submenu)
+ menu)))
(nreverse menu))))
(defun erlang-man-make-menu (filelist)
"Make a leaf menu based on FILELIST."
(let ((menu '())
- item)
+ item)
(while filelist
(setq item (erlang-man-make-menu-item (car filelist)))
(if item
- (setq menu (cons item menu)))
+ (setq menu (cons item menu)))
(setq filelist (cdr filelist)))
(nreverse menu)))
@@ -2054,11 +2062,11 @@ menus is created."
"Create a menu item containing the name of the man page."
(and (string-match ".+/\\([^/]+\\)\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$" file)
(let ((page (substring file (match-beginning 1) (match-end 1))))
- (list (capitalize page)
- (list 'lambda '()
- '(interactive)
- (list 'funcall 'erlang-man-display-function
- file))))))
+ (list (capitalize page)
+ (list 'lambda '()
+ '(interactive)
+ (list 'funcall 'erlang-man-display-function
+ file))))))
(defun erlang-man-get-files (dir)
@@ -2071,33 +2079,33 @@ menus is created."
This function is aware of imported functions."
(interactive
(list (let* ((mod (car-safe (erlang-get-function-under-point)))
- (input (read-string
- (format "Manual entry for module%s: "
- (if (or (null mod) (string= mod ""))
- ""
- (format " (default %s)" mod))))))
- (if (string= input "")
- mod
- input))))
+ (input (read-string
+ (format "Manual entry for module%s: "
+ (if (or (null mod) (string= mod ""))
+ ""
+ (format " (default %s)" mod))))))
+ (if (string= input "")
+ mod
+ input))))
(or module (setq module (car (erlang-get-function-under-point))))
(if (or (null module) (string= module ""))
(error "No Erlang module name given"))
(let ((dir-list erlang-man-dirs)
- (pat (concat "/" (regexp-quote module) "\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$"))
- (file nil)
- file-list)
+ (pat (concat "/" (regexp-quote module) "\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$"))
+ (file nil)
+ file-list)
(while (and dir-list (null file))
(setq file-list (erlang-man-get-files
- (if (nth 2 (car dir-list))
- (concat erlang-root-dir (nth 1 (car dir-list)))
- (nth 1 (car dir-list)))))
+ (if (nth 2 (car dir-list))
+ (concat erlang-root-dir (nth 1 (car dir-list)))
+ (nth 1 (car dir-list)))))
(while (and file-list (null file))
- (if (string-match pat (car file-list))
- (setq file (car file-list)))
- (setq file-list (cdr file-list)))
+ (if (string-match pat (car file-list))
+ (setq file (car file-list)))
+ (setq file-list (cdr file-list)))
(setq dir-list (cdr dir-list)))
(if file
- (funcall erlang-man-display-function file)
+ (funcall erlang-man-display-function file)
(error "No manual page for module %s found" module))))
@@ -2119,55 +2127,55 @@ The entry for `function' is displayed.
This function is aware of imported functions."
(interactive
(list (let* ((mod-func (erlang-get-function-under-point))
- (mod (car-safe mod-func))
- (func (nth 1 mod-func))
- (input (read-string
- (format
- "Manual entry for `module:func' or `module'%s: "
- (if (or (null mod) (string= mod ""))
- ""
- (format " (default %s:%s)" mod func))))))
- (if (string= input "")
- (if (and mod func)
- (concat mod ":" func)
- mod)
- input))))
+ (mod (car-safe mod-func))
+ (func (nth 1 mod-func))
+ (input (read-string
+ (format
+ "Manual entry for `module:func' or `module'%s: "
+ (if (or (null mod) (string= mod ""))
+ ""
+ (format " (default %s:%s)" mod func))))))
+ (if (string= input "")
+ (if (and mod func)
+ (concat mod ":" func)
+ mod)
+ input))))
;; Emacs 18 doesn't provide `man'...
(condition-case nil
(require 'man)
(error nil))
(let ((modname nil)
- (funcname nil))
+ (funcname nil))
(cond ((null name)
- (let ((mod-func (erlang-get-function-under-point)))
- (setq modname (car-safe mod-func))
- (setq funcname (nth 1 mod-func))))
- ((string-match ":" name)
- (setq modname (substring name 0 (match-beginning 0)))
- (setq funcname (substring name (match-end 0) nil)))
- ((stringp name)
- (setq modname name)))
+ (let ((mod-func (erlang-get-function-under-point)))
+ (setq modname (car-safe mod-func))
+ (setq funcname (nth 1 mod-func))))
+ ((string-match ":" name)
+ (setq modname (substring name 0 (match-beginning 0)))
+ (setq funcname (substring name (match-end 0) nil)))
+ ((stringp name)
+ (setq modname name)))
(if (or (null modname) (string= modname ""))
- (error "No Erlang module name given"))
+ (error "No Erlang module name given"))
(cond ((fboundp 'Man-notify-when-ready)
- ;; Emacs 19: The man command could possibly start an
- ;; asynchronous process, i.e. we must hook ourselves into
- ;; the system to be activated when the man-process
- ;; terminates.
- (if (null funcname)
- ()
- (erlang-man-patch-notify)
- (setq erlang-man-function-name funcname))
- (condition-case nil
- (erlang-man-module modname)
- (error (setq erlang-man-function-name nil))))
- (t
- (erlang-man-module modname)
- (if funcname
- (erlang-man-find-function
- (or (get-buffer "*Manual Entry*") ; Emacs 18
- (current-buffer)) ; XEmacs
- funcname))))))
+ ;; Emacs 19: The man command could possibly start an
+ ;; asynchronous process, i.e. we must hook ourselves into
+ ;; the system to be activated when the man-process
+ ;; terminates.
+ (if (null funcname)
+ ()
+ (erlang-man-patch-notify)
+ (setq erlang-man-function-name funcname))
+ (condition-case nil
+ (erlang-man-module modname)
+ (error (setq erlang-man-function-name nil))))
+ (t
+ (erlang-man-module modname)
+ (if funcname
+ (erlang-man-find-function
+ (or (get-buffer "*Manual Entry*") ; Emacs 18
+ (current-buffer)) ; XEmacs
+ funcname))))))
;; Should the defadvice be at the top level, the package `advice' would
@@ -2185,14 +2193,14 @@ command is executed asynchronously."
;; This should never happened since this is only called when
;; running under Emacs 19.
(error (error (concat "This command needs the package `advice', "
- "please upgrade your Emacs."))))
+ "please upgrade your Emacs."))))
(require 'man)
(defadvice Man-notify-when-ready
- (after erlang-Man-notify-when-ready activate)
+ (after erlang-Man-notify-when-ready activate)
"Set point at the documentation of the function name in
`erlang-man-function-name' when the man page is displayed."
(if erlang-man-function-name
- (erlang-man-find-function (ad-get-arg 0) erlang-man-function-name))
+ (erlang-man-find-function (ad-get-arg 0) erlang-man-function-name))
(setq erlang-man-function-name nil)))
@@ -2200,17 +2208,17 @@ command is executed asynchronously."
"Find manual page for function in `erlang-man-function-name' in buffer BUF."
(if func
(let ((win (get-buffer-window buf)))
- (if win
- (progn
- (set-buffer buf)
- (goto-char (point-min))
- (if (re-search-forward
- (concat "^[ \t]+" func " ?(")
- (point-max) t)
- (progn
- (forward-word -1)
- (set-window-point win (point)))
- (message "Could not find function `%s'" func)))))))
+ (if win
+ (progn
+ (set-buffer buf)
+ (goto-char (point-min))
+ (if (re-search-forward
+ (concat "^[ \t]+" func " ?(")
+ (point-max) t)
+ (progn
+ (forward-word -1)
+ (set-window-point win (point)))
+ (message "Could not find function `%s'" func)))))))
(defun erlang-man-display (file)
@@ -2224,25 +2232,25 @@ to be used."
(error nil))
(if file
(let ((process-environment (copy-sequence process-environment)))
- (if (string-match "\\(.*\\)/man[^/]*/\\([^.]+\\)\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$" file)
- (let ((dir (substring file (match-beginning 1) (match-end 1)))
- (page (substring file (match-beginning 2) (match-end 2))))
- (if (fboundp 'setenv)
- (setenv "MANPATH" dir)
- ;; Emacs 18
- (setq process-environment (cons (concat "MANPATH=" dir)
- process-environment)))
- (cond ((not (and (not erlang-xemacs-p)
- (= erlang-emacs-major-version 19)
- (< erlang-emacs-minor-version 29)))
- (manual-entry page))
- (t
- ;; Emacs 19.28 and earlier versions of 19:
- ;; The manual-entry command unconditionally prompts
- ;; the user :-(
- (funcall (symbol-function 'Man-getpage-in-background)
- page))))
- (error "Can't find man page for %s\n" file)))))
+ (if (string-match "\\(.*\\)/man[^/]*/\\([^.]+\\)\\.\\([124-9]\\|3\\(erl\\)?\\)\\(\\.gz\\)?$" file)
+ (let ((dir (substring file (match-beginning 1) (match-end 1)))
+ (page (substring file (match-beginning 2) (match-end 2))))
+ (if (fboundp 'setenv)
+ (setenv "MANPATH" dir)
+ ;; Emacs 18
+ (setq process-environment (cons (concat "MANPATH=" dir)
+ process-environment)))
+ (cond ((not (and (not erlang-xemacs-p)
+ (= erlang-emacs-major-version 19)
+ (< erlang-emacs-minor-version 29)))
+ (manual-entry page))
+ (t
+ ;; Emacs 19.28 and earlier versions of 19:
+ ;; The manual-entry command unconditionally prompts
+ ;; the user :-(
+ (funcall (symbol-function 'Man-getpage-in-background)
+ page))))
+ (error "Can't find man page for %s\n" file)))))
(defun erlang-man-describe-error ()
@@ -2285,43 +2293,43 @@ package not be present, this function does nothing."
(error t))
(if (featurep 'tempo)
(let ((skel erlang-skel)
- (menu '()))
- (while skel
- (cond ((null (car skel))
- (setq menu (cons nil menu)))
- (t
- (funcall (symbol-function 'tempo-define-template)
- (concat "erlang-" (nth 1 (car skel)))
- ;; The tempo template used contains an `include'
- ;; function call only, hence changes to the
- ;; variables describing the templates take effect
- ;; immdiately.
- (list (list 'erlang-skel-include (nth 2 (car skel))))
- (nth 1 (car skel))
- (car (car skel))
- 'erlang-tempo-tags)
- (setq menu (cons (erlang-skel-make-menu-item
- (car skel)) menu))))
- (setq skel (cdr skel)))
- (setq erlang-menu-skel-items
- (list nil (list "Skeletons" (nreverse menu))))
- (setq erlang-menu-items
- (erlang-menu-add-above 'erlang-menu-skel-items
- 'erlang-menu-version-items
- erlang-menu-items))
- (erlang-menu-init))))
+ (menu '()))
+ (while skel
+ (cond ((null (car skel))
+ (setq menu (cons nil menu)))
+ (t
+ (funcall (symbol-function 'tempo-define-template)
+ (concat "erlang-" (nth 1 (car skel)))
+ ;; The tempo template used contains an `include'
+ ;; function call only, hence changes to the
+ ;; variables describing the templates take effect
+ ;; immdiately.
+ (list (list 'erlang-skel-include (nth 2 (car skel))))
+ (nth 1 (car skel))
+ (car (car skel))
+ 'erlang-tempo-tags)
+ (setq menu (cons (erlang-skel-make-menu-item
+ (car skel)) menu))))
+ (setq skel (cdr skel)))
+ (setq erlang-menu-skel-items
+ (list nil (list "Skeletons" (nreverse menu))))
+ (setq erlang-menu-items
+ (erlang-menu-add-above 'erlang-menu-skel-items
+ 'erlang-menu-version-items
+ erlang-menu-items))
+ (erlang-menu-init))))
(defun erlang-skel-make-menu-item (skel)
(let ((func (intern (concat "tempo-template-erlang-" (nth 1 skel)))))
(cond ((null (nth 3 skel))
- (list (car skel) func))
- (t
- (list (car skel)
- (list 'lambda '()
- '(interactive)
- (list 'funcall
- (list 'quote (nth 3 skel))
- (list 'quote func))))))))
+ (list (car skel) func))
+ (t
+ (list (car skel)
+ (list 'lambda '()
+ '(interactive)
+ (list 'funcall
+ (list 'quote (nth 3 skel))
+ (list 'quote func))))))))
;; Functions designed to be added to the skeleton menu.
;; (Not normally used)
@@ -2354,12 +2362,12 @@ Technically, this function returns the `tempo' attribute`(l ...)' which
can contain other `tempo' attributes. Please see the function
`tempo-define-template' for a description of the `(l ...)' attribute."
(let ((res '())
- entry)
+ entry)
(while args
(setq entry (car args))
(while entry
- (setq res (cons (car entry) res))
- (setq entry (cdr entry)))
+ (setq res (cons (car entry) res))
+ (setq entry (cdr entry)))
(setq args (cdr args)))
(cons 'l (nreverse res))))
@@ -2368,25 +2376,25 @@ can contain other `tempo' attributes. Please see the function
(defun erlang-skel-separator (&optional percent)
"Return a comment separator."
(let ((percent (or percent 3)))
- (concat (make-string percent ?%)
- (make-string (- erlang-skel-separator-length percent) ?-)
- "\n")))
+ (concat (make-string percent ?%)
+ (make-string (- erlang-skel-separator-length percent) ?-)
+ "\n")))
(defun erlang-skel-double-separator (&optional percent)
"Return a comment separator."
(let ((percent (or percent 3)))
- (concat (make-string percent ?%)
- (make-string (- erlang-skel-separator-length percent) ?=)
- "\n")))
+ (concat (make-string percent ?%)
+ (make-string (- erlang-skel-separator-length percent) ?=)
+ "\n")))
(defun erlang-skel-dd-mmm-yyyy ()
"Return the current date as a string in \"DD Mon YYYY\" form.
The first character of DD is space if the value is less than 10."
(let ((date (current-time-string)))
(format "%2d %s %s"
- (erlang-string-to-int (substring date 8 10))
- (substring date 4 7)
- (substring date -4))))
+ (erlang-string-to-int (substring date 8 10))
+ (substring date 4 7)
+ (substring date -4))))
;; Indentation code:
@@ -2399,23 +2407,23 @@ rigidly along with this one."
;; If arg, always indent this line as Erlang
;; and shift remaining lines of clause the same amount.
(let ((shift-amt (erlang-indent-line))
- beg end)
- (save-excursion
- (if erlang-tab-always-indent
- (beginning-of-line))
- (setq beg (point))
- (erlang-end-of-clause 1)
- (setq end (point))
- (goto-char beg)
- (forward-line 1)
- (setq beg (point)))
- (if (> end beg)
- (indent-code-rigidly beg end shift-amt "\n")))
+ beg end)
+ (save-excursion
+ (if erlang-tab-always-indent
+ (beginning-of-line))
+ (setq beg (point))
+ (erlang-end-of-clause 1)
+ (setq end (point))
+ (goto-char beg)
+ (forward-line 1)
+ (setq beg (point)))
+ (if (> end beg)
+ (indent-code-rigidly beg end shift-amt "\n")))
(if (and (not erlang-tab-always-indent)
- (save-excursion
- (skip-chars-backward " \t")
- (not (bolp))))
- (insert-tab)
+ (save-excursion
+ (skip-chars-backward " \t")
+ (not (bolp))))
+ (insert-tab)
(erlang-indent-line))))
@@ -2423,33 +2431,34 @@ rigidly along with this one."
"Indent current line as Erlang code.
Return the amount the indentation changed by."
(let ((pos (- (point-max) (point)))
- indent beg
- shift-amt)
+ indent beg
+ shift-amt)
(beginning-of-line 1)
(setq beg (point))
(skip-chars-forward " \t")
(cond ((looking-at "%")
- (setq indent (funcall comment-indent-function))
- (setq shift-amt (- indent (current-column))))
- (t
- (setq indent (erlang-calculate-indent))
- (cond ((null indent)
- (setq indent (current-indentation)))
- ((eq indent t)
- ;; This should never occur here.
- (error "Erlang mode error"))
- ;;((= (char-syntax (following-char)) ?\))
- ;; (setq indent (1- indent)))
- )
- (setq shift-amt (- indent (current-column)))))
+ (setq indent (funcall comment-indent-function))
+ (setq shift-amt (- indent (current-column))))
+ (t
+ (setq indent (erlang-calculate-indent))
+ (cond ((null indent)
+ (setq indent (current-indentation)))
+ ((eq indent t)
+ ;; This should never occur here.
+ (error "Erlang mode error"))
+ ;;((= (char-syntax (following-char)) ?\))
+ ;; (setq indent (1- indent)))
+ )
+ (setq shift-amt (- indent (current-column)))))
(if (zerop shift-amt)
- nil
+ nil
(delete-region beg (point))
(indent-to indent))
;; If initial point was within line's indentation, position
;; after the indentation. Else stay at same point in text.
(if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
+ (goto-char (- (point-max) pos)))
+ (run-hooks 'erlang-indent-line-hook)
shift-amt))
@@ -2460,11 +2469,11 @@ This is automagically called by the user level function `indent-region'."
(interactive "r")
(save-excursion
(let ((case-fold-search nil)
- (continue t)
- (from-end (- (point-max) end))
- indent-point;; The beginning of the current line
- indent;; The indent amount
- state)
+ (continue t)
+ (from-end (- (point-max) end))
+ indent-point;; The beginning of the current line
+ indent;; The indent amount
+ state)
(goto-char beg)
(beginning-of-line)
(setq indent-point (point))
@@ -2478,39 +2487,39 @@ This is automagically called by the user level function `indent-region'."
(error "Illegal syntax"))))
;; Indent every line in the region
(while continue
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (cond ((looking-at "%")
- ;; Do not use our stack to help the user to customize
- ;; comment indentation.
- (setq indent (funcall comment-indent-function)))
- ((looking-at "$")
- ;; Don't indent empty lines.
- (setq indent 0))
- (t
- (setq indent
- (save-excursion
- (erlang-calculate-stack-indent (point) state)))
- (cond ((null indent)
- (setq indent (current-indentation)))
- ((eq indent t)
- ;; This should never occur here.
- (error "Erlang mode error"))
- ;;((= (char-syntax (following-char)) ?\))
- ;; (setq indent (1- indent)))
- )))
- (if (zerop (- indent (current-column)))
- nil
- (delete-region indent-point (point))
- (indent-to indent))
- ;; Find the next line in the region
- (goto-char indent-point)
- (save-excursion
- (forward-line 1)
- (setq indent-point (point)))
- (if (>= from-end (- (point-max) indent-point))
- (setq continue nil)
- (while (< (point) indent-point)
+ (goto-char indent-point)
+ (skip-chars-forward " \t")
+ (cond ((looking-at "%")
+ ;; Do not use our stack to help the user to customize
+ ;; comment indentation.
+ (setq indent (funcall comment-indent-function)))
+ ((looking-at "$")
+ ;; Don't indent empty lines.
+ (setq indent 0))
+ (t
+ (setq indent
+ (save-excursion
+ (erlang-calculate-stack-indent (point) state)))
+ (cond ((null indent)
+ (setq indent (current-indentation)))
+ ((eq indent t)
+ ;; This should never occur here.
+ (error "Erlang mode error"))
+ ;;((= (char-syntax (following-char)) ?\))
+ ;; (setq indent (1- indent)))
+ )))
+ (if (zerop (- indent (current-column)))
+ nil
+ (delete-region indent-point (point))
+ (indent-to indent))
+ ;; Find the next line in the region
+ (goto-char indent-point)
+ (save-excursion
+ (forward-line 1)
+ (setq indent-point (point)))
+ (if (>= from-end (- (point-max) indent-point))
+ (setq continue nil)
+ (while (< (point) indent-point)
(let ((pt (point)))
(setq state (erlang-partial-parse
pt indent-point state))
@@ -2532,7 +2541,7 @@ This is automagically called by the user level function `indent-region'."
(interactive)
(save-excursion
(let ((end (progn (erlang-end-of-function 1) (point)))
- (beg (progn (erlang-beginning-of-function 1) (point))))
+ (beg (progn (erlang-beginning-of-function 1) (point))))
(erlang-indent-region beg end))))
@@ -2541,7 +2550,7 @@ This is automagically called by the user level function `indent-region'."
(interactive)
(save-excursion
(let ((end (progn (erlang-end-of-clause 1) (point)))
- (beg (progn (erlang-beginning-of-clause 1) (point))))
+ (beg (progn (erlang-beginning-of-clause 1) (point))))
(erlang-indent-region beg end))))
@@ -2556,11 +2565,11 @@ This is automagically called by the user level function `indent-region'."
Return nil if line starts inside string, t if in a comment."
(save-excursion
(let ((indent-point (point))
- (case-fold-search nil)
- (state nil))
+ (case-fold-search nil)
+ (state nil))
(if parse-start
- (goto-char parse-start)
- (erlang-beginning-of-clause))
+ (goto-char parse-start)
+ (erlang-beginning-of-clause))
(while (< (point) indent-point)
(let ((pt (point)))
(setq state (erlang-partial-parse pt indent-point state))
@@ -2575,25 +2584,25 @@ Return nil if line starts inside string, t if in a comment."
(save-excursion
(let ((starting-point (point))
- (case-fold-search nil)
- (state nil))
+ (case-fold-search nil)
+ (state nil))
(erlang-beginning-of-clause)
(while (< (point) starting-point)
- (setq state (erlang-partial-parse (point) starting-point state)))
+ (setq state (erlang-partial-parse (point) starting-point state)))
(message "%S" state))))
(defun erlang-partial-parse (from to &optional state)
"Parse Erlang syntax starting at FROM until TO, with an optional STATE.
Value is list (stack token-start token-type in-what)."
- (goto-char from) ; Start at the beginning
+ (goto-char from) ; Start at the beginning
(erlang-skip-blank to)
(let ((cs (char-syntax (following-char)))
- (stack (car state))
- (token (point))
- in-what)
- (cond
-
+ (stack (car state))
+ (token (point))
+ in-what)
+ (cond
+
;; Done: Return previous state.
((>= token to)
(setq token (nth 1 state))
@@ -2603,230 +2612,230 @@ Value is list (stack token-start token-type in-what)."
;; Word constituent: check and handle keywords.
((= cs ?w)
(cond ((looking-at "\\(end\\|after\\)[^_a-zA-Z0-9]")
- ;; Must pop top icr layer, `after' will push a new
- ;; layer next.
- (progn
- (while (and stack (eq (car (car stack)) '->))
- (erlang-pop stack))
- (if (and stack (memq (car (car stack)) '(icr begin fun try)))
- (erlang-pop stack))))
- ((looking-at "catch\\b.*of")
- t)
- ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
- ;; Must pop top icr layer, `catch' in try/catch
- ;;will push a new layer next.
- (progn
- (while (and stack (eq (car (car stack)) '->))
- (erlang-pop stack))
- (if (and stack (memq (car (car stack)) '(icr begin try)))
- (erlang-pop stack))))
- )
+ ;; Must pop top icr layer, `after' will push a new
+ ;; layer next.
+ (progn
+ (while (and stack (eq (car (car stack)) '->))
+ (erlang-pop stack))
+ (if (and stack (memq (car (car stack)) '(icr begin fun try)))
+ (erlang-pop stack))))
+ ((looking-at "catch\\b.*of")
+ t)
+ ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
+ ;; Must pop top icr layer, `catch' in try/catch
+ ;;will push a new layer next.
+ (progn
+ (while (and stack (eq (car (car stack)) '->))
+ (erlang-pop stack))
+ (if (and stack (memq (car (car stack)) '(icr begin try)))
+ (erlang-pop stack))))
+ )
(cond ((looking-at "\\(if\\|case\\|receive\\)[^_a-zA-Z0-9]")
- ;; Must push a new icr (if/case/receive) layer.
- (erlang-push (list 'icr token (current-column)) stack))
- ((looking-at "\\(try\\|after\\)[^_a-zA-Z0-9]")
- ;; Must handle separately, try catch or try X of -> catch
- ;; same for `after', it could be
- ;; receive after Time -> X end, or
- ;; try after X end
- (erlang-push (list 'try token (current-column)) stack))
- ((looking-at "\\(of\\)[^_a-zA-Z0-9]")
- ;; Must handle separately, try X of -> catch
- (if (and stack (eq (car (car stack)) 'try))
- (let ((try-column (nth 2 (car stack)))
- (try-pos (nth 1 (car stack))))
- (erlang-pop stack)
- (erlang-push (list 'icr try-pos try-column) stack))))
-
- ((looking-at "\\(fun\\)[^_a-zA-Z0-9]")
- ;; Push a new layer if we are defining a `fun'
- ;; expression, not when we are refering an existing
- ;; function. 'fun's defines are only indented one level now.
- (if (save-excursion
- (goto-char (match-end 1))
- (erlang-skip-blank to)
- ;; Use erlang-variable-regexp here to look for an
- ;; optional variable name to match EEP37 named funs.
- (if (looking-at erlang-variable-regexp)
- (progn
- (goto-char (match-end 0))
- (erlang-skip-blank to)))
- (eq (following-char) ?\())
- (erlang-push (list 'fun token (current-column)) stack)))
- ((looking-at "\\(begin\\)[^_a-zA-Z0-9]")
- (erlang-push (list 'begin token (current-column)) stack))
- ;; Normal when case
- ;;((looking-at "when\\s ")
- ;;((looking-at "when\\s *\\($\\|%\\)")
- ((looking-at "when[^_a-zA-Z0-9]")
- (erlang-push (list 'when token (current-column)) stack))
- ((looking-at "catch\\b.*of")
- t)
- ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
- (erlang-push (list 'icr token (current-column)) stack))
- ;;(erlang-push (list '-> token (current-column)) stack))
- ;;((looking-at "^of$")
- ;; (erlang-push (list 'icr token (current-column)) stack)
- ;;(erlang-push (list '-> token (current-column)) stack))
- )
+ ;; Must push a new icr (if/case/receive) layer.
+ (erlang-push (list 'icr token (current-column)) stack))
+ ((looking-at "\\(try\\|after\\)[^_a-zA-Z0-9]")
+ ;; Must handle separately, try catch or try X of -> catch
+ ;; same for `after', it could be
+ ;; receive after Time -> X end, or
+ ;; try after X end
+ (erlang-push (list 'try token (current-column)) stack))
+ ((looking-at "\\(of\\)[^_a-zA-Z0-9]")
+ ;; Must handle separately, try X of -> catch
+ (if (and stack (eq (car (car stack)) 'try))
+ (let ((try-column (nth 2 (car stack)))
+ (try-pos (nth 1 (car stack))))
+ (erlang-pop stack)
+ (erlang-push (list 'icr try-pos try-column) stack))))
+
+ ((looking-at "\\(fun\\)[^_a-zA-Z0-9]")
+ ;; Push a new layer if we are defining a `fun'
+ ;; expression, not when we are refering an existing
+ ;; function. 'fun's defines are only indented one level now.
+ (if (save-excursion
+ (goto-char (match-end 1))
+ (erlang-skip-blank to)
+ ;; Use erlang-variable-regexp here to look for an
+ ;; optional variable name to match EEP37 named funs.
+ (if (looking-at erlang-variable-regexp)
+ (progn
+ (goto-char (match-end 0))
+ (erlang-skip-blank to)))
+ (eq (following-char) ?\())
+ (erlang-push (list 'fun token (current-column)) stack)))
+ ((looking-at "\\(begin\\)[^_a-zA-Z0-9]")
+ (erlang-push (list 'begin token (current-column)) stack))
+ ;; Normal when case
+ ;;((looking-at "when\\s ")
+ ;;((looking-at "when\\s *\\($\\|%\\)")
+ ((looking-at "when[^_a-zA-Z0-9]")
+ (erlang-push (list 'when token (current-column)) stack))
+ ((looking-at "catch\\b.*of")
+ t)
+ ((looking-at "catch\\b\\s *\\($\\|%\\|.*->\\)")
+ (erlang-push (list 'icr token (current-column)) stack))
+ ;;(erlang-push (list '-> token (current-column)) stack))
+ ;;((looking-at "^of$")
+ ;; (erlang-push (list 'icr token (current-column)) stack)
+ ;;(erlang-push (list '-> token (current-column)) stack))
+ )
(forward-sexp 1))
- ;; String: Try to skip over it. (Catch error if not complete.)
- ((= cs ?\")
- (condition-case nil
- (progn
- (forward-sexp 1)
- (if (> (point) to)
- (progn
- (setq in-what 'string)
- (goto-char to))))
- (error
- (setq in-what 'string)
- (goto-char to))))
+ ;; String: Try to skip over it. (Catch error if not complete.)
+ ((= cs ?\")
+ (condition-case nil
+ (progn
+ (forward-sexp 1)
+ (if (> (point) to)
+ (progn
+ (setq in-what 'string)
+ (goto-char to))))
+ (error
+ (setq in-what 'string)
+ (goto-char to))))
;; Expression prefix e.i. $ or ^ (Note ^ can be in the character
;; literal $^ or part of string and $ outside of a string denotes
;; a character literal)
((= cs ?')
- (cond
+ (cond
((= (following-char) ?\") ;; $ or ^ was the last char in a string
- (forward-char 1))
+ (forward-char 1))
(t
- ;; Maybe a character literal, quote the next char to avoid
- ;; situations as $" being seen as the begining of a string.
- ;; Note the quoting something in the middle of a string is harmless.
- (quote (following-char))
- (forward-char 1))))
+ ;; Maybe a character literal, quote the next char to avoid
+ ;; situations as $" being seen as the begining of a string.
+ ;; Note the quoting something in the middle of a string is harmless.
+ (quote (following-char))
+ (forward-char 1))))
;; Symbol constituent or punctuation
-
+
((memq cs '(?. ?_))
- (cond
-
+ (cond
+
;; Clause end
((= (following-char) ?\;)
- (if (eq (car (car (last stack))) 'spec)
- (while (memq (car (car stack)) '(when ::))
- (erlang-pop stack)))
- (if (and stack (eq (car (car stack)) '->))
- (erlang-pop stack))
- (forward-char 1))
-
+ (if (eq (car (car (last stack))) 'spec)
+ (while (memq (car (car stack)) '(when ::))
+ (erlang-pop stack)))
+ (if (and stack (eq (car (car stack)) '->))
+ (erlang-pop stack))
+ (forward-char 1))
+
;; Parameter separator
((looking-at ",")
- (forward-char 1)
- (if (and stack (eq (car (car stack)) '::))
- ;; Type or spec
- (erlang-pop stack)))
+ (forward-char 1)
+ (if (and stack (eq (car (car stack)) '::))
+ ;; Type or spec
+ (erlang-pop stack)))
;; Function end
((looking-at "\\.\\(\\s \\|\n\\|\\s<\\)")
- (setq stack nil)
- (forward-char 1))
-
+ (setq stack nil)
+ (forward-char 1))
+
;; Function head
((looking-at "->")
- (if (and stack (eq (car (car stack)) 'when))
- (erlang-pop stack))
- (erlang-push (list '-> token (current-column)) stack)
- (forward-char 2))
-
+ (if (and stack (eq (car (car stack)) 'when))
+ (erlang-pop stack))
+ (erlang-push (list '-> token (current-column)) stack)
+ (forward-char 2))
+
;; List-comprehension divider
((looking-at "||")
- (erlang-push (list '|| token (current-column)) stack)
- (forward-char 2))
+ (erlang-push (list '|| token (current-column)) stack)
+ (forward-char 2))
;; 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 (- (match-end 0) (match-beginning 0))))
-
+ (erlang-push (list '<< token (current-column)) stack)
+ (forward-char (- (match-end 0) (match-beginning 0))))
+
;; Bit-syntax close
((looking-at ">>")
- (while (memq (car (car stack)) '(|| ->))
- (erlang-pop stack))
- (cond ((eq (car (car stack)) '<<)
- (erlang-pop stack))
- ((memq (car (car stack)) '(icr begin fun))
- (error "Missing `end'"))
- (t
- (error "Unbalanced parentheses")))
- (forward-char 2))
-
+ (while (memq (car (car stack)) '(|| ->))
+ (erlang-pop stack))
+ (cond ((eq (car (car stack)) '<<)
+ (erlang-pop stack))
+ ((memq (car (car stack)) '(icr begin fun))
+ (error "Missing `end'"))
+ (t
+ (error "Unbalanced parentheses")))
+ (forward-char 2))
+
;; Macro
((= (following-char) ??)
- ;; Skip over the ?
- (forward-char 1)
- )
+ ;; Skip over the ?
+ (forward-char 1)
+ )
;; Type spec's
((looking-at "-type\\s \\|-opaque\\s ")
- (if stack
- (forward-char 1)
- (erlang-push (list 'icr token (current-column)) stack)
- (forward-char 6)))
+ (if stack
+ (forward-char 1)
+ (erlang-push (list 'icr token (current-column)) stack)
+ (forward-char 6)))
((looking-at "-spec\\s ")
- (if stack
- (forward-char 1)
- (forward-char 6)
- (skip-chars-forward "^(\n")
- (erlang-push (list 'spec (point) (current-column)) stack)
- ))
+ (if stack
+ (forward-char 1)
+ (forward-char 6)
+ (skip-chars-forward "^(\n")
+ (erlang-push (list 'spec (point) (current-column)) stack)
+ ))
;; Type spec delimiter
((looking-at "::")
- (erlang-push (list ':: token (current-column)) stack)
- (forward-char 2))
-
- ;; Don't follow through in the clause below
- ;; '|' don't need spaces around it
+ (erlang-push (list ':: token (current-column)) stack)
+ (forward-char 2))
+
+ ;; Don't follow through in the clause below
+ ;; '|' don't need spaces around it
((looking-at "|")
- (forward-char 1))
-
+ (forward-char 1))
+
;; Other punctuation: Skip over it and any following punctuation
((= cs ?.)
- ;; Skip over all characters in the operand.
- (skip-syntax-forward "."))
-
+ ;; Skip over all characters in the operand.
+ (skip-syntax-forward "."))
+
;; Other char: Skip over it.
(t
- (forward-char 1))))
-
+ (forward-char 1))))
+
;; Open parenthesis
((= cs ?\()
(erlang-push (list '\( token (current-column)) stack)
(forward-char 1))
-
+
;; Close parenthesis
((= cs ?\))
(while (memq (car (car stack)) '(|| -> :: when))
- (erlang-pop stack))
+ (erlang-pop stack))
(cond ((eq (car (car stack)) '\()
- (erlang-pop stack)
- (if (and (eq (car (car stack)) 'fun)
- (or (eq (car (car (last stack))) 'spec)
- (eq (car (car (cdr stack))) '::))) ;; -type()
- ;; Inside fun type def ') closes fun definition
- (erlang-pop stack)))
- ((eq (car (car stack)) 'icr)
- (erlang-pop stack)
- ;; Normal catch not try-catch might have caused icr
- ;; and then incr should be removed and is not an error.
- (if (eq (car (car stack)) '\()
- (erlang-pop stack)
- (error "Missing `end'")
- ))
- ((eq (car (car stack)) 'begin)
- (error "Missing `end'"))
- (t
- (error "Unbalanced parenthesis"))
- )
- (forward-char 1))
-
+ (erlang-pop stack)
+ (if (and (eq (car (car stack)) 'fun)
+ (or (eq (car (car (last stack))) 'spec)
+ (eq (car (car (cdr stack))) '::))) ;; -type()
+ ;; Inside fun type def ') closes fun definition
+ (erlang-pop stack)))
+ ((eq (car (car stack)) 'icr)
+ (erlang-pop stack)
+ ;; Normal catch not try-catch might have caused icr
+ ;; and then incr should be removed and is not an error.
+ (if (eq (car (car stack)) '\()
+ (erlang-pop stack)
+ (error "Missing `end'")
+ ))
+ ((eq (car (car stack)) 'begin)
+ (error "Missing `end'"))
+ (t
+ (error "Unbalanced parenthesis"))
+ )
+ (forward-char 1))
+
;; Character quote: Skip it and the quoted char.
((= cs ?/)
(forward-char 2))
-
+
;; Character escape: Skip it and the escape sequence.
((= cs ?\\)
(forward-char 1)
@@ -2855,49 +2864,49 @@ Return nil if inside string, t if in a comment."
((eq (car stack-top) '\()
;; Element of list, tuple or part of an expression,
(cond ((null erlang-argument-indent)
- ;; indent to next column.
- (1+ (nth 2 stack-top)))
- ((= (char-syntax (following-char)) ?\))
- (goto-char (nth 1 stack-top))
- (cond ((looking-at "[({]\\s *\\($\\|%\\)")
- ;; Line ends with parenthesis.
- (let ((previous (erlang-indent-find-preceding-expr))
- (stack-pos (nth 2 stack-top)))
- (if (>= previous stack-pos) stack-pos
- (- (+ previous erlang-argument-indent) 1))))
- (t
- (nth 2 stack-top))))
- ((= (following-char) ?,)
- ;; a comma at the start of the line: line up with opening parenthesis.
- (nth 2 stack-top))
- (t
- (goto-char (nth 1 stack-top))
- (let ((base (cond ((looking-at "[({]\\s *\\($\\|%\\)")
- ;; Line ends with parenthesis.
- (erlang-indent-parenthesis (nth 2 stack-top)))
- (t
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (1+ (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column)))))
- (erlang-indent-standard indent-point token base 't)))))
- ;;
- ((eq (car stack-top) '<<)
- ;; Element of binary (possible comprehension) expression,
- (cond ((null erlang-argument-indent)
- ;; indent to next column.
- (+ 2 (nth 2 stack-top)))
- ((looking-at "\\(>>\\)[^_a-zA-Z0-9]")
- (nth 2 stack-top))
- (t
- (goto-char (nth 1 stack-top))
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (+ 2 (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column))))
-
+ ;; indent to next column.
+ (1+ (nth 2 stack-top)))
+ ((= (char-syntax (following-char)) ?\))
+ (goto-char (nth 1 stack-top))
+ (cond ((looking-at "[({]\\s *\\($\\|%\\)")
+ ;; Line ends with parenthesis.
+ (let ((previous (erlang-indent-find-preceding-expr))
+ (stack-pos (nth 2 stack-top)))
+ (if (>= previous stack-pos) stack-pos
+ (- (+ previous erlang-argument-indent) 1))))
+ (t
+ (nth 2 stack-top))))
+ ((= (following-char) ?,)
+ ;; a comma at the start of the line: line up with opening parenthesis.
+ (nth 2 stack-top))
+ (t
+ (goto-char (nth 1 stack-top))
+ (let ((base (cond ((looking-at "[({]\\s *\\($\\|%\\)")
+ ;; Line ends with parenthesis.
+ (erlang-indent-parenthesis (nth 2 stack-top)))
+ (t
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (1+ (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column)))))
+ (erlang-indent-standard indent-point token base 't)))))
+ ;;
+ ((eq (car stack-top) '<<)
+ ;; Element of binary (possible comprehension) expression,
+ (cond ((null erlang-argument-indent)
+ ;; indent to next column.
+ (+ 2 (nth 2 stack-top)))
+ ((looking-at "\\(>>\\)[^_a-zA-Z0-9]")
+ (nth 2 stack-top))
+ (t
+ (goto-char (nth 1 stack-top))
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (+ 2 (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column))))
+
((memq (car stack-top) '(icr fun spec))
;; The default indentation is the column of the option
;; directly following the keyword. (This does not apply to
@@ -2908,156 +2917,160 @@ Return nil if inside string, t if in a comment."
;; `after' should be indented to the same level as the
;; corresponding receive.
(cond ((looking-at "\\(after\\|of\\)\\($\\|[^_a-zA-Z0-9]\\)")
- (nth 2 stack-top))
- ((looking-at "when[^_a-zA-Z0-9]")
- ;; Handling one when part
- (+ (nth 2 stack-top) erlang-indent-level erlang-indent-guard))
- (t
- (save-excursion
- (goto-char (nth 1 stack-top))
- (if (looking-at "case[^_a-zA-Z0-9]")
- (+ (nth 2 stack-top) erlang-indent-level)
- (skip-chars-forward "a-z")
- (skip-chars-forward " \t")
- (if (memq (following-char) '(?% ?\n))
- (+ (nth 2 stack-top) erlang-indent-level)
- (current-column))))))
- )
- ((and (eq (car stack-top) '||) (looking-at "\\(]\\|>>\\)[^_a-zA-Z0-9]"))
- (nth 2 (car (cdr stack))))
+ (nth 2 stack-top))
+ ((looking-at "when[^_a-zA-Z0-9]")
+ ;; Handling one when part
+ (+ (nth 2 stack-top) erlang-indent-level erlang-indent-guard))
+ (t
+ (save-excursion
+ (goto-char (nth 1 stack-top))
+ (if (and erlang-icr-indent
+ (looking-at "\\(if\\|case\\|receive\\)[^_a-zA-Z0-9]"))
+ (+ (nth 2 stack-top) erlang-icr-indent)
+ (if (looking-at "\\(case\\|receive\\)[^_a-zA-Z0-9]")
+ (+ (nth 2 stack-top) erlang-indent-level)
+ (skip-chars-forward "a-z")
+ (skip-chars-forward " \t")
+ (if (memq (following-char) '(?% ?\n))
+ (+ (nth 2 stack-top) erlang-indent-level)
+ (current-column))))))))
+ ((and (eq (car stack-top) '||) (looking-at "\\(]\\|>>\\)[^_a-zA-Z0-9]"))
+ (nth 2 (car (cdr stack))))
;; Real indentation, where operators create extra indentation etc.
((memq (car stack-top) '(-> || try begin))
- (if (looking-at "\\(of\\)[^_a-zA-Z0-9]")
- (nth 2 stack-top)
- (goto-char (nth 1 stack-top))
- ;; Check if there is more code after the '->' on the
- ;; same line. If so use this indentation as base, else
- ;; use parent indentation + 2 * level as base.
- (let ((off erlang-indent-level)
- (skip 2))
- (cond ((null (cdr stack))) ; Top level in function.
- ((eq (car stack-top) 'begin)
- (setq skip 5))
- ((eq (car stack-top) 'try)
- (setq skip 5))
- ((eq (car stack-top) '->)
- ;; If in fun definition use standard indent level not double
- ;;(if (not (eq (car (car (cdr stack))) 'fun))
- ;; Removed it made multi clause fun's look to bad
- (setq off (* 2 erlang-indent-level)))) ;; )
- (let ((base (erlang-indent-find-base stack indent-point off skip)))
- ;; Special cases
- (goto-char indent-point)
- (cond ((looking-at "\\(end\\|after\\)\\($\\|[^_a-zA-Z0-9]\\)")
- (if (eq (car stack-top) '->)
- (erlang-pop stack))
- (if stack
- (erlang-caddr (car stack))
- 0))
- ((looking-at "catch\\b\\($\\|[^_a-zA-Z0-9]\\)")
- ;; Are we in a try
- (let ((start (if (eq (car stack-top) '->)
- (car (cdr stack))
- stack-top)))
- (if (null start) nil
- (goto-char (nth 1 start)))
- (cond ((looking-at "try\\($\\|[^_a-zA-Z0-9]\\)")
- (progn
- (if (eq (car stack-top) '->)
- (erlang-pop stack))
- (if stack
- (erlang-caddr (car stack))
- 0)))
- (t (erlang-indent-standard indent-point token base 'nil))))) ;; old catch
- (t
- (erlang-indent-standard indent-point token base 'nil)
- ))))
- ))
- ((eq (car stack-top) 'when)
- (goto-char (nth 1 stack-top))
- (if (looking-at "when\\s *\\($\\|%\\)")
- (progn
- (erlang-pop stack)
- (if (and stack (memq (nth 0 (car stack)) '(icr fun)))
- (progn
- (goto-char (nth 1 (car stack)))
- (+ (nth 2 (car stack)) erlang-indent-guard
- ;; receive XYZ or receive
- ;; XYZ
- ;; This if thing does not seem to be needed
- ;;(if (looking-at "[a-z]+\\s *\\($\\|%\\)")
- ;; erlang-indent-level
- ;; (* 2 erlang-indent-level))))
- (* 2 erlang-indent-level)))
- ;;erlang-indent-level))
- (+ erlang-indent-level erlang-indent-guard)))
+ (if (looking-at "\\(of\\)[^_a-zA-Z0-9]")
+ (nth 2 stack-top)
+ (goto-char (nth 1 stack-top))
+ ;; Check if there is more code after the '->' on the
+ ;; same line. If so use this indentation as base, else
+ ;; use parent indentation + 2 * level as base.
+ (let ((off erlang-indent-level)
+ (skip 2))
+ (cond ((null (cdr stack))) ; Top level in function.
+ ((eq (car stack-top) 'begin)
+ (setq skip 5))
+ ((eq (car stack-top) 'try)
+ (setq skip 5))
+ ((eq (car stack-top) '->)
+ ;; If in fun definition use standard indent level not double
+ ;;(if (not (eq (car (car (cdr stack))) 'fun))
+ ;; Removed it made multi clause fun's look to bad
+ (setq off (+ erlang-indent-level (if (not erlang-icr-indent)
+ erlang-indent-level
+ erlang-icr-indent)))))
+ (let ((base (erlang-indent-find-base stack indent-point off skip)))
+ ;; Special cases
+ (goto-char indent-point)
+ (cond ((looking-at "\\(end\\|after\\)\\($\\|[^_a-zA-Z0-9]\\)")
+ (if (eq (car stack-top) '->)
+ (erlang-pop stack))
+ (if stack
+ (erlang-caddr (car stack))
+ 0))
+ ((looking-at "catch\\b\\($\\|[^_a-zA-Z0-9]\\)")
+ ;; Are we in a try
+ (let ((start (if (eq (car stack-top) '->)
+ (car (cdr stack))
+ stack-top)))
+ (if (null start) nil
+ (goto-char (nth 1 start)))
+ (cond ((looking-at "try\\($\\|[^_a-zA-Z0-9]\\)")
+ (progn
+ (if (eq (car stack-top) '->)
+ (erlang-pop stack))
+ (if stack
+ (erlang-caddr (car stack))
+ 0)))
+ (t (erlang-indent-standard indent-point token base 'nil))))) ;; old catch
+ (t
+ (erlang-indent-standard indent-point token base 'nil)
+ ))))
+ ))
+ ((eq (car stack-top) 'when)
+ (goto-char (nth 1 stack-top))
+ (if (looking-at "when\\s *\\($\\|%\\)")
+ (progn
+ (erlang-pop stack)
+ (if (and stack (memq (nth 0 (car stack)) '(icr fun)))
+ (progn
+ (goto-char (nth 1 (car stack)))
+ (+ (nth 2 (car stack)) erlang-indent-guard
+ ;; receive XYZ or receive
+ ;; XYZ
+ ;; This if thing does not seem to be needed
+ ;;(if (looking-at "[a-z]+\\s *\\($\\|%\\)")
+ ;; erlang-indent-level
+ ;; (* 2 erlang-indent-level))))
+ (* 2 erlang-indent-level)))
+ ;;erlang-indent-level))
+ (+ erlang-indent-level erlang-indent-guard)))
;; "when" is followed by code, let's indent to the same
;; column.
(forward-char 4) ; Skip "when"
(skip-chars-forward " \t")
(current-column)))
- ;; Type and Spec indentation
- ((eq (car stack-top) '::)
- (if (looking-at "[},)]")
- ;; Closing function spec, record definition with types,
+ ;; Type and Spec indentation
+ ((eq (car stack-top) '::)
+ (if (looking-at "[},)]")
+ ;; Closing function spec, record definition with types,
;; or a comma at the start of the line
- ;; pop stack and recurse
- (erlang-calculate-stack-indent indent-point
- (cons (erlang-pop stack) (cdr state)))
- (cond ((null erlang-argument-indent)
- ;; indent to next column.
- (+ 2 (nth 2 stack-top)))
- ((looking-at "::[^_a-zA-Z0-9]")
- (nth 2 stack-top))
- (t
- (let ((start-alternativ (if (looking-at "|") 2 0)))
- (goto-char (nth 1 stack-top))
- (- (cond ((looking-at "::\\s *\\($\\|%\\)")
- ;; Line ends with ::
- (if (eq (car (car (last stack))) 'spec)
- (+ (erlang-indent-find-preceding-expr 1)
- erlang-argument-indent)
- (+ (erlang-indent-find-preceding-expr 2)
- erlang-argument-indent)))
- (t
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (+ 2 (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column))) start-alternativ))))))
- )))
+ ;; pop stack and recurse
+ (erlang-calculate-stack-indent indent-point
+ (cons (erlang-pop stack) (cdr state)))
+ (cond ((null erlang-argument-indent)
+ ;; indent to next column.
+ (+ 2 (nth 2 stack-top)))
+ ((looking-at "::[^_a-zA-Z0-9]")
+ (nth 2 stack-top))
+ (t
+ (let ((start-alternativ (if (looking-at "|") 2 0)))
+ (goto-char (nth 1 stack-top))
+ (- (cond ((looking-at "::\\s *\\($\\|%\\)")
+ ;; Line ends with ::
+ (if (eq (car (car (last stack))) 'spec)
+ (+ (erlang-indent-find-preceding-expr 1)
+ erlang-argument-indent)
+ (+ (erlang-indent-find-preceding-expr 2)
+ erlang-argument-indent)))
+ (t
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (+ 2 (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column))) start-alternativ))))))
+ )))
(defun erlang-indent-standard (indent-point token base inside-parenthesis)
"Standard indent when in blocks or tuple or arguments.
Look at last thing to see in what state we are, move relative to the base."
- (goto-char token)
+ (goto-char token)
(cond ((looking-at "||\\|,\\|->\\||")
- base)
- ((erlang-at-keyword)
- (+ (current-column) erlang-indent-level))
- ((or (= (char-syntax (following-char)) ?.)
- (erlang-at-operator))
- (+ base erlang-indent-level))
- (t
- (goto-char indent-point)
- (cond ((memq (following-char) '(?\( ))
- ;; Function application.
- (+ (erlang-indent-find-preceding-expr)
- erlang-argument-indent))
- ;; Empty line, or end; treat it as the end of
- ;; the block. (Here we have a choice: should
- ;; the user be forced to reindent continued
- ;; lines, or should the "end" be reindented?)
-
- ;; Avoid treating comments a continued line.
- ((= (following-char) ?%)
- base)
- ;; Continued line (e.g. line beginning
- ;; with an operator.)
- (t
- (if (or (erlang-at-operator) (not inside-parenthesis))
- (+ base erlang-indent-level)
- base))))))
+ base)
+ ((erlang-at-keyword)
+ (+ (current-column) erlang-indent-level))
+ ((or (= (char-syntax (following-char)) ?.)
+ (erlang-at-operator))
+ (+ base erlang-indent-level))
+ (t
+ (goto-char indent-point)
+ (cond ((memq (following-char) '(?\( ))
+ ;; Function application.
+ (+ (erlang-indent-find-preceding-expr)
+ erlang-argument-indent))
+ ;; Empty line, or end; treat it as the end of
+ ;; the block. (Here we have a choice: should
+ ;; the user be forced to reindent continued
+ ;; lines, or should the "end" be reindented?)
+
+ ;; Avoid treating comments a continued line.
+ ((= (following-char) ?%)
+ base)
+ ;; Continued line (e.g. line beginning
+ ;; with an operator.)
+ (t
+ (if (or (erlang-at-operator) (not inside-parenthesis))
+ (+ base erlang-indent-level)
+ base))))))
(defun erlang-indent-find-base (stack indent-point &optional offset skip)
"Find the base column for current stack."
@@ -3067,21 +3080,21 @@ Return nil if inside string, t if in a comment."
(let* ((stack-top (car stack)))
(goto-char (nth 1 stack-top))
(if (< skip (- (point-max) (point)))
- (progn
- (forward-char skip)
- (if (looking-at "\\s *\\($\\|%\\)")
- (progn
- (if (memq (car stack-top) '(-> ||))
- (erlang-pop stack))
- ;; Take parent identation + offset,
- ;; else just erlang-indent-level if no parent
- (if stack
- (+ (erlang-caddr (car stack))
- offset)
- erlang-indent-level))
- (erlang-skip-blank indent-point)
- (current-column)))
- (+ (current-column) skip)))))
+ (progn
+ (forward-char skip)
+ (if (looking-at "\\s *\\($\\|%\\)")
+ (progn
+ (if (memq (car stack-top) '(-> ||))
+ (erlang-pop stack))
+ ;; Take parent identation + offset,
+ ;; else just erlang-indent-level if no parent
+ (if stack
+ (+ (erlang-caddr (car stack))
+ offset)
+ erlang-indent-level))
+ (erlang-skip-blank indent-point)
+ (current-column)))
+ (+ (current-column) skip)))))
;; Does not handle `begin' .. `end'.
@@ -3100,51 +3113,51 @@ This assumes that the preceding expression is either simple
;; where the call (forward-sexp -1) will fail when point is at the `#'.
(or
(ignore-errors
- ;; Needed to match the colon in "'foo':'bar'".
- (cond ((eq (preceding-char) ?:)
- (backward-char 1)
- (forward-sexp -1)
- (current-column))
- ((eq (preceding-char) ?#)
- ;; We may now be at:
- ;; - either a construction of a new record
- ;; - or update of a record, in which case we want
- ;; the column of the expression to be updated.
- ;;
- ;; To see which of the two cases we are at, we first
- ;; move an expression backwards, check for keywords,
- ;; then immediately an expression forwards. Moving
- ;; backwards skips past tokens like `,' or `->', but
- ;; when moving forwards again, we won't skip past such
- ;; tokens. We use this: if, after having moved
- ;; forwards, we're back where we started, then it was
- ;; a record update.
- ;; The check for keywords is to detect cases like:
- ;; case Something of #record_construction{...}
- (backward-char 1)
- (let ((record-start (point))
- (record-start-col (current-column)))
- (forward-sexp -1)
- (let ((preceding-expr-col (current-column))
- ;; white space definition according to erl_scan
- (white-space "\000-\040\200-\240"))
- (if (erlang-at-keyword)
- ;; The (forward-sexp -1) call moved past a keyword
- (1+ record-start-col)
- (forward-sexp 1)
- (skip-chars-forward white-space record-start)
- ;; Are we back where we started? If so, it was an update.
- (if (= (point) record-start)
- preceding-expr-col
- (goto-char record-start)
- (1+ (current-column)))))))
- (t col)))
+ ;; Needed to match the colon in "'foo':'bar'".
+ (cond ((eq (preceding-char) ?:)
+ (backward-char 1)
+ (forward-sexp -1)
+ (current-column))
+ ((eq (preceding-char) ?#)
+ ;; We may now be at:
+ ;; - either a construction of a new record
+ ;; - or update of a record, in which case we want
+ ;; the column of the expression to be updated.
+ ;;
+ ;; To see which of the two cases we are at, we first
+ ;; move an expression backwards, check for keywords,
+ ;; then immediately an expression forwards. Moving
+ ;; backwards skips past tokens like `,' or `->', but
+ ;; when moving forwards again, we won't skip past such
+ ;; tokens. We use this: if, after having moved
+ ;; forwards, we're back where we started, then it was
+ ;; a record update.
+ ;; The check for keywords is to detect cases like:
+ ;; case Something of #record_construction{...}
+ (backward-char 1)
+ (let ((record-start (point))
+ (record-start-col (current-column)))
+ (forward-sexp -1)
+ (let ((preceding-expr-col (current-column))
+ ;; white space definition according to erl_scan
+ (white-space "\000-\040\200-\240"))
+ (if (erlang-at-keyword)
+ ;; The (forward-sexp -1) call moved past a keyword
+ (1+ record-start-col)
+ (forward-sexp 1)
+ (skip-chars-forward white-space record-start)
+ ;; Are we back where we started? If so, it was an update.
+ (if (= (point) record-start)
+ preceding-expr-col
+ (goto-char record-start)
+ (1+ (current-column)))))))
+ (t col)))
col))))
-(defun erlang-indent-parenthesis (stack-position)
+(defun erlang-indent-parenthesis (stack-position)
(let ((previous (erlang-indent-find-preceding-expr)))
(if (> previous stack-position)
- (+ stack-position erlang-argument-indent)
+ (+ stack-position erlang-argument-indent)
(+ previous erlang-argument-indent))))
(defun erlang-skip-blank (&optional lim)
@@ -3153,20 +3166,20 @@ This assumes that the preceding expression is either simple
(let (stop)
(while (and (not stop) (< (point) lim))
(cond ((= (following-char) ?%)
- (skip-chars-forward "^\n" lim))
- ((= (following-char) ?\n)
- (skip-chars-forward "\n" lim))
- ((looking-at "\\s ")
- (if (re-search-forward "\\S " lim 'move)
- (forward-char -1)))
- (t
- (setq stop t))))
+ (skip-chars-forward "^\n" lim))
+ ((= (following-char) ?\n)
+ (skip-chars-forward "\n" lim))
+ ((looking-at "\\s ")
+ (if (re-search-forward "\\S " lim 'move)
+ (forward-char -1)))
+ (t
+ (setq stop t))))
stop))
(defun erlang-at-keyword ()
"Are we looking at an Erlang keyword which will increase indentation?"
(looking-at (concat "\\(when\\|if\\|fun\\|case\\|begin\\|"
- "of\\|receive\\|after\\|catch\\|try\\)\\b")))
+ "of\\|receive\\|after\\|catch\\|try\\)\\b")))
(defun erlang-at-operator ()
"Are we looking at an Erlang operator?"
@@ -3179,14 +3192,14 @@ This assumes that the preceding expression is either simple
Used both by `indent-for-comment' and the Erlang specific indentation
commands."
(cond ((looking-at "%%%") 0)
- ((looking-at "%%")
- (or (erlang-calculate-indent)
- (current-indentation)))
- (t
- (save-excursion
- (skip-chars-backward " \t")
- (max (if (bolp) 0 (1+ (current-column)))
- comment-column)))))
+ ((looking-at "%%")
+ (or (erlang-calculate-indent)
+ (current-indentation)))
+ (t
+ (save-excursion
+ (skip-chars-backward " \t")
+ (max (if (bolp) 0 (1+ (current-column)))
+ comment-column)))))
;;; Erlang movement commands
@@ -3214,18 +3227,18 @@ Return t unless search stops due to end of buffer."
;; that the regexp below includes the last character of the
;; previous line.
(if (bobp)
- (or (looking-at "\n")
- (forward-char 1))
- (forward-char -1)
- (if (looking-at "\\`\n")
- (forward-char 1))))
+ (or (looking-at "\n")
+ (forward-char 1))
+ (forward-char -1)
+ (if (looking-at "\\`\n")
+ (forward-char 1))))
;; The regexp matches a function header that isn't
;; included in a string.
(and (re-search-forward "\\(\\`\\|\\`\n\\|[^\\]\n\\)\\(-?[a-z]\\|'\\|-\\)"
- nil 'move (- arg))
+ nil 'move (- arg))
(let ((beg (match-beginning 2)))
- (and beg (goto-char beg))
- t)))
+ (and beg (goto-char beg))
+ t)))
(defun erlang-end-of-clause (&optional arg)
"Move to the end of the current clause.
@@ -3233,18 +3246,16 @@ With argument, do this that many times."
(interactive "p")
(or arg (setq arg 1))
(while (and (looking-at "[ \t]*[%\n]")
- (zerop (forward-line 1))))
+ (zerop (forward-line 1))))
;; Move to the next clause.
(erlang-beginning-of-clause (- arg))
(beginning-of-line);; Just to be sure...
(let ((continue t))
(while (and (not (bobp)) continue)
(forward-line -1)
- (skip-chars-forward " \t")
- (if (looking-at "[%\n]")
- nil
- (end-of-line)
- (setq continue nil)))))
+ (unless (looking-at "[ \t]*[%\n]")
+ (end-of-line)
+ (setq continue nil)))))
(defun erlang-mark-clause ()
"Put mark at end of clause, point at beginning."
@@ -3273,22 +3284,22 @@ Return t unless search stops due to end of buffer."
;; Search backward
((> arg 0)
(while (and (> arg 0)
- (and (erlang-beginning-of-clause 1)
- (let ((start (point))
- (name (erlang-name-of-function))
- (arity (erlang-get-function-arity)))
- ;; Note: "arity" is nil for e.g. "-import", hence
- ;; two "-import" clauses are not considered to
- ;; be part of the same function.
- (while (and (erlang-beginning-of-clause 1)
- (string-equal name
- (erlang-name-of-function))
- arity
- (equal arity
- (erlang-get-function-arity)))
- (setq start (point)))
- (goto-char start)
- t)))
+ (and (erlang-beginning-of-clause 1)
+ (let ((start (point))
+ (name (erlang-name-of-function))
+ (arity (erlang-get-function-arity)))
+ ;; Note: "arity" is nil for e.g. "-import", hence
+ ;; two "-import" clauses are not considered to
+ ;; be part of the same function.
+ (while (and (erlang-beginning-of-clause 1)
+ (string-equal name
+ (erlang-name-of-function))
+ arity
+ (equal arity
+ (erlang-get-function-arity)))
+ (setq start (point)))
+ (goto-char start)
+ t)))
(setq arg (1- arg))))
;; Search forward
((< arg 0)
@@ -3296,19 +3307,19 @@ Return t unless search stops due to end of buffer."
(erlang-beginning-of-clause 1)
;; Step -arg functions forward.
(while (and (< arg 0)
- ;; Step one function forward, or stop if the end of
- ;; the buffer was reached. Return t if we found the
- ;; function.
- (let ((name (erlang-name-of-function))
- (arity (erlang-get-function-arity))
- (found (erlang-beginning-of-clause -1)))
- (while (and found
- (string-equal name (erlang-name-of-function))
- arity
- (equal arity
- (erlang-get-function-arity)))
- (setq found (erlang-beginning-of-clause -1)))
- found))
+ ;; Step one function forward, or stop if the end of
+ ;; the buffer was reached. Return t if we found the
+ ;; function.
+ (let ((name (erlang-name-of-function))
+ (arity (erlang-get-function-arity))
+ (found (erlang-beginning-of-clause -1)))
+ (while (and found
+ (string-equal name (erlang-name-of-function))
+ arity
+ (equal arity
+ (erlang-get-function-arity)))
+ (setq found (erlang-beginning-of-clause -1)))
+ found))
(setq arg (1+ arg)))))
(zerop arg))
@@ -3324,35 +3335,35 @@ With negative argument go towards the beginning of the buffer."
;; Forward
(while (and (> arg 0) (< (point) (point-max)))
(let ((pos (point)))
- (while (progn
- (if (and first
- (progn
- (forward-char 1)
- (erlang-beginning-of-clause 1)))
- nil
- (or (bobp) (forward-char -1))
- (erlang-beginning-of-clause -1))
- (setq first nil)
- (erlang-pass-over-function)
- (skip-chars-forward " \t")
- (if (looking-at "[%\n]")
- (forward-line 1))
- (<= (point) pos))))
+ (while (progn
+ (if (and first
+ (progn
+ (forward-char 1)
+ (erlang-beginning-of-clause 1)))
+ nil
+ (or (bobp) (forward-char -1))
+ (erlang-beginning-of-clause -1))
+ (setq first nil)
+ (erlang-pass-over-function)
+ (skip-chars-forward " \t")
+ (if (looking-at "[%\n]")
+ (forward-line 1))
+ (<= (point) pos))))
(setq arg (1- arg)))
;; Backward
(while (< arg 0)
(let ((pos (point)))
- (erlang-beginning-of-clause 1)
- (erlang-pass-over-function)
- (forward-line 1)
- (if (>= (point) pos)
- (if (erlang-beginning-of-function 2)
- (progn
- (erlang-pass-over-function)
- (skip-chars-forward " \t")
- (if (looking-at "[%\n]")
- (forward-line 1)))
- (goto-char (point-min)))))
+ (erlang-beginning-of-clause 1)
+ (erlang-pass-over-function)
+ (forward-line 1)
+ (if (>= (point) pos)
+ (if (erlang-beginning-of-function 2)
+ (progn
+ (erlang-pass-over-function)
+ (skip-chars-forward " \t")
+ (if (looking-at "[%\n]")
+ (forward-line 1)))
+ (goto-char (point-min)))))
(setq arg (1+ arg)))))
(eval-and-compile
@@ -3366,18 +3377,18 @@ With negative argument go towards the beginning of the buffer."
;; Sets the region. In Emacs 19 and XEmacs, we want to activate
;; the region.
(condition-case nil
- (push-mark (point) nil t)
- (error (push-mark (point))))
+ (push-mark (point) nil t)
+ (error (push-mark (point))))
(erlang-beginning-of-function 1)
;; The above function deactivates the mark.
(if (boundp 'deactivate-mark)
- (funcall (symbol-function 'set) 'deactivate-mark nil)))))
+ (funcall (symbol-function 'set) 'deactivate-mark nil)))))
(defun erlang-pass-over-function ()
(while (progn
- (erlang-skip-blank)
- (and (not (looking-at "\\.\\(\\s \\|\n\\|\\s<\\)"))
- (not (eobp))))
+ (erlang-skip-blank)
+ (and (not (looking-at "\\.\\(\\s \\|\n\\|\\s<\\)"))
+ (not (eobp))))
(forward-sexp 1))
(if (not (eobp))
(forward-char 1)))
@@ -3386,7 +3397,7 @@ With negative argument go towards the beginning of the buffer."
(save-excursion
;; Skip over attribute leader.
(if (looking-at "-[ \t]*")
- (re-search-forward "-[ \t]*" nil 'move))
+ (re-search-forward "-[ \t]*" nil 'move))
(let ((start (point)))
(forward-sexp 1)
(buffer-substring start (point)))))
@@ -3401,54 +3412,54 @@ paragraph of it that point is in, preserving the comment's indentation
and initial `%':s."
(interactive "P")
(let ((has-comment nil)
- ;; If has-comment, the appropriate fill-prefix for the comment.
- comment-fill-prefix)
+ ;; If has-comment, the appropriate fill-prefix for the comment.
+ comment-fill-prefix)
;; Figure out what kind of comment we are looking at.
(save-excursion
(beginning-of-line)
(cond
;; Find the command prefix.
((looking-at (concat "\\s *" comment-start-skip))
- (setq has-comment t)
- (setq comment-fill-prefix (buffer-substring (match-beginning 0)
- (match-end 0))))
+ (setq has-comment t)
+ (setq comment-fill-prefix (buffer-substring (match-beginning 0)
+ (match-end 0))))
;; A line with some code, followed by a comment? Remember that the
;; % which starts the comment shouldn't be part of a string or
;; character.
((progn
- (while (not (looking-at "%\\|$"))
- (skip-chars-forward "^%\n\"\\\\")
- (cond
- ((eq (char-after (point)) ?\\) (forward-char 2))
- ((eq (char-after (point)) ?\") (forward-sexp 1))))
- (looking-at comment-start-skip))
- (setq has-comment t)
- (setq comment-fill-prefix
- (concat (make-string (current-column) ? )
- (buffer-substring (match-beginning 0) (match-end 0)))))))
+ (while (not (looking-at "%\\|$"))
+ (skip-chars-forward "^%\n\"\\\\")
+ (cond
+ ((eq (char-after (point)) ?\\) (forward-char 2))
+ ((eq (char-after (point)) ?\") (forward-sexp 1))))
+ (looking-at comment-start-skip))
+ (setq has-comment t)
+ (setq comment-fill-prefix
+ (concat (make-string (current-column) ? )
+ (buffer-substring (match-beginning 0) (match-end 0)))))))
(if (not has-comment)
- (fill-paragraph justify)
+ (fill-paragraph justify)
;; Narrow to include only the comment, and then fill the region.
(save-restriction
- (narrow-to-region
- ;; Find the first line we should include in the region to fill.
- (save-excursion
- (while (and (zerop (forward-line -1))
- (looking-at "^\\s *%")))
- ;; We may have gone to far. Go forward again.
- (or (looking-at "^\\s *%")
- (forward-line 1))
- (point))
- ;; Find the beginning of the first line past the region to fill.
- (save-excursion
- (while (progn (forward-line 1)
- (looking-at "^\\s *%")))
- (point)))
- ;; Lines with only % on them can be paragraph boundaries.
- (let ((paragraph-start (concat paragraph-start "\\|^[ \t%]*$"))
- (paragraph-separate (concat paragraph-start "\\|^[ \t%]*$"))
- (fill-prefix comment-fill-prefix))
- (fill-paragraph justify))))))
+ (narrow-to-region
+ ;; Find the first line we should include in the region to fill.
+ (save-excursion
+ (while (and (zerop (forward-line -1))
+ (looking-at "^\\s *%")))
+ ;; We may have gone to far. Go forward again.
+ (or (looking-at "^\\s *%")
+ (forward-line 1))
+ (point))
+ ;; Find the beginning of the first line past the region to fill.
+ (save-excursion
+ (while (progn (forward-line 1)
+ (looking-at "^\\s *%")))
+ (point)))
+ ;; Lines with only % on them can be paragraph boundaries.
+ (let ((paragraph-start (concat paragraph-start "\\|^[ \t%]*$"))
+ (paragraph-separate (concat paragraph-start "\\|^[ \t%]*$"))
+ (fill-prefix comment-fill-prefix))
+ (fill-paragraph justify))))))
(defun erlang-uncomment-region (beg end)
@@ -3467,22 +3478,22 @@ first parenthesis is preserved. The point is placed between
the parentheses."
(interactive)
(let ((name (save-excursion
- (and (erlang-beginning-of-clause)
- (erlang-get-function-name t))))
- (arrow (save-excursion
- (and (erlang-beginning-of-clause)
- (erlang-get-function-arrow)))))
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-name t))))
+ (arrow (save-excursion
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-arrow)))))
(if (or (null arrow) (null name))
- (error "Can't find name of current Erlang function"))
+ (error "Can't find name of current Erlang function"))
(if (and (bolp) (eolp))
- nil
+ nil
(end-of-line)
(newline))
(insert name)
(save-excursion
(insert ") " arrow))
(if erlang-new-clause-with-arguments
- (erlang-clone-arguments))))
+ (erlang-clone-arguments))))
(defun erlang-clone-arguments ()
@@ -3492,12 +3503,12 @@ The mark is set at the beginning of the inserted text, the point
at the end."
(interactive)
(let ((args (save-excursion
- (beginning-of-line)
- (and (erlang-beginning-of-clause)
- (erlang-get-function-arguments))))
- (p (point)))
+ (beginning-of-line)
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-arguments))))
+ (p (point)))
(if (null args)
- (error "Can't clone argument list"))
+ (error "Can't clone argument list"))
(insert args)
(set-mark p)))
@@ -3520,18 +3531,18 @@ Return nil if file contains no `-module' attribute."
(widen)
(goto-char (point-min))
(let ((md (match-data)))
- (unwind-protect
- (if (re-search-forward
- (eval-when-compile
- (concat "^-module\\s *(\\s *\\(\\("
- erlang-atom-regexp
- "\\)?\\)\\s *)\\s *\\."))
- (point-max) t)
- (erlang-remove-quotes
- (erlang-buffer-substring (match-beginning 1)
- (match-end 1)))
- nil)
- (store-match-data md))))))
+ (unwind-protect
+ (if (re-search-forward
+ (eval-when-compile
+ (concat "^-module\\s *(\\s *\\(\\("
+ erlang-atom-regexp
+ "\\)?\\)\\s *)\\s *\\."))
+ (point-max) t)
+ (erlang-remove-quotes
+ (erlang-buffer-substring (match-beginning 1)
+ (match-end 1)))
+ nil)
+ (store-match-data md))))))
(defun erlang-get-module-from-file-name (&optional file)
@@ -3551,7 +3562,7 @@ tags system could be used by files written in other languages."
nil
(setq file (file-name-nondirectory file))
(if (string-match erlang-file-name-extension-regexp file)
- (substring file 0 (match-beginning 0))
+ (substring file 0 (match-beginning 0))
nil)))
@@ -3572,30 +3583,30 @@ corresponds to the order of the parsed Erlang list."
(erlang-skip-blank)
(forward-char 1)
(if (not (eq (preceding-char) ?\[))
- '() ; Not looking at an Erlang list.
- (while ; Note: `while' has no body.
- (progn
- (erlang-skip-blank)
- (and (looking-at (eval-when-compile
- (concat erlang-atom-regexp "/\\([0-9]+\\)\\>")))
- (progn
- (setq res (cons
- (cons
- (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 1) (match-end 1)))
- (erlang-string-to-int
- (erlang-buffer-substring
- (match-beginning
- (+ 1 erlang-atom-regexp-matches))
- (match-end
- (+ 1 erlang-atom-regexp-matches)))))
- res))
- (goto-char (match-end 0))
- (erlang-skip-blank)
- (forward-char 1)
- ;; Test if there are more exported functions.
- (eq (preceding-char) ?,))))))
+ '() ; Not looking at an Erlang list.
+ (while ; Note: `while' has no body.
+ (progn
+ (erlang-skip-blank)
+ (and (looking-at (eval-when-compile
+ (concat erlang-atom-regexp "/\\([0-9]+\\)\\>")))
+ (progn
+ (setq res (cons
+ (cons
+ (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 1) (match-end 1)))
+ (erlang-string-to-int
+ (erlang-buffer-substring
+ (match-beginning
+ (+ 1 erlang-atom-regexp-matches))
+ (match-end
+ (+ 1 erlang-atom-regexp-matches)))))
+ res))
+ (goto-char (match-end 0))
+ (erlang-skip-blank)
+ (forward-char 1)
+ ;; Test if there are more exported functions.
+ (eq (preceding-char) ?,))))))
(nreverse res)))
@@ -3607,14 +3618,14 @@ corresponds to the order of the parsed Erlang list."
(save-excursion
(goto-char (point-min))
(let ((md (match-data))
- (res '()))
+ (res '()))
(unwind-protect
- (progn
- (while (re-search-forward "^-export\\s *(" (point-max) t)
- (erlang-skip-blank)
- (setq res (nconc res (erlang-get-function-arity-list))))
- res)
- (store-match-data md)))))
+ (progn
+ (while (re-search-forward "^-export\\s *(" (point-max) t)
+ (erlang-skip-blank)
+ (setq res (nconc res (erlang-get-function-arity-list))))
+ res)
+ (store-match-data md)))))
(defun erlang-get-import ()
@@ -3625,30 +3636,30 @@ function and arity as cdr part."
(save-excursion
(goto-char (point-min))
(let ((md (match-data))
- (res '()))
+ (res '()))
(unwind-protect
- (progn
- (while (re-search-forward "^-import\\s *(" (point-max) t)
- (erlang-skip-blank)
- (if (looking-at erlang-atom-regexp)
- (let ((module (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 0)
- (match-end 0)))))
- (goto-char (match-end 0))
- (erlang-skip-blank)
- (if (eq (following-char) ?,)
- (progn
- (forward-char 1)
- (erlang-skip-blank)
- (let ((funcs (erlang-get-function-arity-list))
- (pair (assoc module res)))
- (if pair
- (setcdr pair (nconc (cdr pair) funcs))
- (setq res (cons (cons module funcs)
- res)))))))))
- (nreverse res))
- (store-match-data md)))))
+ (progn
+ (while (re-search-forward "^-import\\s *(" (point-max) t)
+ (erlang-skip-blank)
+ (if (looking-at erlang-atom-regexp)
+ (let ((module (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 0)
+ (match-end 0)))))
+ (goto-char (match-end 0))
+ (erlang-skip-blank)
+ (if (eq (following-char) ?,)
+ (progn
+ (forward-char 1)
+ (erlang-skip-blank)
+ (let ((funcs (erlang-get-function-arity-list))
+ (pair (assoc module res)))
+ (if pair
+ (setcdr pair (nconc (cdr pair) funcs))
+ (setq res (cons (cons module funcs)
+ res)))))))))
+ (nreverse res))
+ (store-match-data md)))))
(defun erlang-get-function-name (&optional arg)
@@ -3660,12 +3671,12 @@ the first `(' is returned.
Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
(save-excursion
(if (not (eobp)) (forward-char 1))
- (and (erlang-beginning-of-clause)
- (erlang-get-function-name t)))"
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-name t)))"
(let ((n (if arg 0 1)))
(and (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *(")))
- (erlang-buffer-substring (match-beginning n) (match-end n)))))
+ (concat "^" erlang-atom-regexp "\\s *(")))
+ (erlang-buffer-substring (match-beginning n) (match-end n)))))
(defun erlang-get-function-arrow ()
@@ -3674,9 +3685,9 @@ Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
(save-excursion
(if (not (eobp)) (forward-char 1))
- (and (erlang-beginning-of-clause)
- (erlang-get-function-arrow)))"
- (and
+ (and (erlang-beginning-of-clause)
+ (erlang-get-function-arrow)))"
+ (and
(save-excursion
(re-search-forward "->" (point-max) t)
(erlang-buffer-substring (- (point) 2) (+ (point) 1)))))
@@ -3684,33 +3695,33 @@ Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
(defun erlang-get-function-arity ()
"Return the number of arguments of function at point, or nil."
(and (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *(")))
+ (concat "^" erlang-atom-regexp "\\s *(")))
(save-excursion
- (goto-char (match-end 0))
- (condition-case nil
- (let ((res 0)
- (cont t))
- (while cont
- (cond ((eobp)
- (setq res nil)
- (setq cont nil))
- ((looking-at "\\s *)")
- (setq cont nil))
- ((looking-at "\\s *\\($\\|%\\)")
- (forward-line 1))
- ((looking-at "\\s *<<[^>]*?>>")
- (when (zerop res)
- (setq res (+ 1 res)))
- (goto-char (match-end 0)))
- ((looking-at "\\s *,")
- (setq res (+ 1 res))
- (goto-char (match-end 0)))
- (t
- (when (zerop res)
- (setq res (+ 1 res)))
- (forward-sexp 1))))
- res)
- (error nil)))))
+ (goto-char (match-end 0))
+ (condition-case nil
+ (let ((res 0)
+ (cont t))
+ (while cont
+ (cond ((eobp)
+ (setq res nil)
+ (setq cont nil))
+ ((looking-at "\\s *)")
+ (setq cont nil))
+ ((looking-at "\\s *\\($\\|%\\)")
+ (forward-line 1))
+ ((looking-at "\\s *<<[^>]*?>>")
+ (when (zerop res)
+ (setq res (+ 1 res)))
+ (goto-char (match-end 0)))
+ ((looking-at "\\s *,")
+ (setq res (+ 1 res))
+ (goto-char (match-end 0)))
+ (t
+ (when (zerop res)
+ (setq res (+ 1 res)))
+ (forward-sexp 1))))
+ res)
+ (error nil)))))
(defun erlang-get-function-name-and-arity ()
"Return the name and arity of the function at point, or nil.
@@ -3722,15 +3733,15 @@ The return value is a string of the form \"foo/1\"."
(defun erlang-get-function-arguments ()
"Return arguments of current function, or nil."
(if (not (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *("))))
+ (concat "^" erlang-atom-regexp "\\s *("))))
nil
(save-excursion
(condition-case nil
- (let ((start (match-end 0)))
- (goto-char (- start 1))
- (forward-sexp)
- (erlang-buffer-substring start (- (point) 1)))
- (error nil)))))
+ (let ((start (match-end 0)))
+ (goto-char (- start 1))
+ (forward-sexp)
+ (erlang-buffer-substring start (- (point) 1)))
+ (error nil)))))
(defun erlang-get-function-under-point ()
@@ -3747,37 +3758,37 @@ The following could be returned:
In the future the list may contain more elements."
(save-excursion
(let ((md (match-data))
- (res nil))
+ (res nil))
(if (eq (char-syntax (following-char)) ? )
- (skip-chars-backward " \t"))
+ (skip-chars-backward " \t"))
(skip-chars-backward "a-zA-Z0-9_:'")
(cond ((looking-at (eval-when-compile
- (concat erlang-atom-regexp ":" erlang-atom-regexp)))
- (setq res (list
- (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 1) (match-end 1)))
- (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning (1+ erlang-atom-regexp-matches))
- (match-end (1+ erlang-atom-regexp-matches)))))))
- ((looking-at erlang-atom-regexp)
- (let ((fk (erlang-remove-quotes
- (erlang-buffer-substring
- (match-beginning 0) (match-end 0))))
- (mod nil)
- (imports (erlang-get-import)))
- (while (and imports (null mod))
- (if (assoc fk (cdr (car imports)))
- (setq mod (car (car imports)))
- (setq imports (cdr imports))))
- (cond ((eq (preceding-char) ?#)
- (setq fk (concat "-record(" fk)))
- ((eq (preceding-char) ??)
- (setq fk (concat "-define(" fk)))
- ((and (null mod) (not (member fk erlang-int-bifs)))
- (setq mod (erlang-get-module))))
- (setq res (list mod fk)))))
+ (concat erlang-atom-regexp ":" erlang-atom-regexp)))
+ (setq res (list
+ (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 1) (match-end 1)))
+ (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning (1+ erlang-atom-regexp-matches))
+ (match-end (1+ erlang-atom-regexp-matches)))))))
+ ((looking-at erlang-atom-regexp)
+ (let ((fk (erlang-remove-quotes
+ (erlang-buffer-substring
+ (match-beginning 0) (match-end 0))))
+ (mod nil)
+ (imports (erlang-get-import)))
+ (while (and imports (null mod))
+ (if (assoc fk (cdr (car imports)))
+ (setq mod (car (car imports)))
+ (setq imports (cdr imports))))
+ (cond ((eq (preceding-char) ?#)
+ (setq fk (concat "-record(" fk)))
+ ((eq (preceding-char) ??)
+ (setq fk (concat "-define(" fk)))
+ ((and (null mod) (not (member fk erlang-int-bifs)))
+ (setq mod (erlang-get-module))))
+ (setq res (list mod fk)))))
(store-match-data md)
res)))
@@ -3788,11 +3799,11 @@ In the future the list may contain more elements."
"Return STR, possibly with quotes."
(let ((case-fold-search nil)) ; force string matching to be case sensitive
(if (and (stringp str)
- (not (string-match (eval-when-compile
- (concat "\\`" erlang-atom-regexp "\\'")) str)))
- (progn (if (fboundp 'replace-regexp-in-string)
- (setq str (replace-regexp-in-string "'" "\\'" str t t )))
- (concat "'" str "'"))
+ (not (string-match (eval-when-compile
+ (concat "\\`" erlang-atom-regexp "\\'")) str)))
+ (progn (if (fboundp 'replace-regexp-in-string)
+ (setq str (replace-regexp-in-string "'" "\\'" str t t )))
+ (concat "'" str "'"))
str)))
@@ -3800,9 +3811,9 @@ In the future the list may contain more elements."
"Return STR without quotes, if present."
(let ((md (match-data)))
(prog1
- (if (string-match "\\`'\\(.*\\)'\\'" str)
- (substring str 1 -1)
- str)
+ (if (string-match "\\`'\\(.*\\)'\\'" str)
+ (substring str 1 -1)
+ str)
(store-match-data md))))
(defun erlang-match-next-exported-function (max)
@@ -3872,30 +3883,30 @@ is prompted.
This function is normally placed in the hook `local-write-file-hooks'."
(if erlang-check-module-name
- (let ((mn (erlang-add-quotes-if-needed
- (erlang-get-module)))
- (fn (erlang-add-quotes-if-needed
- (erlang-get-module-from-file-name (buffer-file-name)))))
- (if (and (stringp mn) (stringp fn))
- (or (string-equal mn fn)
- (if (or (eq erlang-check-module-name t)
- (y-or-n-p
- "Module does not match file name. Modify source? "))
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (if (re-search-forward
- (eval-when-compile
- (concat "^-module\\s *(\\s *\\(\\("
- erlang-atom-regexp
- "\\)?\\)\\s *)\\s *\\."))
- (point-max) t)
- (progn
- (goto-char (match-beginning 1))
- (delete-region (match-beginning 1)
- (match-end 1))
- (insert fn))))))))))
+ (let ((mn (erlang-add-quotes-if-needed
+ (erlang-get-module)))
+ (fn (erlang-add-quotes-if-needed
+ (erlang-get-module-from-file-name (buffer-file-name)))))
+ (if (and (stringp mn) (stringp fn))
+ (or (string-equal mn fn)
+ (if (or (eq erlang-check-module-name t)
+ (y-or-n-p
+ "Module does not match file name. Modify source? "))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (if (re-search-forward
+ (eval-when-compile
+ (concat "^-module\\s *(\\s *\\(\\("
+ erlang-atom-regexp
+ "\\)?\\)\\s *)\\s *\\."))
+ (point-max) t)
+ (progn
+ (goto-char (match-beginning 1))
+ (delete-region (match-beginning 1)
+ (match-end 1))
+ (insert fn))))))))))
;; Must return nil since it is added to `local-write-file-hook'.
nil)
@@ -3921,13 +3932,13 @@ non-whitespace characters following the point on the current line."
(interactive "P")
(self-insert-command (prefix-numeric-value arg))
(if (or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-semicolon
- erlang-electric-commands)))
- (erlang-in-literal)
- (not (looking-at "\\s *\\(%.*\\)?$"))
- (null (erlang-test-criteria-list
- erlang-electric-semicolon-criteria)))
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-semicolon
+ erlang-electric-commands)))
+ (erlang-in-literal)
+ (not (looking-at "\\s *\\(%.*\\)?$"))
+ (null (erlang-test-criteria-list
+ erlang-electric-semicolon-criteria)))
(setq erlang-electric-newline-inhibit nil)
(setq erlang-electric-newline-inhibit t)
(undo-boundary)
@@ -3935,20 +3946,20 @@ non-whitespace characters following the point on the current line."
(end-of-line)
(newline)
(if (condition-case nil
- (progn (erlang-indent-line) t)
- (error (if (bolp) (delete-char -1))))
- (if (not (bolp))
- (save-excursion
- (insert " ->"))
- (condition-case nil
- (progn
- (erlang-generate-new-clause)
- (if erlang-electric-semicolon-insert-blank-lines
- (save-excursion
- (beginning-of-line)
- (newline
- erlang-electric-semicolon-insert-blank-lines))))
- (error (if (bolp) (delete-char -1))))))))
+ (progn (erlang-indent-line) t)
+ (error (if (bolp) (delete-char -1))))
+ (if (not (bolp))
+ (save-excursion
+ (insert " ->"))
+ (condition-case nil
+ (progn
+ (erlang-generate-new-clause)
+ (if erlang-electric-semicolon-insert-blank-lines
+ (save-excursion
+ (beginning-of-line)
+ (newline
+ erlang-electric-semicolon-insert-blank-lines))))
+ (error (if (bolp) (delete-char -1))))))))
(defun erlang-electric-comma (&optional arg)
@@ -3964,12 +3975,12 @@ non-whitespace characters following the point on the current line."
(self-insert-command (prefix-numeric-value arg))
(if (or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-comma erlang-electric-commands)))
- (erlang-in-literal)
- (not (looking-at "\\s *\\(%.*\\)?$"))
- (null (erlang-test-criteria-list
- erlang-electric-comma-criteria)))
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-comma erlang-electric-commands)))
+ (erlang-in-literal)
+ (not (looking-at "\\s *\\(%.*\\)?$"))
+ (null (erlang-test-criteria-list
+ erlang-electric-comma-criteria)))
(setq erlang-electric-newline-inhibit nil)
(setq erlang-electric-newline-inhibit t)
(undo-boundary)
@@ -3977,12 +3988,12 @@ non-whitespace characters following the point on the current line."
(end-of-line)
(newline)
(condition-case nil
- (erlang-indent-line)
+ (erlang-indent-line)
(error (if (bolp) (delete-char -1))))))
(defun erlang-electric-lt (&optional arg)
"Insert a less-than sign, and optionally mark it as an open paren."
-
+
(interactive "p")
(self-insert-command arg)
@@ -3992,48 +4003,48 @@ non-whitespace characters following the point on the current line."
(save-excursion
(backward-char 2)
(when (and (eq (char-after (point)) ?<)
- (not (eq (get-text-property (point) 'category)
- 'bitsyntax-open-inner)))
- ;; Then mark the two chars...
- (put-text-property (point) (1+ (point))
- 'category 'bitsyntax-open-outer)
- (forward-char 1)
- (put-text-property (point) (1+ (point))
- 'category 'bitsyntax-open-inner)
- ;;...and unmark any subsequent less-than chars.
- (forward-char 1)
- (while (eq (char-after (point)) ?<)
- (remove-text-properties (point) (1+ (point))
- '(category nil))
- (forward-char 1))))))
+ (not (eq (get-text-property (point) 'category)
+ 'bitsyntax-open-inner)))
+ ;; Then mark the two chars...
+ (put-text-property (point) (1+ (point))
+ 'category 'bitsyntax-open-outer)
+ (forward-char 1)
+ (put-text-property (point) (1+ (point))
+ 'category 'bitsyntax-open-inner)
+ ;;...and unmark any subsequent less-than chars.
+ (forward-char 1)
+ (while (eq (char-after (point)) ?<)
+ (remove-text-properties (point) (1+ (point))
+ '(category nil))
+ (forward-char 1))))))
(defun erlang-after-bitsyntax-close ()
"Return t if point is immediately after a bit-syntax close parenthesis (`>>')."
(and (>= (point) 3)
(save-excursion
- (backward-char 2)
- (and (eq (char-after (point)) ?>)
- (not (eq (get-text-property (point) 'category)
- 'bitsyntax-close-outer))))))
-
+ (backward-char 2)
+ (and (eq (char-after (point)) ?>)
+ (not (eq (get-text-property (point) 'category)
+ 'bitsyntax-close-outer))))))
+
(defun erlang-after-arrow ()
"Return true if point is immediately after a function arrow (`->')."
(and (>= (point) 2)
- (and
- (save-excursion
- (backward-char)
- (eq (char-before (point)) ?-))
- (or (not (listp erlang-electric-commands))
- (memq 'erlang-electric-gt
- erlang-electric-commands))
- (not (erlang-in-literal))
- (looking-at "\\s *\\(%.*\\)?$")
- (erlang-test-criteria-list erlang-electric-arrow-criteria))))
+ (and
+ (save-excursion
+ (backward-char)
+ (eq (char-before (point)) ?-))
+ (or (not (listp erlang-electric-commands))
+ (memq 'erlang-electric-gt
+ erlang-electric-commands))
+ (not (erlang-in-literal))
+ (looking-at "\\s *\\(%.*\\)?$")
+ (erlang-test-criteria-list erlang-electric-arrow-criteria))))
(defun erlang-electric-gt (&optional arg)
"Insert a greater-than sign, and optionally mark it as a close paren."
-
+
(interactive "p")
(self-insert-command arg)
@@ -4044,17 +4055,17 @@ non-whitespace characters following the point on the current line."
(save-excursion
;; Then mark the two chars...
(backward-char 2)
- (put-text-property (point) (1+ (point))
- 'category 'bitsyntax-close-inner)
+ (put-text-property (point) (1+ (point))
+ 'category 'bitsyntax-close-inner)
(forward-char)
(put-text-property (point) (1+ (point))
- 'category 'bitsyntax-close-outer)
+ 'category 'bitsyntax-close-outer)
;;...and unmark any subsequent greater-than chars.
(forward-char)
(while (eq (char-after (point)) ?>)
- (remove-text-properties (point) (1+ (point))
- '(category nil))
- (forward-char))))
+ (remove-text-properties (point) (1+ (point))
+ '(category nil))
+ (forward-char))))
;; Did we just write a function arrow (`->')?
((erlang-after-arrow)
@@ -4063,13 +4074,13 @@ non-whitespace characters following the point on the current line."
(end-of-line)
(newline)
(condition-case nil
- (erlang-indent-line)
- (error (if (bolp) (delete-char -1))))))
+ (erlang-indent-line)
+ (error (if (bolp) (delete-char -1))))))
;; Then it's just a plain greater-than.
(t
nil)))
-
+
(defun erlang-electric-arrow\ off (&optional arg)
"Insert a '>'-sign and possibly a new indented line.
@@ -4089,22 +4100,22 @@ After being split/merged into `erlang-after-arrow' and
(let ((prec (preceding-char)))
(self-insert-command (prefix-numeric-value arg))
(if (or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-arrow
- erlang-electric-commands)))
- (not (eq prec ?-))
- (erlang-in-literal)
- (not (looking-at "\\s *\\(%.*\\)?$"))
- (null (erlang-test-criteria-list
- erlang-electric-arrow-criteria)))
- (setq erlang-electric-newline-inhibit nil)
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-arrow
+ erlang-electric-commands)))
+ (not (eq prec ?-))
+ (erlang-in-literal)
+ (not (looking-at "\\s *\\(%.*\\)?$"))
+ (null (erlang-test-criteria-list
+ erlang-electric-arrow-criteria)))
+ (setq erlang-electric-newline-inhibit nil)
(setq erlang-electric-newline-inhibit t)
(undo-boundary)
(end-of-line)
(newline)
(condition-case nil
- (erlang-indent-line)
- (error (if (bolp) (delete-char -1)))))))
+ (erlang-indent-line)
+ (error (if (bolp) (delete-char -1)))))))
(defun erlang-electric-newline (&optional arg)
@@ -4119,30 +4130,30 @@ Should the previous command be another electric command we assume that
the user pressed newline out of old habit, hence we will do nothing."
(interactive "P")
(cond ((and (not arg)
- erlang-electric-newline-inhibit
- (memq last-command erlang-electric-newline-inhibit-list))
- ()) ; Do nothing!
- ((or arg
- (and (listp erlang-electric-commands)
- (not (memq 'erlang-electric-newline
- erlang-electric-commands)))
- (null (erlang-test-criteria-list
- erlang-electric-newline-criteria)))
- (newline (prefix-numeric-value arg)))
- (t
- (if (and comment-multi-line
- (save-excursion
- (beginning-of-line)
- (looking-at (concat "\\s *" comment-start-skip))))
- (let ((str (buffer-substring
- (or (match-end 1) (match-beginning 0))
- (min (match-end 0) (point)))))
- (newline)
- (undo-boundary)
- (insert str))
- (newline)
- (undo-boundary)
- (indent-according-to-mode)))))
+ erlang-electric-newline-inhibit
+ (memq last-command erlang-electric-newline-inhibit-list))
+ ()) ; Do nothing!
+ ((or arg
+ (and (listp erlang-electric-commands)
+ (not (memq 'erlang-electric-newline
+ erlang-electric-commands)))
+ (null (erlang-test-criteria-list
+ erlang-electric-newline-criteria)))
+ (newline (prefix-numeric-value arg)))
+ (t
+ (if (and comment-multi-line
+ (save-excursion
+ (beginning-of-line)
+ (looking-at (concat "\\s *" comment-start-skip))))
+ (let ((str (buffer-substring
+ (or (match-end 1) (match-beginning 0))
+ (min (match-end 0) (point)))))
+ (newline)
+ (undo-boundary)
+ (insert str))
+ (newline)
+ (undo-boundary)
+ (indent-according-to-mode)))))
(defun erlang-test-criteria-list (criteria)
@@ -4167,14 +4178,14 @@ Return t if criteria fulfilled, nil otherwise."
t
(save-excursion
(let ((answer nil))
- (while (and criteria (null answer))
- (if (eq (car criteria) t)
- (setq answer t)
- (setq answer (funcall (car criteria))))
- (setq criteria (cdr criteria)))
- (if (and answer (not (eq answer 'stop)))
- t
- nil)))))
+ (while (and criteria (null answer))
+ (if (eq (car criteria) t)
+ (setq answer t)
+ (setq answer (funcall (car criteria))))
+ (setq criteria (cdr criteria)))
+ (if (and answer (not (eq answer 'stop)))
+ t
+ nil)))))
(defun erlang-in-literal (&optional lim)
@@ -4185,11 +4196,11 @@ Should the point be inside none of the above mentioned types of
context, nil is returned."
(save-excursion
(let* ((lim (or lim (save-excursion
- (erlang-beginning-of-clause)
- (point))))
- (state (if (fboundp 'syntax-ppss) ; post Emacs 21.3
- (funcall (symbol-function 'syntax-ppss))
- (parse-partial-sexp lim (point)))))
+ (erlang-beginning-of-clause)
+ (point))))
+ (state (if (fboundp 'syntax-ppss) ; post Emacs 21.3
+ (funcall (symbol-function 'syntax-ppss))
+ (parse-partial-sexp lim (point)))))
(cond
((eq (nth 3 state) ?') 'atom)
((nth 3 state) 'string)
@@ -4203,7 +4214,7 @@ context, nil is returned."
This function is designed to be a member of a criteria list."
(eq (save-excursion (erlang-skip-blank) (point))
(save-excursion
- (erlang-beginning-of-function -1) (point))))
+ (erlang-beginning-of-function -1) (point))))
(defun erlang-at-end-of-clause-p ()
@@ -4212,7 +4223,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."
(eq (save-excursion (erlang-skip-blank) (point))
(save-excursion
- (erlang-beginning-of-clause -1) (point))))
+ (erlang-beginning-of-clause -1) (point))))
(defun erlang-stop-when-inside-argument-list ()
@@ -4224,22 +4235,22 @@ after `||', `stop' is not returned.
This function is designed to be a member of a criteria list."
(save-excursion
(condition-case nil
- (let ((orig-point (point))
- (state nil))
- (up-list -1)
- (if (not (eq (following-char) ?\[))
- 'stop
- ;; Do not return `stop' when inside a list comprehension
- ;; construction. (The point must be after `||').
- (while (< (point) orig-point)
+ (let ((orig-point (point))
+ (state nil))
+ (up-list -1)
+ (if (not (eq (following-char) ?\[))
+ 'stop
+ ;; Do not return `stop' when inside a list comprehension
+ ;; construction. (The point must be after `||').
+ (while (< (point) orig-point)
(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)))
- (error
+ (if (and (car state) (eq (car (car (car state))) '||))
+ nil
+ 'stop)))
+ (error
nil))))
@@ -4250,11 +4261,11 @@ This function is designed to be a member of a criteria list."
(save-excursion
(beginning-of-line)
(if (and (looking-at (eval-when-compile
- (concat "^" erlang-atom-regexp "\\s *(")))
- (not (looking-at
- (eval-when-compile
- (concat "^" erlang-atom-regexp ".*->")))))
- 'stop
+ (concat "^" erlang-atom-regexp "\\s *(")))
+ (not (looking-at
+ (eval-when-compile
+ (concat "^" erlang-atom-regexp ".*->")))))
+ 'stop
nil)))
@@ -4279,13 +4290,13 @@ A line containing only spaces and tabs is considered empty.
This function is designed to be a member of a criteria list."
(and erlang-next-lines-empty-threshold
(save-excursion
- (let ((left erlang-next-lines-empty-threshold)
- (cont t))
- (while (and cont (> left 0))
- (forward-line 1)
- (setq cont (looking-at "\\s *$"))
- (setq left (- left 1)))
- cont))))
+ (let ((left erlang-next-lines-empty-threshold)
+ (cont t))
+ (while (and cont (> left 0))
+ (forward-line 1)
+ (setq cont (looking-at "\\s *$"))
+ (setq left (- left 1)))
+ cont))))
(defun erlang-at-keyword-end-p ()
@@ -4304,9 +4315,9 @@ This function is designed to be a member of a criteria list."
(eval-when-compile
(if (or (featurep 'bytecomp)
- (featurep 'byte-compile))
+ (featurep 'byte-compile))
(progn
- (require 'etags))))
+ (require 'etags))))
;; Variables:
@@ -4352,26 +4363,26 @@ as on the old form `tag'.
In the completion list, `module:tag' and `module:' shows up.
-Call this function from an appropriate init file, or add it to
-Erlang mode hook with the commands:
- (add-hook 'erlang-mode-hook 'erlang-tags-init)
- (add-hook 'erlang-shell-mode-hook 'erlang-tags-init)
-
This function only works under Emacs 18 and Emacs 19. Currently, It
is not implemented under XEmacs. (Hint: The Emacs 19 etags module
works under XEmacs.)"
(interactive)
(cond ((= erlang-emacs-major-version 18)
- (require 'tags)
- (erlang-tags-define-keys (current-local-map))
- (setq erlang-tags-installed t))
- (t
- (require 'etags)
- ;; Test on a function available in the Emacs 19 version
- ;; of tags but not in the XEmacs version.
- (when (fboundp 'find-tag-noselect)
- (erlang-tags-define-keys (current-local-map))
- (setq erlang-tags-installed t)))))
+ (require 'tags)
+ (erlang-tags-define-keys (current-local-map))
+ (setq erlang-tags-installed t))
+ (t
+ (require 'etags)
+ (set (make-local-variable 'find-tag-default-function)
+ 'erlang-find-tag-for-completion)
+ (if (>= emacs-major-version 25)
+ (add-hook 'xref-backend-functions
+ #'erlang-etags--xref-backend nil t)
+ ;; Test on a function available in the Emacs 19 version
+ ;; of tags but not in the XEmacs version.
+ (when (fboundp 'find-tag-noselect)
+ (erlang-tags-define-keys (current-local-map))
+ (setq erlang-tags-installed t))))))
@@ -4386,11 +4397,11 @@ works under XEmacs.)"
(let ((alist erlang-tags-function-alist))
(while alist
(let* ((old (car (car alist)))
- (new (cdr (car alist)))
- (keys (append (where-is-internal old global-map))))
- (while keys
- (define-key map (car keys) new)
- (setq keys (cdr keys))))
+ (new (cdr (car alist)))
+ (keys (append (where-is-internal old global-map))))
+ (while keys
+ (define-key map (car keys) new)
+ (setq keys (cdr keys))))
(setq alist (cdr alist))))
;; Update the menu.
(erlang-menu-substitute erlang-menu-base-items erlang-tags-function-alist)
@@ -4403,11 +4414,11 @@ Search `-import' list of imported functions.
Single quotes are been stripped away."
(let ((mod-func (erlang-get-function-under-point)))
(cond ((null mod-func)
- nil)
- ((null (car mod-func))
- (nth 1 mod-func))
- (t
- (concat (car mod-func) ":" (nth 1 mod-func))))))
+ nil)
+ ((null (car mod-func))
+ (nth 1 mod-func))
+ (t
+ (concat (car mod-func) ":" (nth 1 mod-func))))))
;; Return `t' since it is used inside `tags-loop-form'.
@@ -4426,31 +4437,31 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(defun erlang-find-tag-other-window (tagname &optional next-p regexp-p)
"Like `find-tag-other-window' but aware of Erlang modules."
(interactive (erlang-tag-interactive
- "Find `module:tag' or `tag' other window: "))
+ "Find `module:tag' or `tag' other window: "))
;; This is to deal with the case where the tag is found in the
;; selected window's buffer; without this, point is moved in both
;; windows. To prevent this, we save the selected window's point
;; before doing find-tag-noselect, and restore it afterwards.
(let* ((window-point (window-point (selected-window)))
- (tagbuf (erlang-find-tag-noselect tagname next-p regexp-p))
- (tagpoint (progn (set-buffer tagbuf) (point))))
+ (tagbuf (erlang-find-tag-noselect tagname next-p regexp-p))
+ (tagpoint (progn (set-buffer tagbuf) (point))))
(set-window-point (prog1
- (selected-window)
- (switch-to-buffer-other-window tagbuf)
- ;; We have to set this new window's point; it
- ;; might already have been displaying a
- ;; different portion of tagbuf, in which case
- ;; switch-to-buffer-other-window doesn't set
- ;; the window's point from the buffer.
- (set-window-point (selected-window) tagpoint))
- window-point)))
+ (selected-window)
+ (switch-to-buffer-other-window tagbuf)
+ ;; We have to set this new window's point; it
+ ;; might already have been displaying a
+ ;; different portion of tagbuf, in which case
+ ;; switch-to-buffer-other-window doesn't set
+ ;; the window's point from the buffer.
+ (set-window-point (selected-window) tagpoint))
+ window-point)))
(defun erlang-find-tag-other-frame (tagname &optional next-p)
"Like `find-tag-other-frame' but aware of Erlang modules."
(interactive (erlang-tag-interactive
- "Find `module:tag' or `tag' other frame: "))
+ "Find `module:tag' or `tag' other frame: "))
(let ((pop-up-frames t))
(erlang-find-tag-other-window tagname next-p)))
@@ -4458,13 +4469,13 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(defun erlang-find-tag-regexp (regexp &optional next-p other-window)
"Like `find-tag-regexp' but aware of Erlang modules."
(interactive (if (fboundp 'find-tag-regexp)
- (erlang-tag-interactive
- "Find `module:regexp' or `regexp': ")
- (error "This version of Emacs can't find tags by regexps")))
+ (erlang-tag-interactive
+ "Find `module:regexp' or `regexp': ")
+ (error "This version of Emacs can't find tags by regexps")))
(funcall (if other-window
- 'erlang-find-tag-other-window
- 'erlang-find-tag)
- regexp next-p t))
+ 'erlang-find-tag-other-window
+ 'erlang-find-tag)
+ regexp next-p t))
;; Just like C-u M-. This could be added to the menu.
@@ -4473,7 +4484,7 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(interactive)
(let ((current-prefix-arg '(4)))
(if erlang-tags-installed
- (call-interactively 'erlang-find-tag)
+ (call-interactively 'erlang-find-tag)
(call-interactively 'find-tag))))
@@ -4485,9 +4496,9 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
;; without extension and directory matches the module.
;;
;; * `module:tag'
-;; Emacs 19: Replace test functions with functions aware of
-;; Erlang modules. Tricky because the etags system wasn't
-;; built for these kind of operations...
+;; Emacs 19: Replace test functions with functions aware of
+;; Erlang modules. Tricky because the etags system wasn't
+;; built for these kind of operations...
;;
;; Emacs 18: We loop over `find-tag' until we find a file
;; whose module matches the requested module. The
@@ -4506,78 +4517,78 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
;; know where to restart a tags command.
(if (boundp 'tags-loop-form)
(funcall (symbol-function 'set)
- 'tags-loop-form '(erlang-find-tag nil t)))
+ 'tags-loop-form '(erlang-find-tag nil t)))
(save-window-excursion
(cond
((string-match ":$" modtagname)
;; Only the module name was given. Read all files whose file name
;; match.
(let ((modname (substring modtagname 0 (match-beginning 0)))
- (file nil))
- (if (not next-p)
- (save-excursion
- (visit-tags-table-buffer)
- (setq erlang-tags-file-list
- (funcall (symbol-function 'tags-table-files)))))
- (while (null file)
- (or erlang-tags-file-list
- (save-excursion
- (if (and (featurep 'etags)
- (funcall
- (symbol-function 'visit-tags-table-buffer) 'same)
- (funcall
- (symbol-function 'visit-tags-table-buffer) t))
- (setq erlang-tags-file-list
- (funcall (symbol-function 'tags-table-files)))
- (error "No %stags containing %s" (if next-p "more " "")
- modtagname))))
- (if erlang-tags-file-list
- (let ((this-module (erlang-get-module-from-file-name
- (car erlang-tags-file-list))))
- (if (and (stringp this-module)
- (string= modname this-module))
- (setq file (car erlang-tags-file-list)))
- (setq erlang-tags-file-list (cdr erlang-tags-file-list)))))
- (set-buffer (or (get-file-buffer file)
- (find-file-noselect file)))))
+ (file nil))
+ (if (not next-p)
+ (save-excursion
+ (visit-tags-table-buffer)
+ (setq erlang-tags-file-list
+ (funcall (symbol-function 'tags-table-files)))))
+ (while (null file)
+ (or erlang-tags-file-list
+ (save-excursion
+ (if (and (featurep 'etags)
+ (funcall
+ (symbol-function 'visit-tags-table-buffer) 'same)
+ (funcall
+ (symbol-function 'visit-tags-table-buffer) t))
+ (setq erlang-tags-file-list
+ (funcall (symbol-function 'tags-table-files)))
+ (error "No %stags containing %s" (if next-p "more " "")
+ modtagname))))
+ (if erlang-tags-file-list
+ (let ((this-module (erlang-get-module-from-file-name
+ (car erlang-tags-file-list))))
+ (if (and (stringp this-module)
+ (string= modname this-module))
+ (setq file (car erlang-tags-file-list)))
+ (setq erlang-tags-file-list (cdr erlang-tags-file-list)))))
+ (set-buffer (or (get-file-buffer file)
+ (find-file-noselect file)))))
((string-match ":" modtagname)
(if (boundp 'find-tag-tag-order)
- ;; Method one: Add module-recognising functions to the
- ;; list of order functions. However, the tags system
- ;; from Emacs 18, and derives thereof (read: XEmacs)
- ;; hasn't got this feature.
- (progn
- (erlang-tags-install-module-check)
- (unwind-protect
- (funcall (symbol-function 'find-tag)
- modtagname next-p regexp-p)
- (erlang-tags-remove-module-check)))
- ;; Method two: Call the tags system until a file matching
- ;; the module is found. This could result in that many
- ;; files are read. (e.g. The tag "foo:file" will take a
- ;; while to process.)
- (let* ((modname (substring modtagname 0 (match-beginning 0)))
- (tagname (substring modtagname (match-end 0) nil))
- (last-tag tagname)
- file)
- (while
- (progn
- (funcall (symbol-function 'find-tag) tagname next-p regexp-p)
- (setq next-p t)
- ;; Determine the module form the file name. (The
- ;; alternative, to check `-module', would make this
- ;; code useless for non-Erlang programs.)
- (setq file (erlang-get-module-from-file-name buffer-file-name))
- (not (and (stringp file)
- (string= modname file))))))))
+ ;; Method one: Add module-recognising functions to the
+ ;; list of order functions. However, the tags system
+ ;; from Emacs 18, and derives thereof (read: XEmacs)
+ ;; hasn't got this feature.
+ (progn
+ (erlang-tags-install-module-check)
+ (unwind-protect
+ (funcall (symbol-function 'find-tag)
+ modtagname next-p regexp-p)
+ (erlang-tags-remove-module-check)))
+ ;; Method two: Call the tags system until a file matching
+ ;; the module is found. This could result in that many
+ ;; files are read. (e.g. The tag "foo:file" will take a
+ ;; while to process.)
+ (let* ((modname (substring modtagname 0 (match-beginning 0)))
+ (tagname (substring modtagname (match-end 0) nil))
+ (last-tag tagname)
+ file)
+ (while
+ (progn
+ (funcall (symbol-function 'find-tag) tagname next-p regexp-p)
+ (setq next-p t)
+ ;; Determine the module form the file name. (The
+ ;; alternative, to check `-module', would make this
+ ;; code useless for non-Erlang programs.)
+ (setq file (erlang-get-module-from-file-name buffer-file-name))
+ (not (and (stringp file)
+ (string= modname file))))))))
(t
(funcall (symbol-function 'find-tag) modtagname next-p regexp-p)))
- (current-buffer))) ; Return the new buffer.
+ (current-buffer))) ; Return the new buffer.
+
-
@@ -4594,18 +4605,18 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(require 'tags)))
(if current-prefix-arg
(list nil (if (< (prefix-numeric-value current-prefix-arg) 0)
- '-
- t))
+ '-
+ t))
(let* ((default (erlang-find-tag-default))
- (prompt (if default
- (format "%s(default %s) " prompt default)
- prompt))
- (spec (if (featurep 'etags)
- (completing-read prompt 'erlang-tags-complete-tag)
- (read-string prompt))))
+ (prompt (if default
+ (format "%s(default %s) " prompt default)
+ prompt))
+ (spec (if (featurep 'etags)
+ (completing-read prompt 'erlang-tags-complete-tag)
+ (read-string prompt))))
(list (if (equal spec "")
- (or default (error "There is no default tag"))
- spec)))))
+ (or default (error "There is no default tag"))
+ spec)))))
;; Search tag functions which are aware of Erlang modules. The tactic
@@ -4632,21 +4643,21 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(setq erlang-tags-orig-format-hooks
(symbol-value 'tags-table-format-hooks))
(funcall (symbol-function 'set) 'tags-table-format-hooks
- (cons 'erlang-tags-recognize-tags-table
- erlang-tags-orig-format-hooks))
+ (cons 'erlang-tags-recognize-tags-table
+ erlang-tags-orig-format-hooks))
(setq erlang-tags-buffer-list '())
- ))
-
+ ))
+
;; Install our functions in the TAGS files already resident.
(save-excursion
(let ((files (symbol-value 'tags-table-computed-list)))
(while files
- (if (stringp (car files))
- (if (get-file-buffer (car files))
- (progn
- (set-buffer (get-file-buffer (car files)))
- (erlang-tags-install-local))))
- (setq files (cdr files))))))
+ (if (stringp (car files))
+ (if (get-file-buffer (car files))
+ (progn
+ (set-buffer (get-file-buffer (car files)))
+ (erlang-tags-install-local))))
+ (setq files (cdr files))))))
(defun erlang-tags-install-local ()
@@ -4656,23 +4667,23 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
;; Mark this buffer as "installed" and record.
(set (make-local-variable 'erlang-tags-buffer-installed-p) t)
(setq erlang-tags-buffer-list
- (cons (current-buffer) erlang-tags-buffer-list))
+ (cons (current-buffer) erlang-tags-buffer-list))
;; Save the original values.
(set (make-local-variable 'erlang-tags-orig-tag-order)
- (symbol-value 'find-tag-tag-order))
+ (symbol-value 'find-tag-tag-order))
(set (make-local-variable 'erlang-tags-orig-regexp-tag-order)
- (symbol-value 'find-tag-regexp-tag-order))
+ (symbol-value 'find-tag-regexp-tag-order))
(set (make-local-variable 'erlang-tags-orig-search-function)
- (symbol-value 'find-tag-search-function))
+ (symbol-value 'find-tag-search-function))
(set (make-local-variable 'erlang-tags-orig-regexp-search-function)
- (symbol-value 'find-tag-regexp-search-function))
+ (symbol-value 'find-tag-regexp-search-function))
;; Install our own functions.
(set (make-local-variable 'find-tag-search-function)
- 'erlang-tags-search-forward)
+ 'erlang-tags-search-forward)
(set (make-local-variable 'find-tag-regexp-search-function)
- 'erlang-tags-regexp-search-forward)
+ 'erlang-tags-regexp-search-forward)
(set (make-local-variable 'find-tag-tag-order)
(mapcar #'erlang-make-order-function-aware-of-modules
erlang-tags-orig-tag-order))
@@ -4700,13 +4711,13 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(cond
((>= erlang-emacs-major-version 20)
(funcall (symbol-function 'set)
- 'tags-table-format-functions
- erlang-tags-orig-format-functions)
+ 'tags-table-format-functions
+ erlang-tags-orig-format-functions)
)
- (t
+ (t
(funcall (symbol-function 'set)
- 'tags-table-format-hooks
- erlang-tags-orig-format-hooks)
+ 'tags-table-format-hooks
+ erlang-tags-orig-format-hooks)
))
;; Remove our functions from the TAGS files. (Note that
@@ -4715,11 +4726,11 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
(save-excursion
(let ((buffers erlang-tags-buffer-list))
(while buffers
- (if (buffer-name (car buffers))
- (progn
- (set-buffer (car buffers))
- (erlang-tags-remove-local)))
- (setq buffers (cdr buffers))))))
+ (if (buffer-name (car buffers))
+ (progn
+ (set-buffer (car buffers))
+ (erlang-tags-remove-local)))
+ (setq buffers (cdr buffers))))))
(defun erlang-tags-remove-local ()
@@ -4728,14 +4739,14 @@ Tags can be given on the forms `tag', `module:', `module:tag'."
()
(funcall (symbol-function 'set) 'erlang-tags-buffer-installed-p nil)
(funcall (symbol-function 'set)
- 'find-tag-tag-order erlang-tags-orig-tag-order)
+ 'find-tag-tag-order erlang-tags-orig-tag-order)
(funcall (symbol-function 'set)
- 'find-tag-regexp-tag-order erlang-tags-orig-regexp-tag-order)
+ 'find-tag-regexp-tag-order erlang-tags-orig-regexp-tag-order)
(funcall (symbol-function 'set)
- 'find-tag-search-function erlang-tags-orig-search-function)
+ 'find-tag-search-function erlang-tags-orig-search-function)
(funcall (symbol-function 'set)
- 'find-tag-regexp-search-function
- erlang-tags-orig-regexp-search-function)))
+ 'find-tag-regexp-search-function
+ erlang-tags-orig-regexp-search-function)))
(defun erlang-tags-recognize-tags-table ()
@@ -4764,10 +4775,10 @@ for a tag on the form `module:tag'."
(if (string-match ":" tag)
(setq tag (substring tag (match-end 0) nil)))
(if (eq erlang-tags-orig-regexp-search-function
- 'erlang-tags-regexp-search-forward)
+ 'erlang-tags-regexp-search-forward)
(re-search-forward tag bound noerror count)
(funcall erlang-tags-orig-regexp-search-function
- tag bound noerror count)))
+ tag bound noerror count)))
;;; Tags completion, Emacs 19 `etags' specific.
;;;
@@ -4775,8 +4786,6 @@ for a tag on the form `module:tag'."
;;; completion-table' containing all normal tags plus tags on the form
;;; `module:tag' and `module:'.
-;; PENDING - Should probably make use of the
-;; `completion-at-point-functions' hook instead of this advice.
(when (and (locate-library "etags")
(require 'etags)
(fboundp 'etags-tags-completion-table)
@@ -4784,11 +4793,7 @@ for a tag on the form `module:tag'."
(if (fboundp 'advice-add)
;; Emacs 24.4+
(advice-add 'etags-tags-completion-table :around
- (lambda (oldfun)
- (if erlang-replace-etags-tags-completion-table
- (erlang-etags-tags-completion-table)
- (funcall oldfun)))
- (list :name 'erlang-replace-tags-table))
+ #'erlang-etags-tags-completion-table-advice)
;; Emacs 23.1-24.3
(defadvice etags-tags-completion-table (around
erlang-replace-tags-table
@@ -4797,6 +4802,11 @@ for a tag on the form `module:tag'."
(setq ad-return-value (erlang-etags-tags-completion-table))
ad-do-it))))
+(defun erlang-etags-tags-completion-table-advice (oldfun)
+ (if erlang-replace-etags-tags-completion-table
+ (erlang-etags-tags-completion-table)
+ (funcall oldfun)))
+
(defun erlang-complete-tag ()
"Perform tags completion on the text around point.
Completes to the set of names listed in the current tags table.
@@ -4807,26 +4817,25 @@ about Erlang modules."
(condition-case nil
(require 'etags)
(error nil))
- (cond ((and erlang-tags-installed
- (fboundp 'etags-tags-completion-table)
+ (cond ((and (fboundp 'etags-tags-completion-table)
(fboundp 'tags-lazy-completion-table)) ; Emacs 23.1+
(let ((erlang-replace-etags-tags-completion-table t))
(complete-tag)))
((and erlang-tags-installed
(fboundp 'complete-tag)
(fboundp 'tags-complete-tag)) ; Emacs 19-22
- (let ((orig-tags-complete-tag (symbol-function 'tags-complete-tag)))
- (fset 'tags-complete-tag
- (symbol-function 'erlang-tags-complete-tag))
- (unwind-protect
+ (let ((orig-tags-complete-tag (symbol-function 'tags-complete-tag)))
+ (fset 'tags-complete-tag
+ (symbol-function 'erlang-tags-complete-tag))
+ (unwind-protect
(complete-tag)
- (fset 'tags-complete-tag orig-tags-complete-tag))))
- ((fboundp 'complete-tag) ; Emacs 19
+ (fset 'tags-complete-tag orig-tags-complete-tag))))
+ ((fboundp 'complete-tag) ; Emacs 19
(complete-tag))
- ((fboundp 'tag-complete-symbol) ; XEmacs
- (funcall (symbol-function 'tag-complete-symbol)))
- (t
- (error "This version of Emacs can't complete tags"))))
+ ((fboundp 'tag-complete-symbol) ; XEmacs
+ (funcall (symbol-function 'tag-complete-symbol)))
+ (t
+ (error "This version of Emacs can't complete tags"))))
(defun erlang-find-tag-for-completion ()
@@ -4850,9 +4859,9 @@ about Erlang modules."
;; If we need to ask for the tag table, allow that.
(let ((enable-recursive-minibuffers t))
(visit-tags-table-buffer))
- (if (eq what t)
- (all-completions string (erlang-tags-completion-table) predicate)
- (try-completion string (erlang-tags-completion-table) predicate)))))
+ (if (eq what t)
+ (all-completions string (erlang-tags-completion-table) predicate)
+ (try-completion string (erlang-tags-completion-table) predicate)))))
;; `tags-completion-table' calls itself recursively, make it
@@ -4862,22 +4871,22 @@ about Erlang modules."
(defun erlang-tags-completion-table ()
"Build completion table. Tags on the form `tag' or `module:tag'."
(setq erlang-tags-orig-completion-table
- (symbol-function 'tags-completion-table))
+ (symbol-function 'tags-completion-table))
(fset 'tags-completion-table
- (symbol-function 'erlang-tags-completion-table-1))
+ (symbol-function 'erlang-tags-completion-table-1))
(unwind-protect
(erlang-tags-completion-table-1)
(fset 'tags-completion-table
- erlang-tags-orig-completion-table)))
+ erlang-tags-orig-completion-table)))
(defun erlang-tags-completion-table-1 ()
(make-local-variable 'erlang-tags-completion-table)
(or erlang-tags-completion-table
(let ((tags-completion-table nil)
- (tags-completion-table-function
- 'erlang-etags-tags-completion-table))
- (funcall erlang-tags-orig-completion-table)
- (setq erlang-tags-completion-table tags-completion-table))))
+ (tags-completion-table-function
+ 'erlang-etags-tags-completion-table))
+ (funcall erlang-tags-orig-completion-table)
+ (setq erlang-tags-completion-table tags-completion-table))))
@@ -4978,7 +4987,7 @@ about Erlang modules."
(cl-defmethod xref-backend-identifier-completion-table
((_backend (eql erlang-etags)))
(let ((erlang-replace-etags-tags-completion-table t))
- (tags-completion-table))))))
+ (tags-completion-table))))))
@@ -5213,44 +5222,36 @@ The following special commands are available:
(setq comint-input-ignoredups t)
(setq comint-scroll-show-maximum-output t)
(setq comint-scroll-to-bottom-on-output t)
- ;; In Emacs 19.30, `add-hook' has got a `local' flag, use it. If
- ;; the call fails, just call the normal `add-hook'.
- (condition-case nil
- (progn
- (add-hook 'comint-output-filter-functions
- 'inferior-erlang-strip-delete nil t)
- (add-hook 'comint-output-filter-functions
- 'inferior-erlang-strip-ctrl-m nil t))
- (error
- (funcall (symbol-function 'make-local-hook)
- 'comint-output-filter-functions) ; obsolete as of Emacs 21.1
- (add-hook 'comint-output-filter-functions 'inferior-erlang-strip-delete)
- (add-hook 'comint-output-filter-functions 'inferior-erlang-strip-ctrl-m)))
+ (add-hook 'comint-output-filter-functions
+ 'inferior-erlang-strip-delete nil t)
+ (add-hook 'comint-output-filter-functions
+ 'inferior-erlang-strip-ctrl-m nil t)
;; Some older versions of comint don't have an input ring.
(if (fboundp 'comint-read-input-ring)
(progn
- (setq comint-input-ring-file-name erlang-input-ring-file-name)
- (comint-read-input-ring t)
- (make-local-variable 'kill-buffer-hook)
- (add-hook 'kill-buffer-hook 'comint-write-input-ring)))
+ (setq comint-input-ring-file-name erlang-input-ring-file-name)
+ (comint-read-input-ring t)
+ (make-local-variable 'kill-buffer-hook)
+ (add-hook 'kill-buffer-hook 'comint-write-input-ring)))
;; At least in Emacs 21, we need to be in `compilation-minor-mode'
;; for `next-error' to work. We can avoid it clobbering the shell
;; keys thus.
(when inferior-erlang-use-cmm
(compilation-minor-mode 1)
(set (make-local-variable 'minor-mode-overriding-map-alist)
- `((compilation-minor-mode
- . ,(let ((map (make-sparse-keymap)))
- ;; It would be useful to put keymap properties on the
- ;; error lines so that we could use RET and mouse-2
- ;; on them directly.
- (when (boundp 'compilation-skip-threshold) ; new compile.el
- (define-key map [mouse-2] #'erlang-mouse-2-command)
- (define-key map "\C-m" #'erlang-RET-command))
- (if (boundp 'compilation-menu-map)
- (define-key map [menu-bar compilation]
- (cons "Errors" compilation-menu-map)))
- map)))))
+ `((compilation-minor-mode
+ . ,(let ((map (make-sparse-keymap)))
+ ;; It would be useful to put keymap properties on the
+ ;; error lines so that we could use RET and mouse-2
+ ;; on them directly.
+ (when (boundp 'compilation-skip-threshold) ; new compile.el
+ (define-key map [mouse-2] #'erlang-mouse-2-command)
+ (define-key map "\C-m" #'erlang-RET-command))
+ (if (boundp 'compilation-menu-map)
+ (define-key map [menu-bar compilation]
+ (cons "Errors" compilation-menu-map)))
+ map)))))
+ (erlang-tags-init)
(run-hooks 'erlang-shell-mode-hook))
@@ -5259,9 +5260,9 @@ The following special commands are available:
Selects Comint or Compilation mode command as appropriate."
(interactive "e")
(if (save-window-excursion
- (save-excursion
- (mouse-set-point event)
- (consp (get-text-property (line-beginning-position) 'message))))
+ (save-excursion
+ (mouse-set-point event)
+ (consp (get-text-property (line-beginning-position) 'message))))
(call-interactively (lookup-key compilation-mode-map [mouse-2]))
(call-interactively (lookup-key comint-mode-map [mouse-2]))))
@@ -5277,7 +5278,7 @@ Selects Comint or Compilation mode command as appropriate."
(define-key map "\M-\t" 'erlang-complete-tag)
(define-key map "\C-a" 'comint-bol) ; Normally the other way around.
(define-key map "\C-c\C-a" 'beginning-of-line)
- (define-key map "\C-d" nil) ; Was `comint-delchar-or-maybe-eof'
+ (define-key map "\C-d" nil) ; Was `comint-delchar-or-maybe-eof'
(define-key map "\M-\C-m" 'compile-goto-error)
(unless inferior-erlang-use-cmm
(define-key map "\C-x`" 'erlang-next-error)))
@@ -5351,8 +5352,8 @@ editing control characters:
(when current-prefix-arg
(list (if (fboundp 'read-shell-command)
;; `read-shell-command' is a new function in Emacs 23.
- (read-shell-command "Erlang command: ")
- (read-string "Erlang command: ")))))
+ (read-shell-command "Erlang command: ")
+ (read-string "Erlang command: ")))))
(require 'comint)
(let (cmd opts)
(if command
@@ -5379,16 +5380,16 @@ editing control characters:
(setq list-buffers-directory fake-file-name))))
(setq inferior-erlang-process
- (get-buffer-process inferior-erlang-buffer))
- (if (> 21 erlang-emacs-major-version) ; funcalls to avoid compiler warnings
- (funcall (symbol-function 'set-process-query-on-exit-flag)
- inferior-erlang-process nil)
+ (get-buffer-process inferior-erlang-buffer))
+ (if (> 21 erlang-emacs-major-version) ; funcalls to avoid compiler warnings
+ (funcall (symbol-function 'set-process-query-on-exit-flag)
+ inferior-erlang-process nil)
(funcall (symbol-function 'process-kill-without-query) inferior-erlang-process))
(if erlang-inferior-shell-split-window
(switch-to-buffer-other-window inferior-erlang-buffer)
- (switch-to-buffer inferior-erlang-buffer))
+ (switch-to-buffer inferior-erlang-buffer))
(if (and (not (eq system-type 'windows-nt))
- (eq inferior-erlang-shell-type 'newshell))
+ (eq inferior-erlang-shell-type 'newshell))
(setq comint-process-echoes t))
(erlang-shell-mode))
@@ -5420,22 +5421,22 @@ frame will become deselected before the next command."
(or (inferior-erlang-running-p)
(error "No inferior Erlang process is running"))
(let ((win (inferior-erlang-window
- inferior-erlang-display-buffer-any-frame))
- (frames-p (fboundp 'selected-frame)))
+ inferior-erlang-display-buffer-any-frame))
+ (frames-p (fboundp 'selected-frame)))
(if (null win)
- (let ((old-win (selected-window)))
- (save-excursion
- (switch-to-buffer-other-window inferior-erlang-buffer)
- (setq win (selected-window)))
- (select-window old-win))
+ (let ((old-win (selected-window)))
+ (save-excursion
+ (switch-to-buffer-other-window inferior-erlang-buffer)
+ (setq win (selected-window)))
+ (select-window old-win))
(if (and window-system
- frames-p
- (or select
- (eq inferior-erlang-display-buffer-any-frame 'raise))
- (not (eq (selected-frame) (window-frame win))))
- (raise-frame (window-frame win))))
+ frames-p
+ (or select
+ (eq inferior-erlang-display-buffer-any-frame 'raise))
+ (not (eq (selected-frame) (window-frame win))))
+ (raise-frame (window-frame win))))
(if select
- (select-window win))
+ (select-window win))
(sit-for 0)
win))
@@ -5452,8 +5453,8 @@ frame will become deselected before the next command."
"Return the window containing the inferior Erlang, or nil."
(and (inferior-erlang-running-p)
(if (and all-frames (>= erlang-emacs-major-version 19))
- (get-buffer-window inferior-erlang-buffer t)
- (get-buffer-window inferior-erlang-buffer))))
+ (get-buffer-window inferior-erlang-buffer t)
+ (get-buffer-window inferior-erlang-buffer))))
(defun inferior-erlang-wait-prompt ()
@@ -5461,21 +5462,21 @@ frame will become deselected before the next command."
(if (eq inferior-erlang-prompt-timeout t)
()
(or (inferior-erlang-running-p)
- (error "No inferior Erlang shell is running"))
+ (error "No inferior Erlang shell is running"))
(with-current-buffer inferior-erlang-buffer
(let ((msg nil))
- (while (save-excursion
- (goto-char (process-mark inferior-erlang-process))
- (forward-line 0)
- (not (looking-at comint-prompt-regexp)))
- (if msg
- ()
- (setq msg t)
- (message "Waiting for Erlang shell prompt (press C-g to abort)."))
- (or (accept-process-output inferior-erlang-process
- inferior-erlang-prompt-timeout)
- (error "No Erlang shell prompt before timeout")))
- (if msg (message ""))))))
+ (while (save-excursion
+ (goto-char (process-mark inferior-erlang-process))
+ (forward-line 0)
+ (not (looking-at comint-prompt-regexp)))
+ (if msg
+ ()
+ (setq msg t)
+ (message "Waiting for Erlang shell prompt (press C-g to abort)."))
+ (or (accept-process-output inferior-erlang-process
+ inferior-erlang-prompt-timeout)
+ (error "No Erlang shell prompt before timeout")))
+ (if msg (message ""))))))
(defun inferior-erlang-send-empty-cmd-unless-already-at-prompt ()
"If not already at a prompt, try to send an empty cmd to get a prompt.
@@ -5484,12 +5485,12 @@ situations, for instance if a crash or error report from sasl
has been printed after the last prompt."
(with-current-buffer inferior-erlang-buffer
(if (> (point-max) 1)
- ;; make sure we get a prompt if buffer contains data
- (if (save-excursion
- (goto-char (process-mark inferior-erlang-process))
- (forward-line 0)
- (not (looking-at comint-prompt-regexp)))
- (inferior-erlang-send-command "")))))
+ ;; make sure we get a prompt if buffer contains data
+ (if (save-excursion
+ (goto-char (process-mark inferior-erlang-process))
+ (forward-line 0)
+ (not (looking-at comint-prompt-regexp)))
+ (inferior-erlang-send-command "")))))
(autoload 'comint-send-input "comint")
@@ -5506,10 +5507,10 @@ Return the position after the newly inserted command."
(or (inferior-erlang-running-p)
(error "No inferior Erlang process is running"))
(let ((old-buffer (current-buffer))
- (insert-point (marker-position (process-mark inferior-erlang-process)))
- (insert-length (if comint-process-echoes
- 0
- (1+ (length cmd)))))
+ (insert-point (marker-position (process-mark inferior-erlang-process)))
+ (insert-length (if comint-process-echoes
+ 0
+ (1+ (length cmd)))))
(set-buffer inferior-erlang-buffer)
(goto-char insert-point)
(insert cmd)
@@ -5522,21 +5523,21 @@ Return the position after the newly inserted command."
;; This was previously cautioned against in the Lisp manual. It
;; has been sorted out in Emacs 21. -- fx
(let ((comint-eol-on-send nil)
- (comint-input-filter (if hist comint-input-filter 'ignore)))
+ (comint-input-filter (if hist comint-input-filter 'ignore)))
(if (and (not erlang-xemacs-p)
- (>= emacs-major-version 22))
- (comint-send-input nil t)
- (comint-send-input)))
+ (>= emacs-major-version 22))
+ (comint-send-input nil t)
+ (comint-send-input)))
;; Adjust all windows whose points are incorrect.
(if (null comint-process-echoes)
- (walk-windows
- (function
- (lambda (window)
- (if (and (eq (window-buffer window) inferior-erlang-buffer)
- (= (window-point window) insert-point))
- (set-window-point window
- (+ insert-point insert-length)))))
- nil t))
+ (walk-windows
+ (function
+ (lambda (window)
+ (if (and (eq (window-buffer window) inferior-erlang-buffer)
+ (= (window-point window) insert-point))
+ (set-window-point window
+ (+ insert-point insert-length)))))
+ nil t))
(set-buffer old-buffer)
(+ insert-point insert-length)))
@@ -5545,17 +5546,17 @@ Return the position after the newly inserted command."
"Remove `^H' (delete) and the characters it was supposed to remove."
(interactive)
(if (and (boundp 'comint-last-input-end)
- (boundp 'comint-last-output-start))
+ (boundp 'comint-last-output-start))
(save-excursion
- (goto-char
- (if (erlang-interactive-p)
- (symbol-value 'comint-last-input-end)
- (symbol-value 'comint-last-output-start)))
- (while (progn (skip-chars-forward "^\C-h")
- (not (eq (point) (point-max))))
- (delete-char 1)
- (or (bolp)
- (backward-delete-char 1))))))
+ (goto-char
+ (if (erlang-interactive-p)
+ (symbol-value 'comint-last-input-end)
+ (symbol-value 'comint-last-output-start)))
+ (while (progn (skip-chars-forward "^\C-h")
+ (not (eq (point) (point-max))))
+ (delete-char 1)
+ (or (bolp)
+ (backward-delete-char 1))))))
;; Basically `comint-strip-ctrl-m', with a few extra checks.
@@ -5563,15 +5564,15 @@ Return the position after the newly inserted command."
"Strip trailing `^M' characters from the current output group."
(interactive)
(if (and (boundp 'comint-last-input-end)
- (boundp 'comint-last-output-start))
+ (boundp 'comint-last-output-start))
(let ((pmark (process-mark (get-buffer-process (current-buffer)))))
- (save-excursion
- (goto-char
- (if (erlang-interactive-p)
- (symbol-value 'comint-last-input-end)
- (symbol-value 'comint-last-output-start)))
- (while (re-search-forward "\r+$" pmark t)
- (replace-match "" t t))))))
+ (save-excursion
+ (goto-char
+ (if (erlang-interactive-p)
+ (symbol-value 'comint-last-input-end)
+ (symbol-value 'comint-last-output-start)))
+ (while (re-search-forward "\r+$" pmark t)
+ (replace-match "" t t))))))
(defun inferior-erlang-compile (arg)
@@ -5594,18 +5595,18 @@ There exists two workarounds for this bug:
(save-some-buffers)
(inferior-erlang-prepare-for-input)
(let* ((dir (inferior-erlang-compile-outdir))
- (noext (substring (erlang-local-buffer-file-name) 0 -4))
- (opts (append (list (cons 'outdir dir))
- (if current-prefix-arg
- (list 'debug_info 'export_all))
- erlang-compile-extra-opts))
- end)
+ (noext (substring (erlang-local-buffer-file-name) 0 -4))
+ (opts (append (list (cons 'outdir dir))
+ (if current-prefix-arg
+ (list 'debug_info 'export_all))
+ erlang-compile-extra-opts))
+ end)
(with-current-buffer inferior-erlang-buffer
(when (fboundp 'compilation-forget-errors)
(compilation-forget-errors)))
(setq end (inferior-erlang-send-command
- (inferior-erlang-compute-compile-command noext opts)
- nil))
+ (inferior-erlang-compute-compile-command noext opts)
+ nil))
(sit-for 0)
(inferior-erlang-wait-prompt)
(with-current-buffer inferior-erlang-buffer
@@ -5619,7 +5620,7 @@ The buffer is displayed, according to `inferior-erlang-display-buffer'
unless the optional NO-DISPLAY is non-nil."
(or (inferior-erlang-running-p)
(save-excursion
- (inferior-erlang)))
+ (inferior-erlang)))
(or (inferior-erlang-running-p)
(error "Error starting inferior Erlang shell"))
(if (not no-display)
@@ -5631,96 +5632,96 @@ unless the optional NO-DISPLAY is non-nil."
(defun inferior-erlang-compile-outdir ()
"Return the directory to compile the current buffer into."
(let* ((buffer-dir (directory-file-name
- (file-name-directory (erlang-local-buffer-file-name))))
- (parent-dir (directory-file-name
- (file-name-directory buffer-dir)))
+ (file-name-directory (erlang-local-buffer-file-name))))
+ (parent-dir (directory-file-name
+ (file-name-directory buffer-dir)))
(ebin-dir (concat (file-name-as-directory parent-dir) "ebin"))
- (buffer-dir-base-name (file-name-nondirectory
- (expand-file-name
- (concat (file-name-as-directory buffer-dir)
- ".")))))
+ (buffer-dir-base-name (file-name-nondirectory
+ (expand-file-name
+ (concat (file-name-as-directory buffer-dir)
+ ".")))))
(if (and (string= buffer-dir-base-name "src")
- (file-directory-p ebin-dir))
- (file-name-as-directory ebin-dir)
+ (file-directory-p ebin-dir))
+ (file-name-as-directory ebin-dir)
(file-name-as-directory buffer-dir))))
(defun inferior-erlang-compute-compile-command (module-name opts)
(let ((ccfn erlang-compile-command-function-alist)
- (res (inferior-erlang-compute-erl-compile-command module-name opts))
- ccfn-entry
- done
+ (res (inferior-erlang-compute-erl-compile-command module-name opts))
+ ccfn-entry
+ done
result)
(if (not (null (erlang-local-buffer-file-name)))
- (while (and (not done) (not (null ccfn)))
- (setq ccfn-entry (car ccfn))
- (setq ccfn (cdr ccfn))
- (if (string-match (car ccfn-entry) (erlang-local-buffer-file-name))
- (let ((c-fn (cdr ccfn-entry)))
- (setq done t)
- (if (not (null c-fn))
- (setq result (funcall c-fn module-name opts)))))))
+ (while (and (not done) (not (null ccfn)))
+ (setq ccfn-entry (car ccfn))
+ (setq ccfn (cdr ccfn))
+ (if (string-match (car ccfn-entry) (erlang-local-buffer-file-name))
+ (let ((c-fn (cdr ccfn-entry)))
+ (setq done t)
+ (if (not (null c-fn))
+ (setq result (funcall c-fn module-name opts)))))))
result))
(defun inferior-erlang-compute-erl-compile-command (module-name opts)
(let* ((out-dir-opt (assoc 'outdir opts))
- (out-dir (cdr out-dir-opt)))
+ (out-dir (cdr out-dir-opt)))
(if erlang-compile-use-outdir
- (format "%s(\"%s\"%s)."
- erlang-compile-erlang-function
- module-name
- (inferior-erlang-format-comma-opts opts))
+ (format "%s(\"%s\"%s)."
+ erlang-compile-erlang-function
+ module-name
+ (inferior-erlang-format-comma-opts opts))
(let (;; Hopefully, noone else will ever use these...
- (tmpvar "Tmp7236")
- (tmpvar2 "Tmp8742"))
- (format
- (concat
- "f(%s), {ok, %s} = file:get_cwd(), "
- "file:set_cwd(\"%s\"), "
- "%s = %s(\"%s\"%s), file:set_cwd(%s), f(%s), %s.")
- tmpvar2 tmpvar
- out-dir
- tmpvar2
- erlang-compile-erlang-function
- module-name (inferior-erlang-format-comma-opts
- (remq out-dir-opt opts))
- tmpvar tmpvar tmpvar2)))))
+ (tmpvar "Tmp7236")
+ (tmpvar2 "Tmp8742"))
+ (format
+ (concat
+ "f(%s), {ok, %s} = file:get_cwd(), "
+ "file:set_cwd(\"%s\"), "
+ "%s = %s(\"%s\"%s), file:set_cwd(%s), f(%s), %s.")
+ tmpvar2 tmpvar
+ out-dir
+ tmpvar2
+ erlang-compile-erlang-function
+ module-name (inferior-erlang-format-comma-opts
+ (remq out-dir-opt opts))
+ tmpvar tmpvar tmpvar2)))))
(defun inferior-erlang-compute-leex-compile-command (module-name opts)
(let ((file-name (erlang-local-buffer-file-name))
- (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
- (inferior-erlang-compute-erl-compile-command
- module-name opts))))
+ (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
+ (inferior-erlang-compute-erl-compile-command
+ module-name opts))))
(format (concat "f(LErr1__), f(LErr2__), "
- "case case leex:file(\"%s\", [%s]) of"
- " ok -> ok;"
- " {ok,_} -> ok;"
- " {ok,_,_} -> ok;"
- " LErr1__ -> LErr1__ "
- "end of"
- " ok -> %s;"
- " LErr2__ -> LErr2__ "
- "end.")
- file-name
- (inferior-erlang-format-comma-opts erlang-leex-compile-opts)
- erl-compile-expr)))
+ "case case leex:file(\"%s\", [%s]) of"
+ " ok -> ok;"
+ " {ok,_} -> ok;"
+ " {ok,_,_} -> ok;"
+ " LErr1__ -> LErr1__ "
+ "end of"
+ " ok -> %s;"
+ " LErr2__ -> LErr2__ "
+ "end.")
+ file-name
+ (inferior-erlang-format-comma-opts erlang-leex-compile-opts)
+ erl-compile-expr)))
(defun inferior-erlang-compute-yecc-compile-command (module-name opts)
(let ((file-name (erlang-local-buffer-file-name))
- (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
- (inferior-erlang-compute-erl-compile-command
- module-name opts))))
+ (erl-compile-expr (inferior-erlang-remove-any-trailing-dot
+ (inferior-erlang-compute-erl-compile-command
+ module-name opts))))
(format (concat "f(YErr1__), f(YErr2__), "
- "case case yecc:file(\"%s\", [%s]) of"
- " {ok,_} -> ok;"
- " {ok,_,_} -> ok;"
- " YErr1__ -> YErr1__ "
- "end of"
- " ok -> %s;"
- " YErr2__ -> YErr2__ "
- "end.")
- file-name
- (inferior-erlang-format-comma-opts erlang-yecc-compile-opts)
- erl-compile-expr)))
+ "case case yecc:file(\"%s\", [%s]) of"
+ " {ok,_} -> ok;"
+ " {ok,_,_} -> ok;"
+ " YErr1__ -> YErr1__ "
+ "end of"
+ " ok -> %s;"
+ " YErr2__ -> YErr2__ "
+ "end.")
+ file-name
+ (inferior-erlang-format-comma-opts erlang-yecc-compile-opts)
+ erl-compile-expr)))
(defun inferior-erlang-remove-any-trailing-dot (str)
(if (string= (substring str -1) ".")
@@ -5730,31 +5731,29 @@ unless the optional NO-DISPLAY is non-nil."
(defun inferior-erlang-format-comma-opts (opts)
(if (null opts)
""
- (concat ", " (inferior-erlang-format-opts opts))))
-
-(defun inferior-erlang-format-opts (opts)
- (concat "[" (inferior-erlang-string-join (mapcar 'inferior-erlang-format-opt
- opts)
- ", ")
- "]"))
+ (concat ", " (inferior-erlang-format-opt opts))))
(defun inferior-erlang-format-opt (opt)
(cond ((stringp opt) (concat "\"" opt "\""))
- ((atom opt) (format "%s" opt))
- ((consp opt) (concat "{" (inferior-erlang-string-join
- (mapcar 'inferior-erlang-format-opt
- (list (car opt) (cdr opt)))
- ", ")
- "}"))
- (t (error (format "Unexpected opt %s" opt)))))
-
-(defun inferior-erlang-string-join (strs sep)
- (let ((result (or (car strs) "")))
- (setq strs (cdr strs))
- (while strs
- (setq result (concat result sep (car strs)))
- (setq strs (cdr strs)))
- result))
+ ((vectorp opt) (inferior-erlang-tuple (append opt nil)))
+ ((atom opt) (format "%s" opt))
+ ((consp opt) (if (listp (cdr opt))
+ (inferior-erlang-list opt)
+ (inferior-erlang-tuple (list (car opt) (cdr opt)))))
+ (t (error "Unexpected erlang compile option %s" opt))))
+
+(defun inferior-erlang-tuple (opts)
+ (concat "{" (mapconcat 'inferior-erlang-format-opt
+ opts
+ ", ")
+ "}"))
+
+(defun inferior-erlang-list (opts)
+ (concat "[" (mapconcat 'inferior-erlang-format-opt
+ opts
+ ", ")
+ "]"))
+
(defun erlang-local-buffer-file-name ()
;; When editing a file remotely via tramp,
@@ -5768,11 +5767,11 @@ unless the optional NO-DISPLAY is non-nil."
;; the file name "/some/path/x.erl" without the
;; tramp-prefix "/ssh:host.example.com:".
(cond ((null (buffer-file-name))
- nil)
- ((erlang-tramp-remote-file-p)
- (erlang-tramp-get-localname))
- (t
- (buffer-file-name))))
+ nil)
+ ((erlang-tramp-remote-file-p)
+ (erlang-tramp-get-localname))
+ (t
+ (buffer-file-name))))
(defun erlang-tramp-remote-file-p ()
(and (fboundp 'tramp-tramp-file-p)
@@ -5798,22 +5797,22 @@ unless the optional NO-DISPLAY is non-nil."
Capable of finding error messages in an inferior Erlang buffer."
(interactive "P")
(let ((done nil)
- (buf (or (and (boundp 'next-error-last-buffer)
- next-error-last-buffer)
- (and (boundp 'compilation-last-buffer)
- compilation-last-buffer))))
+ (buf (or (and (boundp 'next-error-last-buffer)
+ next-error-last-buffer)
+ (and (boundp 'compilation-last-buffer)
+ compilation-last-buffer))))
(if (and (bufferp buf)
- (with-current-buffer buf
- (and (eq major-mode 'erlang-shell-mode)
- (setq major-mode 'compilation-mode))))
- (unwind-protect
- (progn
- (setq done t)
- (next-error argp))
- (with-current-buffer buf
- (setq major-mode 'erlang-shell-mode))))
+ (with-current-buffer buf
+ (and (eq major-mode 'erlang-shell-mode)
+ (setq major-mode 'compilation-mode))))
+ (unwind-protect
+ (progn
+ (setq done t)
+ (next-error argp))
+ (with-current-buffer buf
+ (setq major-mode 'erlang-shell-mode))))
(or done
- (next-error argp))))
+ (next-error argp))))
(defun inferior-erlang-change-directory (&optional dir)
@@ -5850,44 +5849,44 @@ sum([], Sum) -> Sum."
(interactive "r")
(save-excursion
(let (;; regexp for matching arrows. without a prefix argument,
- ;; the regexp matches function heads. With a prefix, it
- ;; matches any arrow.
- (re (if current-prefix-arg
- "^.*\\(\\)->"
- (eval-when-compile
- (concat "^" erlang-atom-regexp ".*\\(\\)->"))))
- ;; part of regexp matching directly before the arrow
- (arrow-match-pos (if current-prefix-arg
- 1
- (1+ erlang-atom-regexp-matches)))
- ;; accumulator for positions where arrows are found, ordered
- ;; by buffer position (from greatest to smallest)
- (arrow-positions '())
- ;; accumulator for longest distance from start of line to arrow
- (most-indent 0)
- ;; marker to track the end of the region we're aligning
- (end-marker (progn (goto-char end)
- (point-marker))))
+ ;; the regexp matches function heads. With a prefix, it
+ ;; matches any arrow.
+ (re (if current-prefix-arg
+ "^.*\\(\\)->"
+ (eval-when-compile
+ (concat "^" erlang-atom-regexp ".*\\(\\)->"))))
+ ;; part of regexp matching directly before the arrow
+ (arrow-match-pos (if current-prefix-arg
+ 1
+ (1+ erlang-atom-regexp-matches)))
+ ;; accumulator for positions where arrows are found, ordered
+ ;; by buffer position (from greatest to smallest)
+ (arrow-positions '())
+ ;; accumulator for longest distance from start of line to arrow
+ (most-indent 0)
+ ;; marker to track the end of the region we're aligning
+ (end-marker (progn (goto-char end)
+ (point-marker))))
;; Pass 1: Find the arrow positions, adjust the whitespace
;; before each arrow to one space, and find the greatest
;; indentation level.
(goto-char start)
(while (re-search-forward re end-marker t)
- (goto-char (match-beginning arrow-match-pos))
- (just-one-space) ; adjust whitespace
- (setq arrow-positions (cons (point) arrow-positions))
- (setq most-indent (max most-indent (erlang-column-number))))
- (set-marker end-marker nil) ; free the marker
+ (goto-char (match-beginning arrow-match-pos))
+ (just-one-space) ; adjust whitespace
+ (setq arrow-positions (cons (point) arrow-positions))
+ (setq most-indent (max most-indent (erlang-column-number))))
+ (set-marker end-marker nil) ; free the marker
;; Pass 2: Insert extra padding so that all arrow indentation is
;; equal. This is done last-to-first by buffer position, so that
;; inserting spaces before one arrow doesn't change the
;; positions of the next ones.
(mapc (lambda (arrow-pos)
- (goto-char arrow-pos)
- (let* ((pad (- most-indent (erlang-column-number))))
- (when (> pad 0)
- (insert-char ?\ pad))))
- arrow-positions))))
+ (goto-char arrow-pos)
+ (let* ((pad (- most-indent (erlang-column-number))))
+ (when (> pad 0)
+ (insert-char ?\ pad))))
+ arrow-positions))))
(defun erlang-column-number ()
"Return the column number of the current position in the buffer.
@@ -5899,7 +5898,7 @@ Tab characters are counted by their visual width."
(save-excursion
(erlang-beginning-of-function)
(if (looking-at "[a-z0-9_]+")
- (match-string 0))))
+ (match-string 0))))
;; Aliases for backward compatibility with older versions of Erlang Mode.
;;
@@ -5918,7 +5917,7 @@ it assumes that NEWDEF is loaded."
(erlang-obsolete 'calculate-erlang-indent 'erlang-calculate-indent)
(erlang-obsolete 'calculate-erlang-stack-indent
- 'erlang-calculate-stack-indent)
+ 'erlang-calculate-stack-indent)
(erlang-obsolete 'at-erlang-keyword 'erlang-at-keyword)
(erlang-obsolete 'at-erlang-operator 'erlang-at-operator)
(erlang-obsolete 'beginning-of-erlang-clause 'erlang-beginning-of-clause)
@@ -5933,12 +5932,12 @@ it assumes that NEWDEF is loaded."
(defconst erlang-unload-hook
(list (lambda ()
- (when (featurep 'advice)
- (ad-unadvise 'Man-notify-when-ready)
- (ad-unadvise 'set-visited-file-name)))))
+ (when (featurep 'advice)
+ (ad-unadvise 'Man-notify-when-ready)
+ (ad-unadvise 'set-visited-file-name)))))
-(defun erlang-string-to-int (string)
+(defun erlang-string-to-int (string)
(if (fboundp 'string-to-number)
(string-to-number string)
(funcall (symbol-function 'string-to-int) string)))
@@ -5951,6 +5950,7 @@ it assumes that NEWDEF is loaded."
;; Local variables:
;; coding: iso-8859-1
+;; indent-tabs-mode: nil
;; End:
;;; erlang.el ends here
diff --git a/lib/tools/emacs/erldoc.el b/lib/tools/emacs/erldoc.el
new file mode 100644
index 0000000000..cb355374d9
--- /dev/null
+++ b/lib/tools/emacs/erldoc.el
@@ -0,0 +1,508 @@
+;;; erldoc.el --- browse Erlang/OTP documentation -*- lexical-binding: t; -*-
+
+;; %CopyrightBegin%
+;;
+;; Copyright Ericsson AB 2016. All Rights Reserved.
+;;
+;; 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
+;;
+;; 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%
+
+;;; Commentary:
+
+;; Crawl Erlang/OTP HTML documentation and generate lookup tables.
+;;
+;; This package depends on `cl-lib', `pcase' and
+;; `libxml-parse-html-region'; emacs 24+ compiled with libxml2 should
+;; work. On emacs 24.1 and 24.2 do `M-x package-install RET cl-lib
+;; RET' to install `cl-lib'.
+;;
+;; Please customise `erldoc-man-index' to point to your local OTP
+;; documentation.
+;;
+;; To use:
+;;
+;; (define-key help-map "u" 'erldoc-browse)
+;; (define-key help-map "t" 'erldoc-browse-topic)
+;; (define-key help-map "a" 'erldoc-apropos)
+;;
+;; Note: these commands trigger indexing OTP documentation on first
+;; run with cache to disk which may take 1-2 minutes.
+
+
+;;; Examples:
+
+;; 1. `M-x erldoc-browse RET erlang:integer_to_binary/2 RET' opens the
+;; `erlang' manual anchored on the entry for `integer_to_binary/2'.
+;;
+;; 2. `M-x erldoc-apropos RET first RET' list all MFAs matching
+;; substring `first'.
+;;
+;; 3. `M-x erldoc-browse-topic RET efficiency_guide#Introduction RET'
+;; opens chapter `Introduction' of the `Efficiency Guide' in the
+;; browser.
+
+;;; History:
+
+;; Written in December 2013 as a temporary solution to help me browse
+;; the rich Erlang/OTP documentation. Three years on I find myself
+;; still using it every day. - Leo (2016)
+
+;;; Code:
+
+(eval-when-compile (require 'url-parse))
+(require 'cl-lib)
+(require 'erlang)
+
+(eval-and-compile ;for emacs < 24.3
+ (or (fboundp 'user-error) (defalias 'user-error 'error)))
+
+(defgroup erldoc nil
+ "Browse Erlang document."
+ :group 'help)
+
+(defcustom erldoc-man-index "http://www.erlang.org/doc/man_index.html"
+ "The URL to the man_index.html page.
+Note it is advisable to customise this to a local URL for example
+`file:///usr/local/19.1/lib/erlang/doc/man_index.html' to speed
+up the indexing."
+ :type 'string
+ :group 'erldoc)
+
+(defcustom erldoc-verify-man-path nil
+ "If non-nil verify man path existence for `file://'."
+ :type 'boolean
+ :group 'erldoc)
+
+(defcustom erldoc-output-file (locate-user-emacs-file "cache/erldoc")
+ "File to store the parsed results."
+ :type 'file
+ :group 'erldoc)
+
+(defun erldoc-strip-string (s)
+ (let* ((re "[ \t\n\r\f\v\u00a0]+")
+ (from (if (string-match (concat "\\`" re) s) (match-end 0) 0))
+ (to (and (string-match (concat re "\\'") s) (match-beginning 0))))
+ (substring s from (and to (max to from)))))
+
+;; Note: don't know how to get the BASE-URL to
+;; `libxml-parse-html-region' to work.
+(defun erldoc-expand-url (url base-url)
+ (if (url-type (url-generic-parse-url url))
+ url
+ (let* ((base (url-generic-parse-url base-url))
+ (dir (directory-file-name (file-name-directory (url-filename base)))))
+ (setf (url-filename base) (expand-file-name url dir))
+ (url-recreate-url base))))
+
+(defun erldoc-parse-html (url)
+ (with-temp-buffer
+ (url-insert-file-contents url)
+ (libxml-parse-html-region (point-min) (point-max))))
+
+(defalias 'erldoc-dom-text-node-p #'stringp)
+
+(defun erldoc-dom-attributes (dom)
+ (and (not (erldoc-dom-text-node-p dom)) (cadr dom)))
+
+(defun erldoc-dom-get-attribute (dom attrib-name)
+ (cdr (assq attrib-name (erldoc-dom-attributes dom))))
+
+(defun erldoc-dom-children (dom)
+ (and (not (erldoc-dom-text-node-p dom)) (cddr dom)))
+
+(defun erldoc-dom-get-text (dom)
+ (let ((text (car (last (erldoc-dom-children dom)))))
+ (and (erldoc-dom-text-node-p text) text)))
+
+(defvar erldoc-dom-walk-parent nil)
+(defvar erldoc-dom-walk-siblings nil)
+
+(defun erldoc-dom-walk (dom k)
+ (funcall k dom)
+ (let ((erldoc-dom-walk-parent dom)
+ (erldoc-dom-walk-siblings (unless (erldoc-dom-text-node-p dom)
+ (cddr dom))))
+ (dolist (child erldoc-dom-walk-siblings)
+ (erldoc-dom-walk child k))))
+
+(defun erldoc-dom-get-element (dom element-name)
+ (catch 'return
+ (erldoc-dom-walk dom (lambda (d)
+ (when (eq (car-safe d) element-name)
+ (throw 'return d))))))
+
+(defun erldoc-dom-get-element-by-id (dom id)
+ (catch 'return
+ (erldoc-dom-walk dom (lambda (d)
+ (when (equal (erldoc-dom-get-attribute d 'id) id)
+ (throw 'return d))))))
+
+(defun erldoc-dom-get-elements-by-id (dom id)
+ (let (result)
+ (erldoc-dom-walk dom (lambda (d)
+ (when (equal (erldoc-dom-get-attribute d 'id) id)
+ (push d result))))
+ (nreverse result)))
+
+(defun erldoc-fix-path (url)
+ (if (and erldoc-verify-man-path
+ ;; Could only verify local files
+ (equal (url-type (url-generic-parse-url url)) "file"))
+ (let* ((obj (url-generic-parse-url url))
+ (new (car (file-expand-wildcards
+ (replace-regexp-in-string
+ "-[0-9]+\\(?:[.][0-9]+\\)*" "*"
+ (url-filename obj))))))
+ (or new (error "File %s does not exist" (url-filename obj)))
+ (setf (url-filename obj) new)
+ (url-recreate-url obj))
+ url))
+
+(defun erldoc-parse-man-index (url)
+ (let ((table (erldoc-dom-get-element (erldoc-parse-html url) 'table))
+ (mans))
+ (erldoc-dom-walk
+ table
+ (lambda (d)
+ (when (eq (car-safe d) 'a)
+ (let ((href (erldoc-dom-get-attribute d 'href)))
+ (when (and href (not (string-match-p "index\\.html\\'" href)))
+ (with-demoted-errors "erldoc-parse-man-index: %S"
+ (push (cons (erldoc-dom-get-text d)
+ (erldoc-fix-path (erldoc-expand-url href url)))
+ mans)))))))
+ (nreverse mans)))
+
+(defun erldoc-parse-man (man)
+ (let ((dom (erldoc-parse-html (cdr man)))
+ (table (make-hash-table :test #'equal)))
+ (erldoc-dom-walk
+ (erldoc-dom-get-element-by-id dom "loadscrollpos")
+ (lambda (d)
+ (let ((href (erldoc-dom-get-attribute d 'href)))
+ (when (and href (string-match "#" href))
+ (puthash (substring href (match-end 0))
+ (list (concat (car man) ":" (erldoc-strip-string
+ (erldoc-dom-get-text d)))
+ (erldoc-expand-url href (cdr man)))
+ table)))))
+ (let ((span-content
+ (lambda (span)
+ (let ((texts))
+ (erldoc-dom-walk span
+ (lambda (d)
+ (and (erldoc-dom-text-node-p d)
+ (push (erldoc-strip-string d) texts))))
+ (and texts (mapconcat 'identity (nreverse texts) " ")))))
+ entries)
+ (erldoc-dom-walk
+ dom
+ (lambda (d)
+ ;; Get the full function signature.
+ (when (and (eq (car-safe d) 'a)
+ (gethash (erldoc-dom-get-attribute d 'name) table))
+ (push (append (gethash (erldoc-dom-get-attribute d 'name) table)
+ (list (funcall span-content
+ (or (erldoc-dom-get-element d 'span)
+ (cadr (memq d erldoc-dom-walk-siblings))))))
+ entries))
+ ;; Get data types
+ (when (and (eq (car-safe d) 'a)
+ (string-prefix-p "type-"
+ (or (erldoc-dom-get-attribute d 'name) "")))
+ (push (list (concat (car man) ":" (funcall span-content d))
+ (concat (cdr man) "#" (erldoc-dom-get-attribute d 'name))
+ (funcall span-content erldoc-dom-walk-parent))
+ entries))))
+ entries)))
+
+(defun erldoc-parse-all (man-index output &optional json)
+ (let* ((output (expand-file-name output))
+ (table (make-hash-table :size 11503 :test #'equal))
+ (mans (erldoc-parse-man-index man-index))
+ (progress 1)
+ (reporter (make-progress-reporter "Parsing Erlang/OTP documentation"
+ progress (length mans)))
+ fails all)
+ (dolist (man mans)
+ (condition-case err
+ (push (erldoc-parse-man man) all)
+ (error (push (error-message-string err) fails)))
+ (accept-process-output nil 0.01)
+ (progress-reporter-update reporter (cl-incf progress)))
+ (when fails
+ (display-warning 'erldoc-parse-all
+ (format "\n\n%s" (mapconcat #'identity fails "\n"))
+ :error))
+ (progress-reporter-done reporter)
+ (mapc (lambda (x) (puthash (car x) (cdr x) table))
+ (apply #'nconc (nreverse all)))
+ (with-temp-buffer
+ (if (not json)
+ (pp table (current-buffer))
+ (eval-and-compile (require 'json))
+ (let ((json-encoding-pretty-print t))
+ (insert (json-encode table))))
+ (unless (file-directory-p (file-name-directory output))
+ (make-directory (file-name-directory output) t))
+ (write-region nil nil output nil nil nil 'ask))))
+
+(defun erldoc-otp-release ()
+ "Get the otp release version (as string) or nil if not found."
+ (let ((otp (erldoc-dom-get-text
+ (erldoc-dom-get-element
+ (erldoc-parse-html
+ (erldoc-expand-url "index.html" erldoc-man-index))
+ 'title))))
+ (and (string-match "[0-9.]+\\'" otp) (match-string 0 otp))))
+
+(defvar erldoc-browse-history nil)
+(defvar erldoc-lookup-table nil)
+
+(defun erldoc-lookup-table ()
+ (or erldoc-lookup-table
+ (progn
+ (unless (file-exists-p erldoc-output-file)
+ (let ((of (pcase (erldoc-otp-release)
+ (`nil erldoc-output-file)
+ (ver (concat erldoc-output-file "-" ver)))))
+ (unless (file-exists-p of)
+ (erldoc-parse-all erldoc-man-index of))
+ (unless (string= erldoc-output-file of)
+ (make-symbolic-link of erldoc-output-file))))
+ (setq erldoc-lookup-table
+ (with-temp-buffer
+ (insert-file-contents erldoc-output-file)
+ (read (current-buffer)))))))
+
+(defun erldoc-best-matches (mfa)
+ (pcase mfa
+ ((and `(,m ,f) (let a (erlang-get-function-arity)))
+ (let ((mfa (format "%s:%s/%s" m f a)))
+ (cond ((gethash mfa (erldoc-lookup-table)) (list mfa))
+ (m (all-completions (concat m ":" f "/") (erldoc-lookup-table)))
+ (t (let* ((mod (erlang-get-module))
+ (mf1 (and mod (concat mod ":" f "/")))
+ (mf2 (concat "erlang:" f "/"))
+ (re (concat ":" (regexp-quote f) "/")))
+ (or (and mf1 (all-completions mf1 (erldoc-lookup-table)))
+ (all-completions mf2 (erldoc-lookup-table))
+ (cl-loop for k being the hash-keys of (erldoc-lookup-table)
+ when (string-match-p re k)
+ collect k)))))))))
+
+;;;###autoload
+(defun erldoc-browse (mfa)
+ (interactive
+ (let ((default
+ ;; `erlang-mode-syntax-table' is lazily initialised.
+ (with-syntax-table (or erlang-mode-syntax-table (standard-syntax-table))
+ (ignore-errors
+ (erldoc-best-matches
+ (or (erlang-get-function-under-point)
+ (save-excursion
+ (goto-char (or (cadr (syntax-ppss)) (point)))
+ (erlang-get-function-under-point))))))))
+ (list (completing-read (format (if default "Function {%d %s} (default %s): "
+ "Function: ")
+ (length default)
+ (if (= (length default) 1) "guess" "guesses")
+ (car default))
+ (erldoc-lookup-table)
+ nil t nil 'erldoc-browse-history default))))
+ (or (stringp mfa)
+ (signal 'wrong-type-argument (list 'string mfa 'mfa)))
+ (browse-url (or (car (gethash mfa (erldoc-lookup-table)))
+ (user-error "No documentation for %s" mfa))))
+
+;;;###autoload
+(defun erldoc-apropos (pattern)
+ (interactive "sPattern: ")
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (princ (concat "Erldoc apropos pattern: " pattern "\n\n"))
+ (maphash (lambda (k v)
+ (when (string-match-p pattern k)
+ (insert-text-button k :type 'help-url
+ 'help-args (list (car v)))
+ (insert "\n")))
+ (erldoc-lookup-table)))))
+
+(defun erldoc-tokenize-signature (sig)
+ ;; Divide SIG into (MF ARGLIST RETTYPE)
+ (let ((from (if (string-match "\\`.+?(" sig)
+ (1- (match-end 0))
+ 0))
+ (to (and (string-match "\\s-*->\\s-*.*?\\'" sig) (match-beginning 0))))
+ (list (erldoc-strip-string (substring sig 0 from))
+ (erldoc-strip-string (substring sig from (and to (max from to))))
+ (and to (erldoc-strip-string (substring sig to))))))
+
+(defun erldoc-format-signature (mod fn)
+ (when (and mod fn (or erldoc-lookup-table
+ (file-exists-p erldoc-output-file)))
+ (let ((re (concat "\\`" mod ":" fn "/\\([0-9]+\\)\\'"))
+ (sigs))
+ (maphash (lambda (k v)
+ (when (string-match re k)
+ (push (cons (string-to-number (match-string 1 k))
+ (cdr (erldoc-tokenize-signature (cadr v))))
+ sigs)))
+ (erldoc-lookup-table))
+ (when sigs
+ ;; Mostly single return type but there are exceptions such as
+ ;; `beam_lib:chunks/2,3'.
+ (let ((single-rettype
+ (cl-reduce (lambda (x1 x2) (and x1 x2 (equal x1 x2) x1))
+ sigs :key #'cl-caddr))
+ (sigs (sort sigs #'car-less-than-car)))
+ (if single-rettype
+ (concat mod ":" fn (mapconcat #'cadr sigs " | ") " " single-rettype)
+ (mapconcat (lambda (x) (concat mod ":" fn (nth 1 x) " " (nth 2 x)))
+ sigs "\n")))))))
+
+;;;###autoload
+(defun erldoc-eldoc-function ()
+ "A function suitable for `eldoc-documentation-function'."
+ (save-excursion
+ (pcase (erlang-get-function-under-point)
+ (`(,_ nil) )
+ (`(nil ,fn) (erldoc-format-signature "erlang" fn))
+ (`(,mod ,fn) (erldoc-format-signature mod fn)))))
+
+(defun erldoc-parse-eeps-index ()
+ (let* ((url "http://www.erlang.org/eeps/")
+ (table (catch 'return
+ (erldoc-dom-walk (erldoc-parse-html url)
+ (lambda (d)
+ (and (eq (car-safe d) 'table)
+ (equal (erldoc-dom-get-attribute d 'summary)
+ "Numerical Index of EEPs")
+ (throw 'return d))))))
+ (fix-title (lambda (title)
+ (replace-regexp-in-string
+ "`` *" "" (replace-regexp-in-string " *``, *" " by " title))))
+ (result))
+ (erldoc-dom-walk
+ table (lambda (d)
+ (when (eq (car-safe d) 'a)
+ (push (cons (funcall fix-title (erldoc-dom-get-attribute d 'title))
+ (erldoc-expand-url
+ (erldoc-dom-get-attribute d 'href)
+ url))
+ result))))
+ (nreverse result)))
+
+(defvar erldoc-user-guides nil)
+
+(defvar erldoc-missing-user-guides
+ '("compiler" "hipe" "kernel" "os_mon" "parsetools" "typer")
+ "List of standard Erlang applications with no user guides.")
+
+;; Search in `code:lib_dir/0' using find LIB_DIR -type f -name
+;; '*_app.html'.
+(defvar erldoc-app-manuals '("crypto" "diameter" "erl_docgen"
+ "kernel" "observer" "os_mon"
+ "runtime_tools" "sasl" "snmp"
+ "ssl" "test_server"
+ ("ssh" . "SSH") ("stdlib" . "STDLIB")
+ ("hipe" . "HiPE") ("typer" . "TypEr"))
+ "List of applications that come with a manual.")
+
+(defun erldoc-user-guide-chapters (user-guide)
+ (pcase-let ((`(,name . ,url) user-guide))
+ (unless (member name erldoc-missing-user-guides)
+ (let ((chaps (erldoc-dom-get-elements-by-id
+ (erldoc-dom-get-element-by-id (erldoc-parse-html url) "leftnav")
+ "no")))
+ (or chaps (warn "erldoc-user-guide-chapters no chapters found for `%s'"
+ (cdr user-guide)))
+ (mapcar (lambda (li)
+ (cons (concat name "#" (erldoc-dom-get-attribute li 'title))
+ (erldoc-expand-url (erldoc-dom-get-attribute
+ (erldoc-dom-get-element li 'a) 'href)
+ url)))
+ chaps)))))
+
+(defun erldoc-user-guides-1 ()
+ (let ((url (erldoc-expand-url "applications.html" erldoc-man-index))
+ app-guides app-mans)
+ (erldoc-dom-walk
+ (erldoc-parse-html url)
+ (lambda (d)
+ (when (and (eq (car-safe d) 'a)
+ (not (string-match-p "\\`[0-9.]+\\'" (erldoc-dom-get-text d))))
+ (with-demoted-errors "erldoc-user-guides-1: %S"
+ (let ((name (erldoc-strip-string (erldoc-dom-get-text d)))
+ (index-page (erldoc-fix-path (erldoc-expand-url
+ (erldoc-dom-get-attribute d 'href) url))))
+ (push (cons name (if (member name erldoc-missing-user-guides)
+ index-page
+ (erldoc-expand-url "users_guide.html" index-page)))
+ app-guides)
+ ;; Collect application manuals.
+ (pcase (assoc name (mapcar (lambda (x) (if (consp x) x (cons x x)))
+ erldoc-app-manuals))
+ (`(,_ . ,manual)
+ (push (cons name
+ (erldoc-expand-url (format "%s_app.html" manual)
+ index-page))
+ app-mans))))))))
+ (list (nreverse app-guides)
+ (nreverse app-mans))))
+
+(defun erldoc-user-guides ()
+ (or erldoc-user-guides
+ (let ((file (concat erldoc-output-file "-topics")))
+ (unless (file-exists-p file)
+ (unless (file-directory-p (file-name-directory file))
+ (make-directory (file-name-directory file) t))
+ (with-temp-buffer
+ (pcase-let ((`(,guides ,mans) (erldoc-user-guides-1)))
+ (pp (append (cl-mapcan #'erldoc-user-guide-chapters
+ (append (mapcar
+ (lambda (dir)
+ (cons dir (erldoc-expand-url
+ (concat dir "/users_guide.html")
+ erldoc-man-index)))
+ '("design_principles"
+ "efficiency_guide"
+ "embedded"
+ "getting_started"
+ "installation_guide"
+ "oam"
+ "programming_examples"
+ "reference_manual"
+ "system_architecture_intro"
+ "system_principles"
+ "tutorial"))
+ guides))
+ (mapcar (lambda (man)
+ (pcase-let ((`(,name . ,url) man))
+ (cons (concat name " (App)") url)))
+ mans)
+ (erldoc-parse-eeps-index))
+ (current-buffer)))
+ (write-region nil nil file nil nil nil 'ask)))
+ (setq erldoc-user-guides (with-temp-buffer (insert-file-contents file)
+ (read (current-buffer)))))))
+
+;;;###autoload
+(defun erldoc-browse-topic (topic)
+ (interactive
+ (list (completing-read "User guide: " (erldoc-user-guides) nil t)))
+ (browse-url (cdr (assoc topic (erldoc-user-guides)))))
+
+(provide 'erldoc)
+;;; erldoc.el ends here
diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented
index 7a1ff6a954..14a4eca7c3 100644
--- a/lib/tools/emacs/test.erl.indented
+++ b/lib/tools/emacs/test.erl.indented
@@ -1,4 +1,4 @@
-%% -*- erlang -*-
+%% -*- Mode: erlang; indent-tabs-mode: nil -*-
%%
%% %CopyrightBegin%
%%
@@ -27,7 +27,7 @@
%%% Created : 6 Oct 2009 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-%% Start off with syntax highlighting you have to verify this by looking here
+%% Start off with syntax highlighting you have to verify this by looking here
%% and see that the code looks alright
-module(test).
@@ -44,175 +44,175 @@ foo() ->
%% Module attributes should be highlighted
-export([t/1]).
--record(record1, {a,
- b,
- c
- }).
+-record(record1, {a,
+ b,
+ c
+ }).
-record(record2, {
- a,
- b
- }).
+ a,
+ b
+ }).
-record(record3, {a = 8#42423 bor
- 8#4234,
- b = 8#5432
- bor 2#1010101
- c = 123 +
- 234,
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+ 234,
d}).
-record(record4, {
- a = 8#42423 bor
- 8#4234,
- b = 8#5432
- bor 2#1010101
- c = 123 +
- 234,
- d}).
+ a = 8#42423 bor
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+ 234,
+ d}).
-record(record5, { a = 1 :: integer()
- , b = foobar :: atom()
- }).
+ , b = foobar :: atom()
+ }).
-define(MACRO_1, macro).
-define(MACRO_2(_), macro).
-spec t(integer()) -> any().
--type ann() :: Var :: integer().
--type ann2() :: Var ::
- 'return'
- | 'return_white_spaces'
- | 'return_comments'
- | 'text' | ann().
--type paren() ::
- (ann2()).
--type t1() :: atom().
--type t2() :: [t1()].
--type t3(Atom) :: integer(Atom).
--type t4() :: t3(foobar).
--type t5() :: {t1(), t3(foo)}.
--type t6() :: 1 | 2 | 3 |
- 'foo' | 'bar'.
--type t7() :: [].
--type t71() :: [_].
+-type ann() :: Var :: integer().
+-type ann2() :: Var ::
+ 'return'
+ | 'return_white_spaces'
+ | 'return_comments'
+ | 'text' | ann().
+-type paren() ::
+ (ann2()).
+-type t1() :: atom().
+-type t2() :: [t1()].
+-type t3(Atom) :: integer(Atom).
+-type t4() :: t3(foobar).
+-type t5() :: {t1(), t3(foo)}.
+-type t6() :: 1 | 2 | 3 |
+ 'foo' | 'bar'.
+-type t7() :: [].
+-type t71() :: [_].
-type t8() :: {any(),none(),pid(),port(),
- reference(),float()}.
--type t9() :: [1|2|3|foo|bar] |
- list(a | b | c) | t71().
--type t10() :: {1|2|3|foo|t9()} | {}.
--type t11() :: 1..2.
--type t13() :: maybe_improper_list(integer(), t11()).
--type t14() :: [erl_scan:foo() |
- %% Should be highlighted
- term() |
- bool() |
- byte() |
- char() |
- non_neg_integer() | nonempty_list() |
- pos_integer() |
- neg_integer() |
- number() |
- list() |
- nonempty_improper_list() | nonempty_maybe_improper_list() |
- maybe_improper_list() | string() | iolist() | byte() |
- module() |
- mfa() |
- node() |
- timeout() |
- no_return() |
- %% Should not be highlighted
- nonempty_() | nonlist() |
- erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
+ reference(),float()}.
+-type t9() :: [1|2|3|foo|bar] |
+ list(a | b | c) | t71().
+-type t10() :: {1|2|3|foo|t9()} | {}.
+-type t11() :: 1..2.
+-type t13() :: maybe_improper_list(integer(), t11()).
+-type t14() :: [erl_scan:foo() |
+ %% Should be highlighted
+ term() |
+ bool() |
+ byte() |
+ char() |
+ non_neg_integer() | nonempty_list() |
+ pos_integer() |
+ neg_integer() |
+ number() |
+ list() |
+ nonempty_improper_list() | nonempty_maybe_improper_list() |
+ maybe_improper_list() | string() | iolist() | byte() |
+ module() |
+ mfa() |
+ node() |
+ timeout() |
+ no_return() |
+ %% Should not be highlighted
+ nonempty_() | nonlist() |
+ erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
-type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>,
<<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>|
- <<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
- <<_:34>>|<<_:34>>|<<_:34>>].
--type t16() :: fun().
--type t17() :: fun((...) -> paren()).
--type t18() :: fun(() -> t17() | t16()).
+ <<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
+ <<_:34>>|<<_:34>>|<<_:34>>].
+-type t16() :: fun().
+-type t17() :: fun((...) -> paren()).
+-type t18() :: fun(() -> t17() | t16()).
-type t19() :: fun((t18()) -> t16()) |
- fun((nonempty_maybe_improper_list('integer', any())|
- 1|2|3|a|b|<<_:3,_:_*14>>|integer()) ->
- nonempty_maybe_improper_list('integer', any())|
- 1|2|3|a|b|<<_:3,_:_*14>>|integer()).
--type t20() :: [t19(), ...].
--type t21() :: tuple().
--type t21(A) :: A.
--type t22() :: t21(integer()).
--type t23() :: #rec1{}.
--type t24() :: #rec2{a :: t23(), b :: [atom()]}.
--type t25() :: #rec3{f123 :: [t24() |
- 1|2|3|4|a|b|c|d|
- nonempty_maybe_improper_list(integer, any())]}.
+ fun((nonempty_maybe_improper_list('integer', any())|
+ 1|2|3|a|b|<<_:3,_:_*14>>|integer()) ->
+ nonempty_maybe_improper_list('integer', any())|
+ 1|2|3|a|b|<<_:3,_:_*14>>|integer()).
+-type t20() :: [t19(), ...].
+-type t21() :: tuple().
+-type t21(A) :: A.
+-type t22() :: t21(integer()).
+-type t23() :: #rec1{}.
+-type t24() :: #rec2{a :: t23(), b :: [atom()]}.
+-type t25() :: #rec3{f123 :: [t24() |
+ 1|2|3|4|a|b|c|d|
+ nonempty_maybe_improper_list(integer, any())]}.
-type t26() :: #rec4{ a :: integer()
- , b :: any()
- }.
+ , b :: any()
+ }.
-type t27() :: { integer()
- , atom()
- }.
+ , atom()
+ }.
-type t99() ::
- {t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14(),
- t15(),t20(),t21(), t22(),t25()}.
+ {t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14(),
+ t15(),t20(),t21(), t22(),t25()}.
-spec t1(FooBar :: t99()) -> t99();
- (t2()) -> t2();
+ (t2()) -> t2();
(t4()) -> t4() when is_subtype(t4(), t24);
- (t23()) -> t23() when is_subtype(t23(), atom()),
- is_subtype(t23(), t14());
- (t24()) -> t24() when is_subtype(t24(), atom()),
- is_subtype(t24(), t14()),
- is_subtype(t24(), t4()).
+ (t23()) -> t23() when is_subtype(t23(), atom()),
+ is_subtype(t23(), t14());
+ (t24()) -> t24() when is_subtype(t24(), atom()),
+ is_subtype(t24(), t14()),
+ is_subtype(t24(), t4()).
-spec over(I :: integer()) -> R1 :: foo:typen();
- (A :: atom()) -> R2 :: foo:atomen();
- (T :: tuple()) -> R3 :: bar:typen().
+ (A :: atom()) -> R2 :: foo:atomen();
+ (T :: tuple()) -> R3 :: bar:typen().
--spec mod:t2() -> any().
+-spec mod:t2() -> any().
--spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
- | {'del_member', name(), pid()},
- #state{}) -> {'noreply', #state{}}.
+-spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
--spec handle_cast(Cast ::
- {'exchange', node(), [[name(),...]]}
- | {'del_member', name(), pid()},
- #state{}) -> {'noreply', #state{}}.
+-spec handle_cast(Cast ::
+ {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
-spec all(fun((T) -> boolean()), List :: [T]) ->
- boolean() when is_subtype(T, term()). % (*)
+ boolean() when is_subtype(T, term()). % (*)
--spec get_closest_pid(term()) ->
- Return :: pid()
- | {'error', {'no_process', term()}
- | {'no_such_group', term()}}.
+-spec get_closest_pid(term()) ->
+ Return :: pid()
+ | {'error', {'no_process', term()}
+ | {'no_such_group', term()}}.
-spec add( X :: integer()
- , Y :: integer()
- ) -> integer().
+ , Y :: integer()
+ ) -> integer().
--opaque attributes_data() ::
- [{'column', column()} | {'line', info_line()} |
- {'text', string()}] | {line(),column()}.
+-opaque attributes_data() ::
+ [{'column', column()} | {'line', info_line()} |
+ {'text', string()}] | {line(),column()}.
-record(r,{
f1 :: attributes_data(),
- f222 = foo:bar(34, #rec3{}, 234234234423,
- aassdsfsdfsdf, 2234242323) ::
- [t24() | 1|2|3|4|a|b|c|d|
- nonempty_maybe_improper_list(integer, any())],
- f333 :: [t24() | 1|2|3|4|a|b|c|d|
- nonempty_maybe_improper_list(integer, any())],
- f3 = x:y(),
- f4 = x:z() :: t99(),
- f17 :: 'undefined',
- f18 :: 1 | 2 | 'undefined',
- f19 = 3 :: integer()|undefined,
- f5 = 3 :: undefined|integer()}).
+ f222 = foo:bar(34, #rec3{}, 234234234423,
+ aassdsfsdfsdf, 2234242323) ::
+ [t24() | 1|2|3|4|a|b|c|d|
+ nonempty_maybe_improper_list(integer, any())],
+ f333 :: [t24() | 1|2|3|4|a|b|c|d|
+ nonempty_maybe_improper_list(integer, any())],
+ f3 = x:y(),
+ f4 = x:z() :: t99(),
+ f17 :: 'undefined',
+ f18 :: 1 | 2 | 'undefined',
+ f19 = 3 :: integer()|undefined,
+ f5 = 3 :: undefined|integer()}).
-record(state, {
- sequence_number = 1 :: integer()
- }).
+ sequence_number = 1 :: integer()
+ }).
highlighting(X) % Function definitions should be highlighted
@@ -230,12 +230,12 @@ highlighting(X) % Function definitions should be highlighted
'#1',atom,
$", atom, % atom should be ok
- $', atom,
+ $', atom,
"string$", atom, "string$", atom, % currently buggy I know...
"string\$", atom, % workaround for bug above
- "char $in string", atom,
+ "char $in string", atom,
'atom$', atom, 'atom$', atom,
'atom\$', atom,
@@ -270,15 +270,15 @@ highlighting(X) % Function definitions should be highlighted
erlang:anything(lists),
%% Guards
is_atom(foo), is_float(2.3), is_integer(32), is_number(4323.3),
- is_function(Fun), is_pid(self()),
+ is_function(Fun), is_pid(self()),
not_a_guard:is_list([]),
%% Other Types
atom, % not (currently) hightlighted
- 234234,
+ 234234,
234.43,
- [list, are, not, higlighted],
+ [list, are, not, higlighted],
{nor, is, tuple},
ok.
@@ -290,35 +290,35 @@ highlighting(X) % Function definitions should be highlighted
%% Indented
- % Right
+ % Right
-indent_basics(X, Y, Z)
+indent_basics(X, Y, Z)
when X > 42,
Z < 13;
Y =:= 4711 ->
%% comments
- % right comments
- case lists:filter(fun(_, AlongName,
- B,
- C) ->
- true
- end,
- [a,v,b])
+ % right comments
+ case lists:filter(fun(_, AlongName,
+ B,
+ C) ->
+ true
+ end,
+ [a,v,b])
of
- [] ->
- Y = 5 * 43,
- ok;
- [_|_] ->
- Y = 5 * 43,
- ok
+ [] ->
+ Y = 5 * 43,
+ ok;
+ [_|_] ->
+ Y = 5 * 43,
+ ok
end,
Y,
%% List, tuples and binaries
- [a,
+ [a,
b, c
],
- [ a,
+ [ a,
b, c
],
@@ -326,10 +326,10 @@ indent_basics(X, Y, Z)
a,
b
],
- {a,
+ {a,
b,c
},
- { a,
+ { a,
b,c
},
@@ -366,16 +366,16 @@ indent_basics(X, Y, Z)
c
),
- call(2#42423 bor
- #4234,
- 2#5432,
- other_arg),
+ call(2#42423 bor
+ #4234,
+ 2#5432,
+ other_arg),
ok;
-indent_basics(Xlongname,
- #struct{a=Foo,
- b=Bar},
- [X|
- Y]) ->
+indent_basics(Xlongname,
+ #struct{a=Foo,
+ b=Bar},
+ [X|
+ Y]) ->
testing_next_clause,
ok;
indent_basics( % AD added clause
@@ -408,295 +408,295 @@ indent_nested() ->
indent_icr(Z) -> % icr = if case receive
%% If
if Z >= 0 ->
- X = 43 div 4,
- foo(X);
+ X = 43 div 4,
+ foo(X);
Z =< 10 ->
- X = 43 div 4,
- foo(X);
+ X = 43 div 4,
+ foo(X);
Z == 5 orelse
Z == 7 ->
- X = 43 div 4,
- foo(X);
+ X = 43 div 4,
+ foo(X);
true ->
- if_works
+ if_works
end,
%% Case
case {Z, foo, bar} of
- {Z,_,_} ->
- X = 43 div 4,
- foo(X);
- {Z,_,_} when
- Z =:= 42 -> % AD line should be indented as a when
- X = 43 div 4,
- foo(X);
- {Z,_,_}
- when Z < 10 -> % AD when should be indented
- X = 43 div 4,
- foo(X);
- {Z,_,_}
- when % AD when should be indented
- Z < 10 % and the guards should follow when
- andalso % unsure about how though
- true ->
- X = 43 div 4,
- foo(X)
+ {Z,_,_} ->
+ X = 43 div 4,
+ foo(X);
+ {Z,_,_} when
+ Z =:= 42 -> % AD line should be indented as a when
+ X = 43 div 4,
+ foo(X);
+ {Z,_,_}
+ when Z < 10 -> % AD when should be indented
+ X = 43 div 4,
+ foo(X);
+ {Z,_,_}
+ when % AD when should be indented
+ Z < 10 % and the guards should follow when
+ andalso % unsure about how though
+ true ->
+ X = 43 div 4,
+ foo(X)
end,
%% begin
begin
- sune,
- X = 74234 + foo(8456) +
- 345 div 43,
- ok
+ sune,
+ X = 74234 + foo(8456) +
+ 345 div 43,
+ ok
end,
%% receive
- receive
- {Z,_,_} ->
- X = 43 div 4,
- foo(X);
- Z ->
- X = 43 div 4,
- foo(X)
+ receive
+ {Z,_,_} ->
+ X = 43 div 4,
+ foo(X);
+ Z ->
+ X = 43 div 4,
+ foo(X)
end,
receive
- {Z,_,_} ->
- X = 43 div 4,
- foo(X);
- Z % AD added clause
- when Z =:= 1 -> % This line should be indented by 2
- X = 43 div 4,
- foo(X);
- Z when % AD added clause
- Z =:= 2 -> % This line should be indented by 2
- X = 43 div 4,
- foo(X);
- Z ->
- X = 43 div 4,
- foo(X)
+ {Z,_,_} ->
+ X = 43 div 4,
+ foo(X);
+ Z % AD added clause
+ when Z =:= 1 -> % This line should be indented by 2
+ X = 43 div 4,
+ foo(X);
+ Z when % AD added clause
+ Z =:= 2 -> % This line should be indented by 2
+ X = 43 div 4,
+ foo(X);
+ Z ->
+ X = 43 div 4,
+ foo(X)
after infinity ->
- foo(X),
- asd(X),
- 5*43
+ foo(X),
+ asd(X),
+ 5*43
end,
receive
- after 10 ->
- foo(X),
- asd(X),
- 5*43
+ after 10 ->
+ foo(X),
+ asd(X),
+ 5*43
end,
ok.
indent_fun() ->
%% Changed fun to one indention level
- Var = spawn(fun(X)
- when X == 2;
- X > 10 ->
- hello,
- case Hello() of
- true when is_atom(X) ->
- foo;
- false ->
- bar
- end;
- (Foo) when is_atom(Foo),
- is_integer(X) ->
- X = 6* 45,
- Y = true andalso
- kalle
- end),
+ Var = spawn(fun(X)
+ when X == 2;
+ X > 10 ->
+ hello,
+ case Hello() of
+ true when is_atom(X) ->
+ foo;
+ false ->
+ bar
+ end;
+ (Foo) when is_atom(Foo),
+ is_integer(X) ->
+ X = 6* 45,
+ Y = true andalso
+ kalle
+ end),
%% check EEP37 named funs
Fn1 = fun Fact(N) when N > 0 ->
- F = Fact(N-1),
- N * F;
- Fact(0) ->
- 1
- end,
+ F = Fact(N-1),
+ N * F;
+ Fact(0) ->
+ 1
+ end,
%% check anonymous funs too
Fn2 = fun(0) ->
- 1;
- (N) ->
- N
- end,
+ 1;
+ (N) ->
+ N
+ end,
ok.
indent_try_catch() ->
try
- io:format(stdout, "Parsing file ~s, ",
- [St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
- parse_rules(Xfile, Line2, Macs, St2)
+ io:format(stdout, "Parsing file ~s, ",
+ [St0#leex.xfile]),
+ {ok,Line3,REAs,Actions,St3} =
+ parse_rules(Xfile, Line2, Macs, St2)
catch
- exit:{badarg,R} ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R);
- error:R % AD added clause
- when R =:= 42 -> % when should be indented
- foo(R);
- error:R % AD added clause
- when % when should be indented
- R =:= 42 -> % but unsure about this (maybe 2 more)
- foo(R);
- error:R when % AD added clause
- R =:= foo -> % line should be 2 indented (works)
- foo(R);
- error:R ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R)
+ exit:{badarg,R} ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R);
+ error:R % AD added clause
+ when R =:= 42 -> % when should be indented
+ foo(R);
+ error:R % AD added clause
+ when % when should be indented
+ R =:= 42 -> % but unsure about this (maybe 2 more)
+ foo(R);
+ error:R when % AD added clause
+ R =:= foo -> % line should be 2 indented (works)
+ foo(R);
+ error:R ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R)
after
- foo('after'),
- file:close(Xfile)
+ foo('after'),
+ file:close(Xfile)
end;
indent_try_catch() ->
try
- foo(bar)
+ foo(bar)
of
- X when true andalso
- kalle ->
- io:format(stdout, "Parsing file ~s, ",
- [St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
- parse_rules(Xfile, Line2, Macs, St2);
- X % AD added clause
- when false andalso % when should be 2 indented
- bengt ->
- gurka();
- X when % AD added clause
- false andalso % line should be 2 indented
- not bengt ->
- gurka();
- X ->
- io:format(stdout, "Parsing file ~s, ",
- [St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
- parse_rules(Xfile, Line2, Macs, St2)
+ X when true andalso
+ kalle ->
+ io:format(stdout, "Parsing file ~s, ",
+ [St0#leex.xfile]),
+ {ok,Line3,REAs,Actions,St3} =
+ parse_rules(Xfile, Line2, Macs, St2);
+ X % AD added clause
+ when false andalso % when should be 2 indented
+ bengt ->
+ gurka();
+ X when % AD added clause
+ false andalso % line should be 2 indented
+ not bengt ->
+ gurka();
+ X ->
+ io:format(stdout, "Parsing file ~s, ",
+ [St0#leex.xfile]),
+ {ok,Line3,REAs,Actions,St3} =
+ parse_rules(Xfile, Line2, Macs, St2)
catch
- exit:{badarg,R} ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R);
- error:R ->
- foo(R),
- io:format(stdout,
- "ERROR reason ~p~n",
- R)
+ exit:{badarg,R} ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R);
+ error:R ->
+ foo(R),
+ io:format(stdout,
+ "ERROR reason ~p~n",
+ R)
after
- foo('after'),
- file:close(Xfile),
- bar(with_long_arg,
- with_second_arg)
+ foo('after'),
+ file:close(Xfile),
+ bar(with_long_arg,
+ with_second_arg)
end;
indent_try_catch() ->
try foo()
- after
- foo(),
- bar(with_long_arg,
- with_second_arg)
+ after
+ foo(),
+ bar(with_long_arg,
+ with_second_arg)
end.
indent_catch() ->
D = B +
- float(43.1),
+ float(43.1),
B = catch oskar(X),
- A = catch (baz +
- bax),
+ A = catch (baz +
+ bax),
catch foo(),
- C = catch B +
- float(43.1),
+ C = catch B +
+ float(43.1),
case catch foo(X) of
- A ->
- B
+ A ->
+ B
end,
case
- catch foo(X)
+ catch foo(X)
of
- A ->
- B
+ A ->
+ B
end,
case
- foo(X)
+ foo(X)
of
- A ->
- catch B,
- X
+ A ->
+ catch B,
+ X
end,
try sune of
- _ -> foo
+ _ -> foo
catch _:_ -> baf
end,
try
- sune
+ sune
of
- _ ->
- X = 5,
- (catch foo(X)),
- X + 10
+ _ ->
+ X = 5,
+ (catch foo(X)),
+ X + 10
catch _:_ -> baf
end,
try
- (catch sune)
+ (catch sune)
of
- _ ->
- catch foo() %% BUGBUG can't handle catch inside try without parentheses
+ _ ->
+ catch foo() %% BUGBUG can't handle catch inside try without parentheses
catch _:_ ->
- baf
+ baf
end,
try
- (catch exit())
+ (catch exit())
catch
- _ ->
- catch baf()
+ _ ->
+ catch baf()
end,
ok.
indent_binary() ->
X = lists:foldr(fun(M) ->
- <<Ma/binary, " ">>
- end, [], A),
+ <<Ma/binary, " ">>
+ end, [], A),
A = <<X/binary, 0:8>>,
B.
indent_comprehensions() ->
- %% I don't have a good idea how we want to handle this
+ %% I don't have a good idea how we want to handle this
%% but they are here to show how they are indented today.
- Result1 = [X ||
- #record{a=X} <- lists:seq(1, 10),
- true = (X rem 2)
- ],
+ Result1 = [X ||
+ #record{a=X} <- lists:seq(1, 10),
+ true = (X rem 2)
+ ],
Result2 = [X || <<X:32,_:32>> <= <<0:512>>,
- true = (X rem 2)
- ],
+ true = (X rem 2)
+ ],
- Binary1 = << <<X:8>> ||
- #record{a=X} <- lists:seq(1, 10),
- true = (X rem 2)
- >>,
+ Binary1 = << <<X:8>> ||
+ #record{a=X} <- lists:seq(1, 10),
+ true = (X rem 2)
+ >>,
Binary2 = << <<X:8>> || <<X:32,_:32>> <= <<0:512>>,
- true = (X rem 2)
- >>,
+ true = (X rem 2)
+ >>,
ok.
%% This causes an error in earlier erlang-mode versions.
foo() ->
[#foo{
- foo = foo}].
+ foo = foo}].
%% Record indentation
some_function_with_a_very_long_name() ->
@@ -704,20 +704,20 @@ some_function_with_a_very_long_name() ->
field1=a,
field2=b},
case dummy_function_with_a_very_very_long_name(x) of
- #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
- field1=a,
- field2=b} ->
- ok;
- Var = #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
- field1=a,
- field2=b} ->
- Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
- field1=a,
- field2=b};
- #xyz{
- a=1,
- b=2} ->
- ok
+ #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
+ field1=a,
+ field2=b} ->
+ ok;
+ Var = #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
+ field1=a,
+ field2=b} ->
+ Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{
+ field1=a,
+ field2=b};
+ #xyz{
+ a=1,
+ b=2} ->
+ ok
end.
another_function_with_a_very_very_long_name() ->
@@ -726,45 +726,45 @@ another_function_with_a_very_very_long_name() ->
field2=1}.
some_function_name_xyz(xyzzy, #some_record{
- field1=Field1,
- field2=Field2}) ->
+ field1=Field1,
+ field2=Field2}) ->
SomeVariable = f(#'Some-long-record-name'{
- field_a = 1,
- 'inter-xyz-parameters' =
- #'Some-other-very-long-record-name'{
- field2 = Field1,
- field2 = Field2}}),
+ field_a = 1,
+ 'inter-xyz-parameters' =
+ #'Some-other-very-long-record-name'{
+ field2 = Field1,
+ field2 = Field2}}),
{ok, SomeVariable}.
commas_first() ->
{abc, [ {some_var, 1}
- , {some_other_var, 2}
- , {erlang_ftw, 9}
- , {erlang_cookie, 'cookie'}
- , {cmds,
- [ {one, "sudo ls"}
- , {one, "sudo ls"}
- , {two, "sudo ls"}
- , {three, "sudo ls"}
- , {four, "sudo ls"}
- , {three, "sudo ls"}
- ] }
- , {ssh_username, "yow"}
- , {cluster,
- [ {aaaa, [ {"10.198.55.12" , "" }
- , {"10.198.55.13" , "" }
- ] }
- , {bbbb, [ {"10.198.55.151", "" }
- , {"10.198.55.123", "" }
- , {"10.198.55.34" , "" }
- , {"10.198.55.85" , "" }
- , {"10.198.55.67" , "" }
- ] }
- , {cccc, [ {"10.198.55.68" , "" }
- , {"10.198.55.69" , "" }
- ] }
- ] }
- ]
+ , {some_other_var, 2}
+ , {erlang_ftw, 9}
+ , {erlang_cookie, 'cookie'}
+ , {cmds,
+ [ {one, "sudo ls"}
+ , {one, "sudo ls"}
+ , {two, "sudo ls"}
+ , {three, "sudo ls"}
+ , {four, "sudo ls"}
+ , {three, "sudo ls"}
+ ] }
+ , {ssh_username, "yow"}
+ , {cluster,
+ [ {aaaa, [ {"10.198.55.12" , "" }
+ , {"10.198.55.13" , "" }
+ ] }
+ , {bbbb, [ {"10.198.55.151", "" }
+ , {"10.198.55.123", "" }
+ , {"10.198.55.34" , "" }
+ , {"10.198.55.85" , "" }
+ , {"10.198.55.67" , "" }
+ ] }
+ , {cccc, [ {"10.198.55.68" , "" }
+ , {"10.198.55.69" , "" }
+ ] }
+ ] }
+ ]
}.
@@ -776,9 +776,9 @@ commas_first() ->
%% body, due to the function name being mistaken for a keyword
catcher(N) ->
try generate_exception(N) of
- Val -> {N, normal, Val}
+ Val -> {N, normal, Val}
catch
- throw:X -> {N, caught, thrown, X};
- exit:X -> {N, caught, exited, X};
- error:X -> {N, caught, error, X}
+ throw:X -> {N, caught, thrown, X};
+ exit:X -> {N, caught, exited, X};
+ error:X -> {N, caught, error, X}
end.
diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig
index 2552c71baf..c0cf1749b6 100644
--- a/lib/tools/emacs/test.erl.orig
+++ b/lib/tools/emacs/test.erl.orig
@@ -1,4 +1,4 @@
-%% -*- erlang -*-
+%% -*- Mode: erlang; indent-tabs-mode: nil -*-
%%
%% %CopyrightBegin%
%%
@@ -27,7 +27,7 @@
%%% Created : 6 Oct 2009 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-%% Start off with syntax highlighting you have to verify this by looking here
+%% Start off with syntax highlighting you have to verify this by looking here
%% and see that the code looks alright
-module(test).
@@ -44,18 +44,18 @@ foo() ->
%% Module attributes should be highlighted
-export([t/1]).
--record(record1, {a,
- b,
+-record(record1, {a,
+ b,
c
}).
-record(record2, {
a,
b
}).
-
+
-record(record3, {a = 8#42423 bor
8#4234,
- b = 8#5432
+ b = 8#5432
bor 2#1010101
c = 123 +
234,
@@ -64,7 +64,7 @@ foo() ->
-record(record4, {
a = 8#42423 bor
8#4234,
- b = 8#5432
+ b = 8#5432
bor 2#1010101
c = 123 +
234,
@@ -79,31 +79,31 @@ foo() ->
-spec t(integer()) -> any().
--type ann() :: Var :: integer().
--type ann2() :: Var ::
- 'return'
- | 'return_white_spaces'
+-type ann() :: Var :: integer().
+-type ann2() :: Var ::
+ 'return'
+ | 'return_white_spaces'
| 'return_comments'
- | 'text' | ann().
--type paren() ::
- (ann2()).
--type t1() :: atom().
--type t2() :: [t1()].
--type t3(Atom) :: integer(Atom).
--type t4() :: t3(foobar).
--type t5() :: {t1(), t3(foo)}.
--type t6() :: 1 | 2 | 3 |
- 'foo' | 'bar'.
--type t7() :: [].
--type t71() :: [_].
+ | 'text' | ann().
+-type paren() ::
+ (ann2()).
+-type t1() :: atom().
+-type t2() :: [t1()].
+-type t3(Atom) :: integer(Atom).
+-type t4() :: t3(foobar).
+-type t5() :: {t1(), t3(foo)}.
+-type t6() :: 1 | 2 | 3 |
+ 'foo' | 'bar'.
+-type t7() :: [].
+-type t71() :: [_].
-type t8() :: {any(),none(),pid(),port(),
- reference(),float()}.
--type t9() :: [1|2|3|foo|bar] |
- list(a | b | c) | t71().
--type t10() :: {1|2|3|foo|t9()} | {}.
--type t11() :: 1..2.
--type t13() :: maybe_improper_list(integer(), t11()).
--type t14() :: [erl_scan:foo() |
+ reference(),float()}.
+-type t9() :: [1|2|3|foo|bar] |
+ list(a | b | c) | t71().
+-type t10() :: {1|2|3|foo|t9()} | {}.
+-type t11() :: 1..2.
+-type t13() :: maybe_improper_list(integer(), t11()).
+-type t14() :: [erl_scan:foo() |
%% Should be highlighted
term() |
bool() |
@@ -122,31 +122,31 @@ foo() ->
timeout() |
no_return() |
%% Should not be highlighted
- nonempty_() | nonlist() |
+ nonempty_() | nonlist() |
erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
-type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>,
<<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>|
<<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
-<<_:34>>|<<_:34>>|<<_:34>>].
--type t16() :: fun().
--type t17() :: fun((...) -> paren()).
--type t18() :: fun(() -> t17() | t16()).
+<<_:34>>|<<_:34>>|<<_:34>>].
+-type t16() :: fun().
+-type t17() :: fun((...) -> paren()).
+-type t18() :: fun(() -> t17() | t16()).
-type t19() :: fun((t18()) -> t16()) |
fun((nonempty_maybe_improper_list('integer', any())|
1|2|3|a|b|<<_:3,_:_*14>>|integer()) ->
nonempty_maybe_improper_list('integer', any())|
-1|2|3|a|b|<<_:3,_:_*14>>|integer()).
--type t20() :: [t19(), ...].
--type t21() :: tuple().
--type t21(A) :: A.
--type t22() :: t21(integer()).
--type t23() :: #rec1{}.
--type t24() :: #rec2{a :: t23(), b :: [atom()]}.
--type t25() :: #rec3{f123 :: [t24() |
-1|2|3|4|a|b|c|d|
-nonempty_maybe_improper_list(integer, any())]}.
+1|2|3|a|b|<<_:3,_:_*14>>|integer()).
+-type t20() :: [t19(), ...].
+-type t21() :: tuple().
+-type t21(A) :: A.
+-type t22() :: t21(integer()).
+-type t23() :: #rec1{}.
+-type t24() :: #rec2{a :: t23(), b :: [atom()]}.
+-type t25() :: #rec3{f123 :: [t24() |
+1|2|3|4|a|b|c|d|
+nonempty_maybe_improper_list(integer, any())]}.
-type t26() :: #rec4{ a :: integer()
, b :: any()
}.
@@ -155,7 +155,7 @@ nonempty_maybe_improper_list(integer, any())]}.
}.
-type t99() ::
{t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14(),
-t15(),t20(),t21(), t22(),t25()}.
+t15(),t20(),t21(), t22(),t25()}.
-spec t1(FooBar :: t99()) -> t99();
(t2()) -> t2();
(t4()) -> t4() when is_subtype(t4(), t24);
@@ -169,21 +169,21 @@ t15(),t20(),t21(), t22(),t25()}.
(A :: atom()) -> R2 :: foo:atomen();
(T :: tuple()) -> R3 :: bar:typen().
--spec mod:t2() -> any().
+-spec mod:t2() -> any().
--spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
+-spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
| {'del_member', name(), pid()},
#state{}) -> {'noreply', #state{}}.
--spec handle_cast(Cast ::
- {'exchange', node(), [[name(),...]]}
+-spec handle_cast(Cast ::
+ {'exchange', node(), [[name(),...]]}
| {'del_member', name(), pid()},
#state{}) -> {'noreply', #state{}}.
-spec all(fun((T) -> boolean()), List :: [T]) ->
boolean() when is_subtype(T, term()). % (*)
--spec get_closest_pid(term()) ->
+-spec get_closest_pid(term()) ->
Return :: pid()
| {'error', {'no_process', term()}
| {'no_such_group', term()}}.
@@ -192,23 +192,23 @@ t15(),t20(),t21(), t22(),t25()}.
, Y :: integer()
) -> integer().
--opaque attributes_data() ::
+-opaque attributes_data() ::
[{'column', column()} | {'line', info_line()} |
- {'text', string()}] | {line(),column()}.
+ {'text', string()}] | {line(),column()}.
-record(r,{
f1 :: attributes_data(),
-f222 = foo:bar(34, #rec3{}, 234234234423,
- aassdsfsdfsdf, 2234242323) ::
-[t24() | 1|2|3|4|a|b|c|d|
+f222 = foo:bar(34, #rec3{}, 234234234423,
+ aassdsfsdfsdf, 2234242323) ::
+[t24() | 1|2|3|4|a|b|c|d|
nonempty_maybe_improper_list(integer, any())],
-f333 :: [t24() | 1|2|3|4|a|b|c|d|
+f333 :: [t24() | 1|2|3|4|a|b|c|d|
nonempty_maybe_improper_list(integer, any())],
f3 = x:y(),
f4 = x:z() :: t99(),
f17 :: 'undefined',
f18 :: 1 | 2 | 'undefined',
f19 = 3 :: integer()|undefined,
-f5 = 3 :: undefined|integer()}).
+f5 = 3 :: undefined|integer()}).
-record(state, {
sequence_number = 1 :: integer()
@@ -230,12 +230,12 @@ highlighting(X) % Function definitions should be highlighted
'#1',atom,
$", atom, % atom should be ok
- $', atom,
-
+ $', atom,
+
"string$", atom, "string$", atom, % currently buggy I know...
"string\$", atom, % workaround for bug above
-
- "char $in string", atom,
+
+ "char $in string", atom,
'atom$', atom, 'atom$', atom,
'atom\$', atom,
@@ -270,18 +270,18 @@ highlighting(X) % Function definitions should be highlighted
erlang:anything(lists),
%% Guards
is_atom(foo), is_float(2.3), is_integer(32), is_number(4323.3),
- is_function(Fun), is_pid(self()),
+ is_function(Fun), is_pid(self()),
not_a_guard:is_list([]),
%% Other Types
atom, % not (currently) hightlighted
- 234234,
+ 234234,
234.43,
- [list, are, not, higlighted],
+ [list, are, not, higlighted],
{nor, is, tuple},
ok.
-
+
%%%
%%% Indentation
%%%
@@ -293,32 +293,32 @@ highlighting(X) % Function definitions should be highlighted
% Right
-indent_basics(X, Y, Z)
+indent_basics(X, Y, Z)
when X > 42,
Z < 13;
Y =:= 4711 ->
%% comments
% right comments
- case lists:filter(fun(_, AlongName,
- B,
+ case lists:filter(fun(_, AlongName,
+ B,
C) ->
true
- end,
+ end,
[a,v,b])
of
[] ->
Y = 5 * 43,
ok;
- [_|_] ->
+ [_|_] ->
Y = 5 * 43,
ok
end,
Y,
%% List, tuples and binaries
- [a,
+ [a,
b, c
],
- [ a,
+ [ a,
b, c
],
@@ -326,10 +326,10 @@ Y =:= 4711 ->
a,
b
],
- {a,
+ {a,
b,c
},
- { a,
+ { a,
b,c
},
@@ -337,7 +337,7 @@ Y =:= 4711 ->
a,
b
},
-
+
<<1:8,
2:8
>>,
@@ -359,21 +359,21 @@ Y =:= 4711 ->
c
),
-
+
(
a,
b,
c
),
- call(2#42423 bor
+ call(2#42423 bor
#4234,
2#5432,
other_arg),
ok;
-indent_basics(Xlongname,
+indent_basics(Xlongname,
#struct{a=Foo,
- b=Bar},
+ b=Bar},
[X|
Y]) ->
testing_next_clause,
@@ -451,13 +451,13 @@ indent_icr(Z) -> % icr = if case receive
%% receive
- receive
+ receive
{Z,_,_} ->
X = 43 div 4,
foo(X);
Z ->
X = 43 div 4,
- foo(X)
+ foo(X)
end,
receive
{Z,_,_} ->
@@ -473,33 +473,33 @@ indent_icr(Z) -> % icr = if case receive
foo(X);
Z ->
X = 43 div 4,
- foo(X)
+ foo(X)
after infinity ->
foo(X),
asd(X),
5*43
end,
receive
- after 10 ->
+ after 10 ->
foo(X),
asd(X),
5*43
end,
ok.
-
+
indent_fun() ->
%% Changed fun to one indention level
-Var = spawn(fun(X)
+Var = spawn(fun(X)
when X == 2;
- X > 10 ->
+ X > 10 ->
hello,
- case Hello() of
- true when is_atom(X) ->
+ case Hello() of
+ true when is_atom(X) ->
foo;
false ->
bar
end;
- (Foo) when is_atom(Foo),
+ (Foo) when is_atom(Foo),
is_integer(X) ->
X = 6* 45,
Y = true andalso
@@ -522,14 +522,14 @@ Fact(0) ->
indent_try_catch() ->
try
- io:format(stdout, "Parsing file ~s, ",
+ io:format(stdout, "Parsing file ~s, ",
[St0#leex.xfile]),
- {ok,Line3,REAs,Actions,St3} =
+ {ok,Line3,REAs,Actions,St3} =
parse_rules(Xfile, Line2, Macs, St2)
catch
exit:{badarg,R} ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R);
error:R % AD added clause
@@ -544,7 +544,7 @@ indent_try_catch() ->
foo(R);
error:R ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R)
after
@@ -577,12 +577,12 @@ indent_try_catch() ->
catch
exit:{badarg,R} ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R);
error:R ->
foo(R),
- io:format(stdout,
+ io:format(stdout,
"ERROR reason ~p~n",
R)
after
@@ -593,7 +593,7 @@ indent_try_catch() ->
end;
indent_try_catch() ->
try foo()
- after
+ after
foo(),
bar(with_long_arg,
with_second_arg)
@@ -602,16 +602,16 @@ indent_try_catch() ->
indent_catch() ->
D = B +
float(43.1),
-
+
B = catch oskar(X),
-
- A = catch (baz +
+
+ A = catch (baz +
bax),
catch foo(),
- C = catch B +
+ C = catch B +
float(43.1),
-
+
case catch foo(X) of
A ->
B
@@ -673,9 +673,9 @@ indent_binary() ->
indent_comprehensions() ->
-%% I don't have a good idea how we want to handle this
+%% I don't have a good idea how we want to handle this
%% but they are here to show how they are indented today.
-Result1 = [X ||
+Result1 = [X ||
#record{a=X} <- lists:seq(1, 10),
true = (X rem 2)
],
@@ -683,7 +683,7 @@ Result2 = [X || <<X:32,_:32>> <= <<0:512>>,
true = (X rem 2)
],
-Binary1 = << <<X:8>> ||
+Binary1 = << <<X:8>> ||
#record{a=X} <- lists:seq(1, 10),
true = (X rem 2)
>>,
diff --git a/lib/tools/examples/xref_examples.erl b/lib/tools/examples/xref_examples.erl
index 4c082195a2..f7e71c9708 100644
--- a/lib/tools/examples/xref_examples.erl
+++ b/lib/tools/examples/xref_examples.erl
@@ -7,7 +7,7 @@
%% ${HOME}/unused_locals.txt.
script() ->
Root = code:root_dir(),
- Dir = os:getenv("HOME"),
+ {ok,[[Dir]]} = init:get_argument(home),
Server = s,
xref:start(Server),
{ok, _Relname} = xref:add_release(Server, code:lib_dir(), {name,otp}),
diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl
index 8db23dd151..d1a4624419 100644
--- a/lib/tools/src/fprof.erl
+++ b/lib/tools/src/fprof.erl
@@ -1636,6 +1636,11 @@ trace_handler({trace_ts, Pid, gc_major_start, _Func, TS} = Trace, Table, _, Dump
dump_stack(Dump, get(Pid), Trace),
trace_gc_start(Table, Pid, TS),
TS;
+
+trace_handler({trace_ts, Pid, gc_start, _Func, TS} = Trace, Table, _, Dump) ->
+ dump_stack(Dump, get(Pid), Trace),
+ trace_gc_start(Table, Pid, TS),
+ TS;
%%
%% gc_end
@@ -1648,6 +1653,12 @@ trace_handler({trace_ts, Pid, gc_major_end, _Func, TS} = Trace, Table, _, Dump)
dump_stack(Dump, get(Pid), Trace),
trace_gc_end(Table, Pid, TS),
TS;
+
+trace_handler({trace_ts, Pid, gc_end, _Func, TS} = Trace, Table, _, Dump) ->
+ dump_stack(Dump, get(Pid), Trace),
+ trace_gc_end(Table, Pid, TS),
+ TS;
+
%%
%% link
trace_handler({trace_ts, Pid, link, _OtherPid, TS} = Trace,
@@ -1691,6 +1702,12 @@ trace_handler({trace_ts, Pid, send, _OtherPid, _Msg, TS} = Trace,
dump_stack(Dump, get(Pid), Trace),
TS;
%%
+%% send_to_non_existing_process
+trace_handler({trace_ts, Pid, send_to_non_existing_process, _OtherPid, _Msg, TS} = Trace,
+ _Table, _, Dump) ->
+ dump_stack(Dump, get(Pid), Trace),
+ TS;
+%%
%% 'receive'
trace_handler({trace_ts, Pid, 'receive', _Msg, TS} = Trace,
_Table, _, Dump) ->
diff --git a/lib/tools/src/make.erl b/lib/tools/src/make.erl
index 26378f28a0..37e67cbe34 100644
--- a/lib/tools/src/make.erl
+++ b/lib/tools/src/make.erl
@@ -317,5 +317,7 @@ check_includes2(Epp, File, ObjMTime) ->
epp:close(Epp),
false;
{error, _Error} ->
+ check_includes2(Epp, File, ObjMTime);
+ {warning, _Warning} ->
check_includes2(Epp, File, ObjMTime)
end.
diff --git a/lib/tools/src/tags.erl b/lib/tools/src/tags.erl
index b833d96c19..fff67eb0fd 100644
--- a/lib/tools/src/tags.erl
+++ b/lib/tools/src/tags.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/lib/tools/src/tools.app.src b/lib/tools/src/tools.app.src
index a00969eabe..4c7dd24006 100644
--- a/lib/tools/src/tools.app.src
+++ b/lib/tools/src/tools.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@
{env, [{file_util_search_methods,[{"", ""}, {"ebin", "esrc"}, {"ebin", "src"}]}
]
},
- {runtime_dependencies, ["stdlib-2.5","runtime_tools-1.8.14",
+ {runtime_dependencies, ["stdlib-3.1","runtime_tools-1.8.14",
"kernel-3.0","inets-5.10","erts-7.0",
"compiler-5.0"]}
]
diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl
index bb9815f9b0..f298a1ce81 100644
--- a/lib/tools/src/xref_base.erl
+++ b/lib/tools/src/xref_base.erl
@@ -746,7 +746,7 @@ read_a_module({Dir, BaseName}, AppName, Builtins, Verbose, Warnings, Mode) ->
message(Warnings, no_debug_info, [File]),
no;
{ok, M, Data, UnresCalls0} ->
- message(Verbose, done, [File]),
+ message(Verbose, done_file, [File]),
%% Remove duplicates. Identical unresolved calls on the
%% same line are counted as _one_ unresolved call.
UnresCalls = usort(UnresCalls0),
@@ -1842,6 +1842,8 @@ message(true, What, Arg) ->
set_up ->
io:format("Setting up...", Arg);
done ->
+ io:format("done~n", Arg);
+ done_file ->
io:format("done reading ~ts~n", Arg);
error ->
io:format("error~n", Arg);
diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl
index b4c9264b30..90e113c178 100644
--- a/lib/tools/test/cover_SUITE.erl
+++ b/lib/tools/test/cover_SUITE.erl
@@ -1001,41 +1001,40 @@ otp_6115(Config) when is_list(Config) ->
%% Cover compile f1, but not f2
{ok, f1} = cover:compile(f1),
+ %% This test used to ensure that a process containing a
+ %% fun refering to cover compiled code was killed.
+ %% check_process_code may however ignore funs as of ERTS
+ %% version 8.1. The test has therefore been rewritten to
+ %% check that a process with a direct reference (in this
+ %% case a return address) to the code is killed.
+ %%
%% If f1 is cover compiled, a process P is started with a
- %% reference to the fun created in start_fail/0, and cover:stop() is
- %% called, then P should be killed.
- %% This is because (the fun held by P) references the cover
+ %% direct reference to the f1, and cover:stop() is called,
+ %% then P should be killed.
+ %% This is because of the return address to the cover
%% compiled code which should be *unloaded* when cover:stop() is
%% called -- running cover compiled code when there is no cover
%% server and thus no ets tables to bump counters in, makes no
%% sense.
- Pid1 = f1:start_a(),
- Pid2 = f1:start_b(),
+ Pid = spawn(fun () -> f1:non_tail_call_f2_wait() end),
%% Now stop cover
cover:stop(),
%% Ensure that f1 is loaded (and not cover compiled), and that
- %% both Pid1 and Pid2 are dead.
+ %% both Pid is dead.
case code:which(f1) of
Beam when is_list(Beam) ->
ok;
Other ->
ct:fail({"f1 is not reloaded", Other})
end,
- case process_info(Pid1) of
+ case process_info(Pid) of
undefined ->
ok;
- _PI1 ->
- RefToOldP1 = erlang:check_process_code(Pid1, f1),
- ct:fail({"Pid1 still alive", RefToOldP1})
- end,
- case process_info(Pid2) of
- undefined ->
- ok;
- _PI2 ->
- RefToOldP2 = erlang:check_process_code(Pid1, f2),
- ct:fail({"Pid2 still alive", RefToOldP2})
+ _PI ->
+ RefToOldP = erlang:check_process_code(Pid, f1),
+ ct:fail({"Pid still alive", RefToOldP})
end,
file:set_cwd(CWD),
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
index 5399b33f19..fc4a62e70e 100644
--- a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl
@@ -1,13 +1,6 @@
-module(f1).
--export([start_a/0, start_b/0]).
+-export([non_tail_call_f2_wait/0]).
-start_a() ->
- f2:start(fun() ->
- ok
- end).
-
-start_b() ->
- f2:start(fun fun1/0).
-
-fun1() ->
- ok.
+non_tail_call_f2_wait() ->
+ f2:wait(),
+ im_back.
diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
index 72a6a64c4d..4bc88035c7 100644
--- a/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
+++ b/lib/tools/test/cover_SUITE_data/otp_6115/f2.erl
@@ -1,13 +1,5 @@
-module(f2).
--export([start/1]).
+-export([wait/0]).
-start(Fun) ->
- spawn(fun() ->
- wait(Fun)
- end).
-
-wait(Fun) ->
- receive
- go ->
- Fun()
- end.
+wait() ->
+ receive after infinity -> ok end.
diff --git a/lib/tools/test/make_SUITE_data/test1.erl b/lib/tools/test/make_SUITE_data/test1.erl
index f4a133008e..9e21bdc767 100644
--- a/lib/tools/test/make_SUITE_data/test1.erl
+++ b/lib/tools/test/make_SUITE_data/test1.erl
@@ -3,6 +3,8 @@
-vsn('$Revision: /main/release/2 $').
-compile(export_all).
+-warning("a warning").
+
f1() ->
true.
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index ce30fb711a..01dbac6ecb 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -50,7 +50,7 @@
-export([analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]).
--export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1]).
+-export([format_error/1, otp_7423/1, otp_7831/1, otp_10192/1, otp_13708/1]).
-import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]).
@@ -82,7 +82,7 @@ groups() ->
fun_mfa_r14, fun_mfa_vars, qlc]},
{analyses, [],
[analyze, basic, md, q, variables, unused_locals]},
- {misc, [], [format_error, otp_7423, otp_7831, otp_10192]}].
+ {misc, [], [format_error, otp_7423, otp_7831, otp_10192, otp_13708]}].
init_per_suite(Conf) when is_list(Conf) ->
@@ -2393,6 +2393,19 @@ otp_10192(Conf) when is_list(Conf) ->
xref:stop(s),
ok.
+%% OTP-10192. Allow filenames with character codes greater than 126.
+otp_13708(Conf) when is_list(Conf) ->
+ {ok, _} = start(s),
+ ok = xref:set_default(s, [{verbose, true}]),
+ {ok, []} = xref:q(s,"E"),
+ xref:stop(s),
+
+ CopyDir = ?copydir,
+ Dir = fname(CopyDir,"lib_test"),
+ {ok, _} = start(s),
+ ok = xref:set_library_path(s, [Dir], [{verbose, true}]),
+ xref:stop(s).
+
%%%
%%% Utilities
%%%
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 8c889cbe4e..f60da27c44 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.8.4
+TOOLS_VSN = 2.9.1