diff options
Diffstat (limited to 'lib/tools/emacs')
-rw-r--r-- | lib/tools/emacs/Makefile | 2 | ||||
-rw-r--r-- | lib/tools/emacs/erlang-edoc.el | 172 | ||||
-rw-r--r-- | lib/tools/emacs/erlang-skels.el | 50 | ||||
-rw-r--r-- | lib/tools/emacs/erlang-start.el | 15 | ||||
-rw-r--r-- | lib/tools/emacs/erlang.el | 3524 | ||||
-rw-r--r-- | lib/tools/emacs/erldoc.el | 508 | ||||
-rw-r--r-- | lib/tools/emacs/test.erl.indented | 810 | ||||
-rw-r--r-- | lib/tools/emacs/test.erl.orig | 210 |
8 files changed, 3002 insertions, 2289 deletions
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 0284c9d686..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. @@ -904,7 +904,7 @@ Please see the function `tempo-define-template'.") "%% @doc" n "%% Define the callback_mode() for this callback module." n (erlang-skel-separator-end 2) - "-spec callback_mode() -> gen_statem:callback_mode()." n + "-spec callback_mode() -> gen_statem:callback_mode_result()." n "callback_mode() -> state_functions." n n (erlang-skel-separator-start 2) @@ -915,11 +915,7 @@ Please see the function `tempo-define-template'.") "%% process to initialize." n (erlang-skel-separator-end 2) "-spec init(Args :: term()) ->" n> - "{ok, State :: term(), Data :: term()} |" n> - "{ok, State :: term(), Data :: term()," n> - "[gen_statem:action()] | gen_statem:action()} |" n> - "ignore |" n> - "{stop, Reason :: term()}." n + "gen_statem:init_result(atom())." n "init([]) ->" n> "process_flag(trap_exit, true)," n> "{ok, state_name, #data{}}." n @@ -931,14 +927,16 @@ Please see the function `tempo-define-template'.") "%% 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 - "%%" n - "%% NOTE: If there is an exported function handle_event/4, it is called" n - "%% instead of StateName/3 functions like this!" 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_function_result()." n + "gen_statem:state_enter_result('state_name');" n> + "(gen_statem:event_type()," n> + "Msg :: term()," n> + "Data :: term()) ->" 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 @@ -1015,7 +1013,7 @@ Please see the function `tempo-define-template'.") "%% @doc" n "%% Define the callback_mode() for this callback module." n (erlang-skel-separator-end 2) - "-spec callback_mode() -> gen_statem:callback_mode()." n + "-spec callback_mode() -> gen_statem:callback_mode_result()." n "callback_mode() -> handle_event_function." n n (erlang-skel-separator-start 2) @@ -1026,11 +1024,7 @@ Please see the function `tempo-define-template'.") "%% process to initialize." n (erlang-skel-separator-end 2) "-spec init(Args :: term()) ->" n> - "{ok, State :: term(), Data :: term()} |" n> - "{ok, State :: term(), Data :: term()," n> - "[gen_statem:action()] | gen_statem:action()} |" n> - "ignore |" n> - "{stop, Reason :: term()}." n + "gen_statem:init_result(term())." n "init([]) ->" n> "process_flag(trap_exit, true)," n> "{ok, state_name, #data{}}." n @@ -1039,14 +1033,18 @@ Please see the function `tempo-define-template'.") "%% @private" n "%% @doc" n "%% This function is called for every event a gen_statem receives." n - "%%" n - "%% NOTE: If there is no exported function handle_event/4," n - "%% StateName/3 functions are called instead!" 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 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 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.el b/lib/tools/emacs/erlang.el index 73c6b8d768..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,6 +1445,11 @@ Other commands: (erlang-skel-init) (when (fboundp 'tempo-use-tag-list) (tempo-use-tag-list 'erlang-tempo-tags)) + (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))) @@ -1448,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)) @@ -1486,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)) @@ -1512,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) @@ -1552,9 +1564,9 @@ Other commands: "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) @@ -1563,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 @@ -1588,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. @@ -1606,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 "'")))))) @@ -1653,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))) @@ -1755,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))) @@ -1813,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, @@ -1845,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))) @@ -1868,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))))) @@ -1909,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) @@ -1950,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))) @@ -1967,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)) @@ -1981,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 @@ -2016,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))) @@ -2050,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) @@ -2067,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)))) @@ -2115,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 @@ -2181,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))) @@ -2196,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) @@ -2220,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 () @@ -2281,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) @@ -2350,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)))) @@ -2364,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: @@ -2395,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)))) @@ -2419,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)) @@ -2456,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)) @@ -2474,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)) @@ -2528,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)))) @@ -2537,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)))) @@ -2552,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)) @@ -2571,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)) @@ -2599,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) @@ -2851,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 @@ -2904,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." @@ -3063,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'. @@ -3096,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) @@ -3149,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?" @@ -3175,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 @@ -3210,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. @@ -3267,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) @@ -3290,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)) @@ -3318,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 @@ -3360,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))) @@ -3380,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))))) @@ -3395,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) @@ -3461,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 () @@ -3486,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))) @@ -3514,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) @@ -3545,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))) @@ -3566,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))) @@ -3601,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 () @@ -3619,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) @@ -3654,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 () @@ -3668,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))))) @@ -3678,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. @@ -3716,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 () @@ -3741,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))) @@ -3782,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))) @@ -3794,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) @@ -3866,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) @@ -3915,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) @@ -3929,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) @@ -3958,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) @@ -3971,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) @@ -3986,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) @@ -4038,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) @@ -4057,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. @@ -4083,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) @@ -4113,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) @@ -4161,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) @@ -4179,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) @@ -4197,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 () @@ -4206,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 () @@ -4218,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)))) @@ -4244,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))) @@ -4273,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 () @@ -4298,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: @@ -4351,11 +4368,11 @@ 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) + (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) @@ -4380,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) @@ -4397,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'. @@ -4420,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))) @@ -4452,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. @@ -4467,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)))) @@ -4479,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 @@ -4500,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. + - @@ -4588,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 @@ -4626,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 () @@ -4650,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)) @@ -4694,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 @@ -4709,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 () @@ -4722,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 () @@ -4758,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. ;;; @@ -4807,18 +4824,18 @@ about Erlang modules." ((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 () @@ -4842,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 @@ -4854,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)))) @@ -4970,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)))))) @@ -5212,28 +5229,28 @@ The following special commands are available: ;; 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)) @@ -5243,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])))) @@ -5261,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))) @@ -5335,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 @@ -5363,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)) @@ -5404,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)) @@ -5436,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 () @@ -5445,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. @@ -5468,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") @@ -5490,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) @@ -5506,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))) @@ -5529,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. @@ -5547,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) @@ -5578,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 @@ -5603,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) @@ -5615,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) ".") @@ -5750,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) @@ -5780,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) @@ -5832,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. @@ -5881,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. ;; @@ -5900,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) @@ -5915,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))) @@ -5933,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) >>, |