From 8755c68695ee5c672a4105077ac2e5953939d528 Mon Sep 17 00:00:00 2001 From: Johan Claesson Date: Mon, 3 Sep 2018 22:19:45 +0200 Subject: Emacs: add test-erlang-mode --- lib/tools/emacs/test-erlang-mode | 81 ++++++++++++++++++++++++++++++++++++++++ lib/tools/test/emacs_SUITE.erl | 64 +++++++++++++++++++------------ 2 files changed, 122 insertions(+), 23 deletions(-) create mode 100755 lib/tools/emacs/test-erlang-mode diff --git a/lib/tools/emacs/test-erlang-mode b/lib/tools/emacs/test-erlang-mode new file mode 100755 index 0000000000..910af48ed8 --- /dev/null +++ b/lib/tools/emacs/test-erlang-mode @@ -0,0 +1,81 @@ +#!/bin/bash + +# Usage: test-erlang-mode [options] +# +# Basic test script for erlang.el +# +# Options: +# -f - Forgiving mode. Return success if no +# suitable emacs is found. +# + +invalid_emacs_rc=33 + +tmp=$(getopt --options hf --long help: -- "$@") || exit + +eval set -- $tmp + +while true +do + case "$1" in + -f) + invalid_emacs_rc=0 + shift;; + + --) + shift + break;; + + -h|--help) + echo + sed -nr '/^# Usage:/,/^$/ s/^# ?//p' "$0" + exit;; + esac +done + + +set -e + +cd $(dirname "$0") + +if ! type emacs &> /dev/null +then + echo "Skipping emacs test due to no emacs in PATH" + exit "$invalid_emacs_rc" +fi + +version="$(emacs --version | head -n1)" +version_number="${version#GNU Emacs }" +version_major="${version_number%%\.*}" + + +case "$version_major" in + [0-9][0-9]) + if [ "$version_major" -lt 24 ] + then + echo "Skipping emacs test due to too old emacs ($version_major)" + exit "$invalid_emacs_rc" + fi;; + *) + echo "Skipping emacs test due to unsupported emacs version ($version)" + exit "$invalid_emacs_rc";; +esac + +set -x + +# Test interpreted erlang-mode. +emacs -Q -batch -L . -l erlang.el -f erlang-mode + +# Compile. +emacs -Q -batch -L . -f batch-byte-compile *.el + +# Test compiled erlang-mode. +emacs -Q -batch -L . -l erlang.elc -f erlang-mode + +# Run unit tests in interpreted mode. +emacs -Q -batch -L . -l erlang.el -l erlang-test.el \ + -f ert-run-tests-batch-and-exit + +# Run unit tests in compiled mode. +emacs -Q -batch -L . -l erlang.elc -l erlang-test.elc \ + -f ert-run-tests-batch-and-exit diff --git a/lib/tools/test/emacs_SUITE.erl b/lib/tools/test/emacs_SUITE.erl index 5839f9ce5b..387c93f9fa 100644 --- a/lib/tools/test/emacs_SUITE.erl +++ b/lib/tools/test/emacs_SUITE.erl @@ -23,18 +23,18 @@ -export([all/0, init_per_testcase/2, end_per_testcase/2]). --export([bif_highlight/1, indent/1]). +-export([bif_highlight/1, indent/1, test_erlang_mode_script/1]). all() -> - [bif_highlight, indent]. + [bif_highlight, indent, test_erlang_mode_script]. init_per_testcase(_Case, Config) -> ErlangEl = filename:join([code:lib_dir(tools),"emacs","erlang.el"]), case file:read_file_info(ErlangEl) of - {ok, _} -> - [{el, ErlangEl}|Config]; - _ -> - {skip, "Could not find erlang.el"} + {ok, _} -> + [{el, ErlangEl}|Config]; + _ -> + {skip, "Could not find erlang.el"} end. end_per_testcase(_Case, _Config) -> @@ -46,26 +46,26 @@ bif_highlight(Config) -> %% All auto-imported bifs IntBifs = lists:usort( - [F || {F,A} <- erlang:module_info(exports), - erl_internal:bif(F,A)]), + [F || {F,A} <- erlang:module_info(exports), + erl_internal:bif(F,A)]), %% all bif which need erlang: prefix and are not operands ExtBifs = lists:usort( - [F || {F,A} <- erlang:module_info(exports), - not erl_internal:bif(F,A) andalso - not is_atom(catch erl_internal:op_type(F,A))]), + [F || {F,A} <- erlang:module_info(exports), + not erl_internal:bif(F,A) andalso + not is_atom(catch erl_internal:op_type(F,A))]), check_bif_highlight(Bin, <<"erlang-int-bifs">>, IntBifs), check_bif_highlight(Bin, <<"erlang-ext-bifs">>, ExtBifs). - + check_bif_highlight(Bin, Tag, Compare) -> - [_H,IntMatch,_T] = - re:split(Bin,<<"defvar ",Tag/binary, - "[^(]*\\(([^)]*)">>,[]), - EmacsIntBifs = [list_to_atom(S) || - S <- string:tokens(binary_to_list(IntMatch)," '\"\n")], - + [_H,IntMatch,_T] = + re:split(Bin,<<"defvar ",Tag/binary, + "[^(]*\\(([^)]*)">>,[]), + EmacsIntBifs = [list_to_atom(S) || + S <- string:tokens(binary_to_list(IntMatch)," '\"\n")], + ct:log("Emacs ~p",[EmacsIntBifs]), ct:log("Int ~p",[Compare]), @@ -73,14 +73,17 @@ check_bif_highlight(Bin, Tag, Compare) -> ct:log("Diff2 ~p",[EmacsIntBifs -- Compare]), [] = Compare -- EmacsIntBifs, [] = EmacsIntBifs -- Compare. - + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% indent(Config) -> case emacs_version_ok() of false -> {skip, "Old or no emacs found"}; true -> - Def = filename:dirname(code:which(?MODULE)) ++ "/" ++ ?MODULE_STRING ++ "_data", + Def = filename:dirname(code:which(?MODULE)) + ++ "/" + ++ ?MODULE_STRING + ++ "_data", Dir = proplists:get_value(data_dir, Config, Def), OrigFs = filelib:wildcard(Dir ++ "/*"), io:format("Dir: ~s~nFs: ~p~n", [Dir, OrigFs]), @@ -119,7 +122,7 @@ emacs_version_ok() -> {Vsn, _} when Vsn >= 24.1 -> true; _ -> - io:format("Emacs version fail~n~s~n~n",[Ver]), + io:format("Unsupported Emacs version~n~s~n~n",[Ver]), false end; Res -> @@ -128,10 +131,9 @@ emacs_version_ok() -> end. emacs(File) -> - EmacsErlDir = filename:join([code:lib_dir(tools), "emacs"]), Cmd = ["emacs ", "--batch --quick ", - "--directory ", EmacsErlDir, " ", + "--directory ", emacs_dir(), " ", "--eval \"(require 'erlang-start)\" ", File, " ", "--eval '(indent-region (point-min) (point-max) nil)' ", @@ -140,3 +142,19 @@ emacs(File) -> _Res = os:cmd(Cmd), % io:format("cmd ~s:~n=> ~s~n", [Cmd, _Res]), ok. + +emacs_dir() -> + filename:join([code:lib_dir(tools), "emacs"]). + +test_erlang_mode_script(_Config) -> + Script = filename:join([emacs_dir(), "test-erlang-mode"]), + RcFile = string:trim(os:cmd("mktemp /tmp/emacs_SUITE.XXXXXX")), + Output = os:cmd(Script ++ " -f; echo $? > " ++ RcFile), + io:format("~s output:~n~ts~n", [Script, Output]), + {ok, RcBin} = file:read_file(RcFile), + ok = file:delete(RcFile), + RcString = binary:bin_to_list(RcBin), + {Rc, _} = string:to_integer(RcString), + io:format("Script return code: ~p~n", [Rc]), + 0 = Rc, + ok. -- cgit v1.2.3 From 02e3a9b162a1fe193c271cd0db7a99c326b63844 Mon Sep 17 00:00:00 2001 From: Johan Claesson Date: Sat, 15 Sep 2018 23:14:47 +0200 Subject: Emacs: do not accept compiler warnings in selected elisp files --- lib/tools/emacs/erlang-edoc.el | 1 + lib/tools/emacs/erlang-eunit.el | 10 +++--- lib/tools/emacs/erlang-pkg.el | 3 ++ lib/tools/emacs/erlang-skels.el | 2 +- lib/tools/emacs/erlang-test.el | 74 +++++++++++++++++++++------------------- lib/tools/emacs/erlang.el | 37 ++++++++++---------- lib/tools/emacs/erlang_appwiz.el | 13 +++---- lib/tools/emacs/test-erlang-mode | 49 ++++++++++++++++++++------ lib/tools/test/emacs_SUITE.erl | 2 +- 9 files changed, 112 insertions(+), 79 deletions(-) diff --git a/lib/tools/emacs/erlang-edoc.el b/lib/tools/emacs/erlang-edoc.el index d0dcc81028..ea1e263faf 100644 --- a/lib/tools/emacs/erlang-edoc.el +++ b/lib/tools/emacs/erlang-edoc.el @@ -28,6 +28,7 @@ (defcustom erlang-edoc-indent-level 2 "Indentation level of xhtml in Erlang edoc." + :type '(integer) :safe 'integerp :group 'erlang) diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el index 38c40927f4..53543d7b01 100644 --- a/lib/tools/emacs/erlang-eunit.el +++ b/lib/tools/emacs/erlang-eunit.el @@ -23,6 +23,7 @@ (eval-when-compile (require 'cl)) +(require 'erlang) (defvar erlang-eunit-src-candidate-dirs '("../src" ".") "*Name of directories which to search for source files matching @@ -331,8 +332,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." t) (apply test-fun test-args) (if under-cover - (save-excursion - (set-buffer (find-file-noselect src-filename)) + (with-current-buffer (find-file-noselect src-filename) (erlang-eunit-analyze-coverage))))))) (defun erlang-eunit-compile-and-run-module-tests-under-cover () @@ -348,8 +348,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." (defun erlang-eunit-compile-file (file-path &optional under-cover) (if (file-readable-p file-path) - (save-excursion - (set-buffer (find-file-noselect file-path)) + (with-current-buffer (find-file-noselect file-path) ;; In order to run a code coverage analysis on a ;; module, we have two options: ;; @@ -376,8 +375,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set." (error msg)))) (defun erlang-eunit-last-compilation-successful-p () - (save-excursion - (set-buffer inferior-erlang-buffer) + (with-current-buffer inferior-erlang-buffer (goto-char compilation-parsing-end) (erlang-eunit-all-list-elems-fulfill-p (lambda (re) (let ((continue t) diff --git a/lib/tools/emacs/erlang-pkg.el b/lib/tools/emacs/erlang-pkg.el index 02d6bebbf4..7e95e4050e 100644 --- a/lib/tools/emacs/erlang-pkg.el +++ b/lib/tools/emacs/erlang-pkg.el @@ -1,3 +1,6 @@ (define-package "erlang" "2.7.0" "Erlang major mode" '((emacs "24.1"))) +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/lib/tools/emacs/erlang-skels.el b/lib/tools/emacs/erlang-skels.el index 534f50ab33..3ebc6e8e1e 100644 --- a/lib/tools/emacs/erlang-skels.el +++ b/lib/tools/emacs/erlang-skels.el @@ -1985,7 +1985,7 @@ configured off." The first character of DD is space if the value is less than 10." (let ((date (current-time-string))) (format "%2d %s %s" - (string-to-int (substring date 8 10)) + (string-to-number (substring date 8 10)) (substring date 4 7) (substring date -4)))) diff --git a/lib/tools/emacs/erlang-test.el b/lib/tools/emacs/erlang-test.el index efe3d515e9..ca0b641791 100644 --- a/lib/tools/emacs/erlang-test.el +++ b/lib/tools/emacs/erlang-test.el @@ -29,7 +29,7 @@ ;; This library require GNU Emacs 25 or later. ;; -;; There are two ways to run emacs unit tests. +;; There are three ways to run the erlang emacs unit tests. ;; ;; 1. Within a running emacs process. Load this file. Then to run ;; all defined test cases: @@ -49,11 +49,15 @@ ;; ;; The -L option adds a directory to the load-path. It should be the ;; directory containing erlang.el and erlang-test.el. +;; +;; 3. Call the script test-erlang-mode in this directory. This script +;; use the second method. ;;; Code: +(eval-when-compile + (require 'cl)) (require 'ert) -(require 'cl-lib) (require 'erlang) (defvar erlang-test-code @@ -116,8 +120,8 @@ concatenated to form an erlang file to test on.") (defun erlang-test-create-erlang-file (erlang-file) (with-temp-file erlang-file - (cl-loop for (_ . code) in erlang-test-code - do (insert code "\n")))) + (loop for (_ . code) in erlang-test-code + do (insert code "\n")))) (defun erlang-test-compile-tags (erlang-file tags-file) (should (zerop (call-process "etags" nil nil nil @@ -132,19 +136,19 @@ concatenated to form an erlang file to test on.") (sort (erlang-expected-completion-table) #'string-lessp)))) (defun erlang-expected-completion-table () - (append (cl-loop for (symbol . _) in erlang-test-code - when (stringp symbol) - append (list symbol (concat "erlang_test:" symbol))) + (append (loop for (symbol . _) in erlang-test-code + when (stringp symbol) + append (list symbol (concat "erlang_test:" symbol))) (list "erlang_test:" "erlang_test:module_info"))) (defun erlang-test-xref-find-definitions (erlang-file erlang-buffer) - (cl-loop for (tagname . code) in erlang-test-code - for line = 1 then (1+ line) - do (when tagname - (switch-to-buffer erlang-buffer) - (erlang-test-xref-jump tagname erlang-file line) - (erlang-test-xref-jump (concat "erlang_test:" tagname) - erlang-file line))) + (loop for (tagname . code) in erlang-test-code + for line = 1 then (1+ line) + do (when tagname + (switch-to-buffer erlang-buffer) + (erlang-test-xref-jump tagname erlang-file line) + (erlang-test-xref-jump (concat "erlang_test:" tagname) + erlang-file line))) (erlang-test-xref-jump "erlang_test:" erlang-file 1)) (defun erlang-test-xref-jump (id expected-file expected-line) @@ -213,27 +217,27 @@ concatenated to form an erlang file to test on.") (ert-deftest erlang-test-parse-id () - (cl-loop for id-string in '("fun/10" - "qualified-function module:fun/10" - "record reko" - "macro _SYMBOL" - "macro MACRO/10" - "module modula" - "macro" - nil) - for id-list in '((nil nil "fun" 10) - (qualified-function "module" "fun" 10) - (record nil "reko" nil) - (macro nil "_SYMBOL" nil) - (macro nil "MACRO" 10) - (module nil "modula" nil) - (nil nil "macro" nil) - nil) - for id-list2 = (erlang-id-to-list id-string) - do (should (equal id-list id-list2)) - for id-string2 = (erlang-id-to-string id-list) - do (should (equal id-string id-string2)) - collect id-list2)) + (loop for id-string in '("fun/10" + "qualified-function module:fun/10" + "record reko" + "macro _SYMBOL" + "macro MACRO/10" + "module modula" + "macro" + nil) + for id-list in '((nil nil "fun" 10) + (qualified-function "module" "fun" 10) + (record nil "reko" nil) + (macro nil "_SYMBOL" nil) + (macro nil "MACRO" 10) + (module nil "modula" nil) + (nil nil "macro" nil) + nil) + for id-list2 = (erlang-id-to-list id-string) + do (should (equal id-list id-list2)) + for id-string2 = (erlang-id-to-string id-list) + do (should (equal id-string id-string2)) + collect id-list2)) (provide 'erlang-test) diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index 82e5c2222d..fc6966c3e8 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -78,6 +78,8 @@ (eval-when-compile (require 'cl)) (require 'align) +(require 'comint) +(require 'tempo) ;; Variables: @@ -334,6 +336,7 @@ when a new function header is generated. When nil, no blank line is inserted between the current line and the new header. When bound to a number it represents the number of blank lines which should be inserted." + :type '(restricted-sexp :match-alternatives (integerp 'nil)) :group 'erlang) (defvar erlang-electric-semicolon-criteria @@ -1711,10 +1714,10 @@ Personal extensions could be added to `erlang-menu-personal-items'. This function should be called if any variable describing the menu configuration is changed." - (erlang-menu-install "Erlang" erlang-menu-items erlang-mode-map t)) + (erlang-menu-install "Erlang" erlang-menu-items erlang-mode-map)) -(defun erlang-menu-install (name items keymap &optional popup) +(defun erlang-menu-install (name items keymap) "Install a menu in Emacs based on an abstract description. NAME is the name of the menu. @@ -4207,22 +4210,18 @@ Return t if criteria fulfilled, nil otherwise." nil))))) -(defun erlang-in-literal (&optional lim) +(defun erlang-in-literal () "Test if point is in string, quoted atom or comment. Return one of the three atoms `atom', `string', and `comment'. 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 (funcall (symbol-function 'syntax-ppss)))) - (cond - ((eq (nth 3 state) ?') 'atom) - ((nth 3 state) 'string) - ((nth 4 state) 'comment) - (t nil))))) + (let ((state (funcall (symbol-function 'syntax-ppss)))) + (cond ((eq (nth 3 state) ?') 'atom) + ((nth 3 state) 'string) + ((nth 4 state) 'comment) + (t nil))))) (defun erlang-at-end-of-function-p () @@ -5041,7 +5040,10 @@ considered first when it is time to jump to the definition.") (defun erlang-visit-tags-table-buffer (cont cbuf) (if (< emacs-major-version 26) (visit-tags-table-buffer cont) - (visit-tags-table-buffer cont cbuf))) + ;; Remove this with-no-warnings when Emacs 26 is the required + ;; version minimum. + (with-no-warnings + (visit-tags-table-buffer cont cbuf)))) (defun erlang-xref-find-definitions-module-tag (module tag @@ -5536,7 +5538,7 @@ Return the position after the newly inserted command." (+ insert-point insert-length))) -(defun inferior-erlang-strip-delete (&optional s) +(defun inferior-erlang-strip-delete (&optional _s) "Remove `^H' (delete) and the characters it was supposed to remove." (interactive) (if (and (boundp 'comint-last-input-end) @@ -5554,7 +5556,7 @@ Return the position after the newly inserted command." ;; Basically `comint-strip-ctrl-m', with a few extra checks. -(defun inferior-erlang-strip-ctrl-m (&optional string) +(defun inferior-erlang-strip-ctrl-m (&optional _string) "Strip trailing `^M' characters from the current output group." (interactive) (if (and (boundp 'comint-last-input-end) @@ -5591,8 +5593,8 @@ There exists two workarounds for this bug: (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)) + (when arg + (list 'debug_info 'export_all)) erlang-compile-extra-opts)) end) (with-current-buffer inferior-erlang-buffer @@ -5641,7 +5643,6 @@ unless the optional NO-DISPLAY is non-nil." (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 result) diff --git a/lib/tools/emacs/erlang_appwiz.el b/lib/tools/emacs/erlang_appwiz.el index ecbce66f47..b71c180739 100644 --- a/lib/tools/emacs/erlang_appwiz.el +++ b/lib/tools/emacs/erlang_appwiz.el @@ -103,6 +103,10 @@ ;; ;; +(defvar appwiz-erlang-modulename "foo") +(defvar appwiz-erlang-ext "_work") + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Erlang application wizard @@ -245,13 +249,6 @@ creating the root directory and for naming application files." (insert "Application specification file for " name ".") (save-buffer))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; These are setq:ed -;; - -(defvar appwiz-erlang-modulename "foo") -(defvar appwiz-erlang-ext "_work") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -468,7 +465,7 @@ Call the function `erlang-menu-init' after modifying this variable.") The first character of DD is *not* space if the value is less than 10." (let ((date (current-time-string))) (format "%d %s %s" - (string-to-int (substring date 8 10)) + (string-to-number (substring date 8 10)) (substring date 4 7) (substring date -4)))) diff --git a/lib/tools/emacs/test-erlang-mode b/lib/tools/emacs/test-erlang-mode index 910af48ed8..2418d23c92 100755 --- a/lib/tools/emacs/test-erlang-mode +++ b/lib/tools/emacs/test-erlang-mode @@ -48,6 +48,7 @@ version="$(emacs --version | head -n1)" version_number="${version#GNU Emacs }" version_major="${version_number%%\.*}" +echo "Emacs version $version" case "$version_major" in [0-9][0-9]) @@ -60,22 +61,50 @@ case "$version_major" in echo "Skipping emacs test due to unsupported emacs version ($version)" exit "$invalid_emacs_rc";; esac - + set -x # Test interpreted erlang-mode. emacs -Q -batch -L . -l erlang.el -f erlang-mode -# Compile. -emacs -Q -batch -L . -f batch-byte-compile *.el +# Compile everything except erldoc.el. +for el in *.el +do + [ "$el" = "erldoc.el" ] && continue + emacs -Q -batch -L . -f batch-byte-compile "$el" +done # Test compiled erlang-mode. emacs -Q -batch -L . -l erlang.elc -f erlang-mode -# Run unit tests in interpreted mode. -emacs -Q -batch -L . -l erlang.el -l erlang-test.el \ - -f ert-run-tests-batch-and-exit - -# Run unit tests in compiled mode. -emacs -Q -batch -L . -l erlang.elc -l erlang-test.elc \ - -f ert-run-tests-batch-and-exit +if [ "$version_major" -ge 25 ] +then + # Run unit tests in interpreted mode. + emacs -Q -batch -L . -l erlang.el -l erlang-test.el \ + -f ert-run-tests-batch-and-exit + + # Run unit tests in compiled mode. + emacs -Q -batch -L . -l erlang.elc -l erlang-test.elc \ + -f ert-run-tests-batch-and-exit + + # Compile erldoc which depends on cl-lib which was introduced in + # Emacs 25. + emacs -Q -batch -L . -f batch-byte-compile erldoc.el + + # Compile selected files again and this time do not accept any + # warnings. Add files here whenever they are cleaned of warnings. + if [ "$version_major" -ge 26 ] + then + unforgiving="(setq byte-compile-error-on-warn t)" + else + # Workaround byte-compile-error-on-warn which seem broken in + # Emacs 25. + unforgiving="(advice-add #'display-warning :after \ + (lambda (_ f _ _) (error \"%s\" f)))" + fi + for el in erlang.el erlang-test.el erlang-edoc.el \ + erlang-start.el erldoc.el + do + emacs -Q -batch -L . --eval "$unforgiving" -f batch-byte-compile "$el" + done +fi diff --git a/lib/tools/test/emacs_SUITE.erl b/lib/tools/test/emacs_SUITE.erl index 387c93f9fa..0ad00d8fdb 100644 --- a/lib/tools/test/emacs_SUITE.erl +++ b/lib/tools/test/emacs_SUITE.erl @@ -150,7 +150,7 @@ test_erlang_mode_script(_Config) -> Script = filename:join([emacs_dir(), "test-erlang-mode"]), RcFile = string:trim(os:cmd("mktemp /tmp/emacs_SUITE.XXXXXX")), Output = os:cmd(Script ++ " -f; echo $? > " ++ RcFile), - io:format("~s output:~n~ts~n", [Script, Output]), + io:format("~s output:~n~n~ts~n", [Script, Output]), {ok, RcBin} = file:read_file(RcFile), ok = file:delete(RcFile), RcString = binary:bin_to_list(RcBin), -- cgit v1.2.3 From 8e938ab671bdcadbf6571426e045de7855a5b196 Mon Sep 17 00:00:00 2001 From: Johan Claesson Date: Sun, 16 Sep 2018 21:04:35 +0200 Subject: Emacs: consider case in erlang-get-identifier-at-point --- lib/tools/emacs/erlang-test.el | 7 ++++--- lib/tools/emacs/erlang.el | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/tools/emacs/erlang-test.el b/lib/tools/emacs/erlang-test.el index ca0b641791..2ee584d11a 100644 --- a/lib/tools/emacs/erlang-test.el +++ b/lib/tools/emacs/erlang-test.el @@ -67,7 +67,7 @@ ("SYMBOL" . "-define(SYMBOL, value).") ("MACRO" . "-define(MACRO(X), X + X).") ("struct" . "-record(struct, {until,maps,are,everywhere}).") - ("function". "function() -> #struct{}.")) + ("function" . "function() -> #struct{}.")) "Alist of erlang test code. Each entry have the format (TAGNAME . ERLANG_CODE). If TAGNAME is nil there is no definitions in the ERLANG_CODE. The @@ -147,8 +147,9 @@ concatenated to form an erlang file to test on.") do (when tagname (switch-to-buffer erlang-buffer) (erlang-test-xref-jump tagname erlang-file line) - (erlang-test-xref-jump (concat "erlang_test:" tagname) - erlang-file line))) + (when (string-equal tagname "function") + (erlang-test-xref-jump (concat "erlang_test:" tagname) + erlang-file line)))) (erlang-test-xref-jump "erlang_test:" erlang-file 1)) (defun erlang-test-xref-jump (id expected-file expected-line) diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index fc6966c3e8..3cbe9daa60 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -3697,16 +3697,17 @@ retried without regard to module. 4. Arity - Integer in case of functions and macros if the number of arguments could be found, otherwise nil." (save-excursion - (save-match-data - (if (eq (char-syntax (following-char)) ? ) - (skip-chars-backward " \t")) - (skip-chars-backward "[:word:]_:'") - (cond ((looking-at erlang-module-function-regexp) - (erlang-get-qualified-function-id-at-point)) - ((looking-at (concat erlang-atom-regexp ":")) - (erlang-get-module-id-at-point)) - ((looking-at erlang-name-regexp) - (erlang-get-some-other-id-at-point)))))) + (let (case-fold-search) + (save-match-data + (if (eq (char-syntax (following-char)) ? ) + (skip-chars-backward " \t")) + (skip-chars-backward "[:word:]_:'") + (cond ((looking-at erlang-module-function-regexp) + (erlang-get-qualified-function-id-at-point)) + ((looking-at (concat erlang-atom-regexp ":")) + (erlang-get-module-id-at-point)) + ((looking-at erlang-name-regexp) + (erlang-get-some-other-id-at-point))))))) (defun erlang-get-qualified-function-id-at-point () (let ((kind 'qualified-function) -- cgit v1.2.3 From b7a6a4ba1c1d91146af44f9d83cb53486a852c9c Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Mon, 1 Oct 2018 17:04:03 +0200 Subject: Run emacs tests from test_suite Drive emacs test from test_suite instead of bash script. --- lib/tools/emacs/Makefile | 1 + lib/tools/emacs/test-erlang-mode | 110 ---------------------------- lib/tools/test/emacs_SUITE.erl | 153 +++++++++++++++++++++++++++------------ 3 files changed, 107 insertions(+), 157 deletions(-) delete mode 100755 lib/tools/emacs/test-erlang-mode diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile index ea4d6cb723..b7775d1c8c 100644 --- a/lib/tools/emacs/Makefile +++ b/lib/tools/emacs/Makefile @@ -46,6 +46,7 @@ EMACS_FILES= \ erlang-eunit \ erlang-edoc \ erlang-flymake \ + erlang-test \ erlang README_FILES= README diff --git a/lib/tools/emacs/test-erlang-mode b/lib/tools/emacs/test-erlang-mode deleted file mode 100755 index 2418d23c92..0000000000 --- a/lib/tools/emacs/test-erlang-mode +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/bash - -# Usage: test-erlang-mode [options] -# -# Basic test script for erlang.el -# -# Options: -# -f - Forgiving mode. Return success if no -# suitable emacs is found. -# - -invalid_emacs_rc=33 - -tmp=$(getopt --options hf --long help: -- "$@") || exit - -eval set -- $tmp - -while true -do - case "$1" in - -f) - invalid_emacs_rc=0 - shift;; - - --) - shift - break;; - - -h|--help) - echo - sed -nr '/^# Usage:/,/^$/ s/^# ?//p' "$0" - exit;; - esac -done - - -set -e - -cd $(dirname "$0") - -if ! type emacs &> /dev/null -then - echo "Skipping emacs test due to no emacs in PATH" - exit "$invalid_emacs_rc" -fi - -version="$(emacs --version | head -n1)" -version_number="${version#GNU Emacs }" -version_major="${version_number%%\.*}" - -echo "Emacs version $version" - -case "$version_major" in - [0-9][0-9]) - if [ "$version_major" -lt 24 ] - then - echo "Skipping emacs test due to too old emacs ($version_major)" - exit "$invalid_emacs_rc" - fi;; - *) - echo "Skipping emacs test due to unsupported emacs version ($version)" - exit "$invalid_emacs_rc";; -esac - -set -x - -# Test interpreted erlang-mode. -emacs -Q -batch -L . -l erlang.el -f erlang-mode - -# Compile everything except erldoc.el. -for el in *.el -do - [ "$el" = "erldoc.el" ] && continue - emacs -Q -batch -L . -f batch-byte-compile "$el" -done - -# Test compiled erlang-mode. -emacs -Q -batch -L . -l erlang.elc -f erlang-mode - -if [ "$version_major" -ge 25 ] -then - # Run unit tests in interpreted mode. - emacs -Q -batch -L . -l erlang.el -l erlang-test.el \ - -f ert-run-tests-batch-and-exit - - # Run unit tests in compiled mode. - emacs -Q -batch -L . -l erlang.elc -l erlang-test.elc \ - -f ert-run-tests-batch-and-exit - - # Compile erldoc which depends on cl-lib which was introduced in - # Emacs 25. - emacs -Q -batch -L . -f batch-byte-compile erldoc.el - - # Compile selected files again and this time do not accept any - # warnings. Add files here whenever they are cleaned of warnings. - if [ "$version_major" -ge 26 ] - then - unforgiving="(setq byte-compile-error-on-warn t)" - else - # Workaround byte-compile-error-on-warn which seem broken in - # Emacs 25. - unforgiving="(advice-add #'display-warning :after \ - (lambda (_ f _ _) (error \"%s\" f)))" - fi - for el in erlang.el erlang-test.el erlang-edoc.el \ - erlang-start.el erldoc.el - do - emacs -Q -batch -L . --eval "$unforgiving" -f batch-byte-compile "$el" - done -fi diff --git a/lib/tools/test/emacs_SUITE.erl b/lib/tools/test/emacs_SUITE.erl index 0ad00d8fdb..a6d43d1816 100644 --- a/lib/tools/test/emacs_SUITE.erl +++ b/lib/tools/test/emacs_SUITE.erl @@ -23,16 +23,26 @@ -export([all/0, init_per_testcase/2, end_per_testcase/2]). --export([bif_highlight/1, indent/1, test_erlang_mode_script/1]). +-export([bif_highlight/1, + load_interpreted/1, compile_and_load/1, + indent/1, + tests_interpreted/1, tests_compiled/1 + ]). all() -> - [bif_highlight, indent, test_erlang_mode_script]. + [bif_highlight, load_interpreted, compile_and_load, + indent, + tests_interpreted, tests_compiled + ]. -init_per_testcase(_Case, Config) -> +init_per_testcase(Case, Config) -> ErlangEl = filename:join([code:lib_dir(tools),"emacs","erlang.el"]), case file:read_file_info(ErlangEl) of {ok, _} -> - [{el, ErlangEl}|Config]; + case Case =:= bif_highlight orelse emacs_version_ok(24.1) of + false -> {skip, "Old or no emacs found"}; + _ -> [{el, ErlangEl}|Config] + end; _ -> {skip, "Could not find erlang.el"} end. @@ -76,27 +86,89 @@ check_bif_highlight(Bin, Tag, Compare) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -indent(Config) -> - case emacs_version_ok() of +load_interpreted(_Config) -> + _ = emacs(["-l erlang.el -f erlang-mode"]), + ok. + +compile_and_load(_Config) -> + Dir = emacs_dir(), + Files0 = filelib:wildcard("*.el", Dir), + Files = case emacs_version_ok(24.3) of + %% erldoc.el depends on cl-lib which was introduced in 24.3. + false -> Files0 -- ["erldoc.el"]; + _ -> Files0 + end, + Unforgiving = + case emacs_version_ok(24) of + Ver when Ver < 25 -> + ""; + Ver when Ver < 26 -> + %% Workaround byte-compile-error-on-warn which seem broken in + %% Emacs 25. + "\"(advice-add #'display-warning :after " + "(lambda (_ f _ _) (error \"%s\" f)))\""; + _ -> + "\"(setq byte-compile-error-on-warn t)\"" + end, + %% Add files here whenever they are cleaned of warnings. + NoWarn = ["erlang.el", "erlang-test.el", "erlang-edoc.el", "erlang-start.el", "erldoc.el"], + Compile = fun(File) -> + Pedantic = case lists:member(File, NoWarn) andalso Unforgiving /= "" of + true -> ["--eval ", Unforgiving, " "]; + false -> " " + end, + emacs([Pedantic, + " -f batch-byte-compile ",filename:join(Dir, File)]), + true + end, + lists:foreach(Compile, Files), + emacs(["-l erlang.elc -f erlang-mode"]), + ok. + +tests_interpreted(_Config) -> + case emacs_version_ok(25) of false -> {skip, "Old or no emacs found"}; - true -> - Def = filename:dirname(code:which(?MODULE)) - ++ "/" - ++ ?MODULE_STRING - ++ "_data", - Dir = proplists:get_value(data_dir, Config, Def), - OrigFs = filelib:wildcard(Dir ++ "/*"), - io:format("Dir: ~s~nFs: ~p~n", [Dir, OrigFs]), - Fs = [{File, unindent(File)} || File <- OrigFs, - filename:extension(File) =:= ""], - Indent = fun emacs/1, - [Indent(File) || {_, File} <- Fs], - Res = [diff(Orig, File) || {Orig, File} <- Fs], - [file:delete(File) || {ok, File} <- Res], %% Cleanup - [] = [Fail || {fail, Fail} <- Res], + _ -> + emacs(["-l erlang.el ", + "-l erlang-test.el -f ert-run-tests-batch-and-exit"]), ok end. +tests_compiled(_Config) -> + case emacs_version_ok(25) of + false -> {skip, "Old or no emacs found"}; + _ -> + emacs(["-l erlang.elc ", + "-l erlang-test.elc -f ert-run-tests-batch-and-exit"]), + ok + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +indent(Config) -> + Def = filename:dirname(code:which(?MODULE)) + ++ "/" + ++ ?MODULE_STRING + ++ "_data", + Dir = proplists:get_value(data_dir, Config, Def), + OrigFs = filelib:wildcard(Dir ++ "/*"), + io:format("Dir: ~s~nFs: ~p~n", [Dir, OrigFs]), + Fs = [{File, unindent(File)} || File <- OrigFs, + filename:extension(File) =:= ""], + Indent = fun(File) -> + emacs([ + File, " ", + "--eval '(indent-region (point-min) (point-max) nil)' ", + "--eval '(save-buffer 0)'" + ]), + ok + end, + [Indent(File) || {_, File} <- Fs], + Res = [diff(Orig, File) || {Orig, File} <- Fs], + [file:delete(File) || {ok, File} <- Res], %% Cleanup + [] = [Fail || {fail, Fail} <- Res], + ok. + unindent(Input) -> Output = Input ++ ".erl", {ok, Bin} = file:read_file(Input), @@ -115,14 +187,13 @@ diff(Orig, File) -> {fail, File} end. -emacs_version_ok() -> +emacs_version_ok(AcceptVer) -> case os:cmd("emacs --version | head -1") of "GNU Emacs " ++ Ver -> case string:to_float(Ver) of - {Vsn, _} when Vsn >= 24.1 -> - true; + {Vsn, _} when Vsn >= AcceptVer -> + Vsn; _ -> - io:format("Unsupported Emacs version~n~s~n~n",[Ver]), false end; Res -> @@ -130,31 +201,19 @@ emacs_version_ok() -> false end. -emacs(File) -> +emacs(EmacsCmds) when is_list(EmacsCmds) -> Cmd = ["emacs ", "--batch --quick ", "--directory ", emacs_dir(), " ", - "--eval \"(require 'erlang-start)\" ", - File, " ", - "--eval '(indent-region (point-min) (point-max) nil)' ", - "--eval '(save-buffer 0)'" - ], - _Res = os:cmd(Cmd), - % io:format("cmd ~s:~n=> ~s~n", [Cmd, _Res]), - ok. + "--eval \"(require 'erlang-start)\" " + | EmacsCmds], + Res0 = os:cmd(Cmd ++ " ; echo $?"), + Rows = string:lexemes(Res0, ["\r\n", $\n]), + Res = lists:last(Rows), + Output = string:join(lists:droplast(Rows), "\n"), + io:format("Cmd ~s:~n => ~s ~ts~n", [Cmd, Res, Output]), + "0" = Res, + Output. emacs_dir() -> filename:join([code:lib_dir(tools), "emacs"]). - -test_erlang_mode_script(_Config) -> - Script = filename:join([emacs_dir(), "test-erlang-mode"]), - RcFile = string:trim(os:cmd("mktemp /tmp/emacs_SUITE.XXXXXX")), - Output = os:cmd(Script ++ " -f; echo $? > " ++ RcFile), - io:format("~s output:~n~n~ts~n", [Script, Output]), - {ok, RcBin} = file:read_file(RcFile), - ok = file:delete(RcFile), - RcString = binary:bin_to_list(RcBin), - {Rc, _} = string:to_integer(RcString), - io:format("Script return code: ~p~n", [Rc]), - 0 = Rc, - ok. -- cgit v1.2.3