From 1c3a6c89c4f8d25dc0a3f71f4967ad80729cdbfe Mon Sep 17 00:00:00 2001 From: Ulf Wiger Date: Thu, 17 Dec 2009 23:54:51 +0100 Subject: Shell tab completion now works for quoted module and function names While quoted atoms in module and function names are not common, they are allowed, and sometimes quite useful. In OTP, they are commonplace in ORBER, and can also be found in XMERL. Tab completion needs to recognize quoted atoms and act accordingly. This patch includes changes in edlin:over_word/1. It should be noted that these changes also affect the 'kill word', 'forward word' and 'backward word' commands in the line editor. The author thinks that the changes are for the better. There are also minor changes in edlin_expand.erl - mainly in regard to the conversion between atoms and strings. Another change is that the list of matches is now sorted, partly to simplify testing, but also because it seems sensible to present the matches that way. A test suite, edlin_expand_SUITE, has been added to the stdlib test suites. (amended 2009-12-18 to actually include the modified files too and again to rename the capitalized test modules for portability.) --- lib/stdlib/test/ExpandTestCaps.erl | 32 +++++++ lib/stdlib/test/ExpandTestCaps1.erl | 44 ++++++++++ lib/stdlib/test/Makefile | 5 ++ lib/stdlib/test/edlin_expand_SUITE.erl | 156 +++++++++++++++++++++++++++++++++ lib/stdlib/test/expand_test.erl | 32 +++++++ lib/stdlib/test/expand_test1.erl | 44 ++++++++++ 6 files changed, 313 insertions(+) create mode 100644 lib/stdlib/test/ExpandTestCaps.erl create mode 100644 lib/stdlib/test/ExpandTestCaps1.erl create mode 100644 lib/stdlib/test/edlin_expand_SUITE.erl create mode 100644 lib/stdlib/test/expand_test.erl create mode 100644 lib/stdlib/test/expand_test1.erl (limited to 'lib/stdlib/test') diff --git a/lib/stdlib/test/ExpandTestCaps.erl b/lib/stdlib/test/ExpandTestCaps.erl new file mode 100644 index 0000000000..15da7dbeff --- /dev/null +++ b/lib/stdlib/test/ExpandTestCaps.erl @@ -0,0 +1,32 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module('ExpandTestCaps'). + +-export([a_fun_name/1, + a_less_fun_name/1, + b_comes_after_a/1]). + +a_fun_name(X) -> + X. + +a_less_fun_name(X) -> + X. + +b_comes_after_a(X) -> + X. diff --git a/lib/stdlib/test/ExpandTestCaps1.erl b/lib/stdlib/test/ExpandTestCaps1.erl new file mode 100644 index 0000000000..b934f4b9cc --- /dev/null +++ b/lib/stdlib/test/ExpandTestCaps1.erl @@ -0,0 +1,44 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module('ExpandTestCaps1'). + +-export([a_fun_name/1, + a_less_fun_name/1, + b_comes_after_a/1, + 'Quoted_fun_name'/0, + 'Quoted_fun_too'/0, + '#weird-fun-name'/0]). + +a_fun_name(X) -> + X. + +a_less_fun_name(X) -> + X. + +b_comes_after_a(X) -> + X. + +'Quoted_fun_name'() -> + whoopee. + +'Quoted_fun_too'() -> + too. + +'#weird-fun-name'() -> + weird. diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile index 7a87eef5f3..ac8cbba375 100644 --- a/lib/stdlib/test/Makefile +++ b/lib/stdlib/test/Makefile @@ -18,6 +18,7 @@ MODULES= \ digraph_utils_SUITE \ dummy1_h \ dummy_h \ + edlin_expand_SUITE \ epp_SUITE \ erl_eval_helper \ erl_eval_SUITE \ @@ -29,6 +30,10 @@ MODULES= \ escript_SUITE \ ets_SUITE \ ets_tough_SUITE \ + expand_test \ + expand_test1 \ + ExpandTestCaps \ + ExpandTestCaps1 \ filelib_SUITE \ file_sorter_SUITE \ filename_SUITE \ diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl new file mode 100644 index 0000000000..d757230016 --- /dev/null +++ b/lib/stdlib/test/edlin_expand_SUITE.erl @@ -0,0 +1,156 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(edlin_expand_SUITE). +-export([all/1]). + +-export([normal/1, quoted_fun/1, quoted_module/1, quoted_both/1]). + +-export([init_per_testcase/2, fin_per_testcase/2]). + +-include("test_server.hrl"). + +% Default timetrap timeout (set in init_per_testcase). +-define(default_timeout, ?t:minutes(1)). + +init_per_testcase(_Case, Config) -> + ?line Dog = ?t:timetrap(?default_timeout), + [{watchdog, Dog} | Config]. +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +all(doc) -> + ["Test cases for edlin_expand."]; +all(suite) -> + [normal, quoted_fun, quoted_module, quoted_both]. + +normal(doc) -> + [""]; +normal(suite) -> + []; +normal(Config) when is_list(Config) -> + ?line {module,expand_test} = c:l(expand_test), + % These tests might fail if another module with the prefix "expand_" happens + % to also be loaded. + ?line {yes, "test:", []} = edlin_expand:expand(lists:reverse("expand_")), + ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")), + ?line {no,[], + [{"a_fun_name",1}, + {"a_less_fun_name",1}, + {"b_comes_after_a",1}, + {"module_info",0}, + {"module_info",1}]} = edlin_expand:expand(lists:reverse("expand_test:")), + ?line {yes,[],[{"a_fun_name",1}, + {"a_less_fun_name",1}]} = edlin_expand:expand( + lists:reverse("expand_test:a_")), + ok. + +quoted_fun(doc) -> + ["Normal module name, some function names using quoted atoms"]; +quoted_fun(suite) -> + []; +quoted_fun(Config) when is_list(Config) -> + ?line {module,expand_test} = c:l(expand_test), + ?line {module,expand_test1} = c:l(expand_test1), + %% should be no colon after test this time + ?line {yes, "test", []} = edlin_expand:expand(lists:reverse("expand_")), + ?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")), + ?line {no,[],[{"'#weird-fun-name'",0}, + {"'Quoted_fun_name'",0}, + {"'Quoted_fun_too'",0}, + {"a_fun_name",1}, + {"a_less_fun_name",1}, + {"b_comes_after_a",1}, + {"module_info",0}, + {"module_info",1}]} = edlin_expand:expand( + lists:reverse("expand_test1:")), + ?line {yes,"_",[]} = edlin_expand:expand( + lists:reverse("expand_test1:a")), + ?line {yes,[],[{"a_fun_name",1}, + {"a_less_fun_name",1}]} = edlin_expand:expand( + lists:reverse("expand_test1:a_")), + ?line {yes,[], + [{"'#weird-fun-name'",0}, + {"'Quoted_fun_name'",0}, + {"'Quoted_fun_too'",0}]} = edlin_expand:expand( + lists:reverse("expand_test1:'")), + ?line {yes,"uoted_fun_",[]} = edlin_expand:expand( + lists:reverse("expand_test1:'Q")), + ?line {yes,[], + [{"'Quoted_fun_name'",0}, + {"'Quoted_fun_too'",0}]} = edlin_expand:expand( + lists:reverse("expand_test1:'Quoted_fun_")), + ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand( + lists:reverse("expand_test1:'#")), + ok. + +quoted_module(doc) -> + [""]; +quoted_module(suite) -> + []; +quoted_module(Config) when is_list(Config) -> + ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'), + ?line {yes, "Caps':", []} = edlin_expand:expand(lists:reverse("'ExpandTest")), + ?line {no,[], + [{"a_fun_name",1}, + {"a_less_fun_name",1}, + {"b_comes_after_a",1}, + {"module_info",0}, + {"module_info",1}]} = edlin_expand:expand(lists:reverse("'ExpandTestCaps':")), + ?line {yes,[],[{"a_fun_name",1}, + {"a_less_fun_name",1}]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps':a_")), + ok. + +quoted_both(suite) -> + []; +quoted_both(Config) when is_list(Config) -> + ?line {module,'ExpandTestCaps'} = c:l('ExpandTestCaps'), + ?line {module,'ExpandTestCaps1'} = c:l('ExpandTestCaps1'), + %% should be no colon (or quote) after test this time + ?line {yes, "Caps", []} = edlin_expand:expand(lists:reverse("'ExpandTest")), + ?line {no,[],[{"'#weird-fun-name'",0}, + {"'Quoted_fun_name'",0}, + {"'Quoted_fun_too'",0}, + {"a_fun_name",1}, + {"a_less_fun_name",1}, + {"b_comes_after_a",1}, + {"module_info",0}, + {"module_info",1}]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps1':")), + ?line {yes,"_",[]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps1':a")), + ?line {yes,[],[{"a_fun_name",1}, + {"a_less_fun_name",1}]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps1':a_")), + ?line {yes,[], + [{"'#weird-fun-name'",0}, + {"'Quoted_fun_name'",0}, + {"'Quoted_fun_too'",0}]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps1':'")), + ?line {yes,"uoted_fun_",[]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps1':'Q")), + ?line {yes,[], + [{"'Quoted_fun_name'",0}, + {"'Quoted_fun_too'",0}]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps1':'Quoted_fun_")), + ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand( + lists:reverse("'ExpandTestCaps1':'#")), + ok. diff --git a/lib/stdlib/test/expand_test.erl b/lib/stdlib/test/expand_test.erl new file mode 100644 index 0000000000..4a0e0b4784 --- /dev/null +++ b/lib/stdlib/test/expand_test.erl @@ -0,0 +1,32 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(expand_test). + +-export([a_fun_name/1, + a_less_fun_name/1, + b_comes_after_a/1]). + +a_fun_name(X) -> + X. + +a_less_fun_name(X) -> + X. + +b_comes_after_a(X) -> + X. diff --git a/lib/stdlib/test/expand_test1.erl b/lib/stdlib/test/expand_test1.erl new file mode 100644 index 0000000000..8e9344fa31 --- /dev/null +++ b/lib/stdlib/test/expand_test1.erl @@ -0,0 +1,44 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(expand_test1). + +-export([a_fun_name/1, + a_less_fun_name/1, + b_comes_after_a/1, + 'Quoted_fun_name'/0, + 'Quoted_fun_too'/0, + '#weird-fun-name'/0]). + +a_fun_name(X) -> + X. + +a_less_fun_name(X) -> + X. + +b_comes_after_a(X) -> + X. + +'Quoted_fun_name'() -> + whoopee. + +'Quoted_fun_too'() -> + too. + +'#weird-fun-name'() -> + weird. -- cgit v1.2.3