diff options
author | Ulf Wiger <[email protected]> | 2009-12-17 23:54:51 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-01-07 10:13:49 +0100 |
commit | 1c3a6c89c4f8d25dc0a3f71f4967ad80729cdbfe (patch) | |
tree | 9b46e2dbc05b66b97d06e472bda7c8af2511adc5 /lib/stdlib/src | |
parent | ebaa01050deb2bbc4cf4e1279e3d8ffe220080d9 (diff) | |
download | otp-1c3a6c89c4f8d25dc0a3f71f4967ad80729cdbfe.tar.gz otp-1c3a6c89c4f8d25dc0a3f71f4967ad80729cdbfe.tar.bz2 otp-1c3a6c89c4f8d25dc0a3f71f4967ad80729cdbfe.zip |
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.)
Diffstat (limited to 'lib/stdlib/src')
-rw-r--r-- | lib/stdlib/src/edlin.erl | 26 | ||||
-rw-r--r-- | lib/stdlib/src/edlin_expand.erl | 39 |
2 files changed, 50 insertions, 15 deletions
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl index 31a653bda0..d5ab294fb8 100644 --- a/lib/stdlib/src/edlin.erl +++ b/lib/stdlib/src/edlin.erl @@ -281,12 +281,32 @@ do_op(_, Bef, Aft, Rs) -> %% Step over word/non-word characters pushing the stepped over ones on %% the stack. -over_word([C|Cs], Stack, N) -> + +over_word(Cs, Stack, N) -> + L = length([1 || $\' <- Cs]), + case L rem 2 of + 0 -> + over_word1(Cs, Stack, N); + 1 -> + until_quote(Cs, Stack, N) + end. + +until_quote([$\'|Cs], Stack, N) -> + {Cs, [$\'|Stack], N+1}; +until_quote([C|Cs], Stack, N) -> + until_quote(Cs, [C|Stack], N+1). + +over_word1([$\'=C|Cs], Stack, N) -> + until_quote(Cs, [C|Stack], N+1); +over_word1(Cs, Stack, N) -> + over_word2(Cs, Stack, N). + +over_word2([C|Cs], Stack, N) -> case word_char(C) of - true -> over_word(Cs, [C|Stack], N+1); + true -> over_word2(Cs, [C|Stack], N+1); false -> {[C|Cs],Stack,N} end; -over_word([], Stack, N) when is_integer(N) -> +over_word2([], Stack, N) when is_integer(N) -> {[],Stack,N}. over_non_word([C|Cs], Stack, N) -> diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl index 7ed76a6b09..a38e118e68 100644 --- a/lib/stdlib/src/edlin_expand.erl +++ b/lib/stdlib/src/edlin_expand.erl @@ -46,23 +46,38 @@ expand_module_name(Prefix) -> match(Prefix, code:all_loaded(), ":"). expand_function_name(ModStr, FuncPrefix) -> - Mod = list_to_atom(ModStr), - case erlang:module_loaded(Mod) of - true -> - L = Mod:module_info(), - case lists:keyfind(exports, 1, L) of - {_, Exports} -> - match(FuncPrefix, Exports, "("); - _ -> - {no, [], []} - end; - false -> + case to_atom(ModStr) of + {ok, Mod} -> + case erlang:module_loaded(Mod) of + true -> + L = Mod:module_info(), + case lists:keyfind(exports, 1, L) of + {_, Exports} -> + match(FuncPrefix, Exports, "("); + _ -> + {no, [], []} + end; + false -> + {no, [], []} + end; + error -> {no, [], []} end. +%% if it's a quoted atom, atom_to_list/1 will do the wrong thing. +to_atom(Str) -> + case erl_scan:string(Str) of + {ok, [{atom,_,A}], _} -> + {ok, A}; + _ -> + error + end. + match(Prefix, Alts, Extra) -> Len = length(Prefix), - Matches = [{S, A} || {H, A} <- Alts, prefix(Prefix, S=atom_to_list(H))], + Matches = lists:sort( + [{S, A} || {H, A} <- Alts, + prefix(Prefix, S=hd(io_lib:fwrite("~w",[H])))]), case longest_common_head([N || {N, _} <- Matches]) of {partial, []} -> {no, [], Matches}; % format_matches(Matches)}; |