cmdcon: more mt fixes
[iv.d.git] / autocomplete.d
blob418a1a0c3511071acc52d0ee4498cbfb74462100
1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module iv.autocomplete is aliced;
20 import iv.alice;
23 /**
24 * Build list of suitable autocompletions.
26 * Params:
27 * cmd = user-given command prefix
28 * cmdlist = list of all available commands
30 * Returns:
31 * null = no matches (empty array)
32 * array with one item: exactly one match
33 * array with more that one item = [0] is max prefix, then list of autocompletes
35 * Throws:
36 * Out of memory exception
38 string[] autocomplete (string cmd, string[] cmdlist...) @trusted nothrow {
39 if (cmdlist.length == 0) return [cmd];
40 string found; // autoinit
41 usize foundlen, pfxcount; // autoinit
42 // ÐÅÒ×ÙÊ ÐÒÏÈÏÄ: ÓÞÉÔÁÅÍ ÐÒÅÆÉËÓÙ, ÚÁÐÏÍÉÎÁÅÍ ËÏÍÁÎÄÕ Ó ÓÁÍÙÍ ÄÌÉÎÎÙÍ ÐÒÅÆÉËÓÏÍ
43 foreach (immutable s; cmdlist) {
44 if (cmd.length <= s.length) {
45 usize pos = cmd.length;
46 foreach (immutable idx; 0..cmd.length) if (cmd[idx] != s[idx]) { pos = idx; break; }
47 if (pos == cmd.length) {
48 if (s.length > found.length) found = s;
49 ++pfxcount;
53 if (pfxcount == 0) return null; // ÎÅ ÎÁÛÌÉ ×ÏÏÂÝÅ ÎÉÈÅÒÁ, ×ÁÌÉÍ ÏÔÓÀÄÁ, ÐÁÃÁÎÙ!
54 if (pfxcount == 1) return [found]; // ÅÓÔØ ÔÏÌØËÏ ÏÄÉÎ, ÕÎÏÓÉÔÅ
55 // ÎÁÛÌÉ ÄÏÈÅÒÁ, ÜÔÏ ÐÒÉÓËÏÒÂÎÏ
56 // ÉÝÅÍ ÓÁÍÙÊ ÄÌÉÎÎÙÊ ÐÒÅÆÉËÓ ÉÚ ×ÏÚÍÏÖÎÙÈ, ÚÁÏÄÎÏ ÓÏÂÉÒÁÅÍ ×Ó£, ÞÔÏ ÍÏÖÎÏ
57 string[] res = new string[pfxcount+1]; // ÓÀÄÁ ÓÌÏÖÉÍ ×Ó£ ÐÏÄÈÏÄÑÝÅÅ; ÍÙ ÔÏÞÎÏ ÚÎÁÅÍ, ÓËÏÌØËÏ ÉÈ ÂÕÄÅÔ
58 usize respos = 1; // res[0] -- ÓÁÍÙÊ ÄÌÉÎÎÙÊ ÐÒÅÆÉËÓ, ÎÁÞÎ£Í Ó [1]
59 usize slen = cmd.length; // ÔÏÞÎÏ ÎÅ ÂÏÌØÛÅ found.length
60 foreach (immutable s; cmdlist) {
61 if (s.length >= slen) {
62 usize pos = slen;
63 foreach (immutable idx; 0..slen) if (found[idx] != s[idx]) { pos = idx; break; }
64 if (pos == slen) {
65 // ÎÁÛÅ, ÚÁÐÏÍÉÎÁÅÍ É ÐÒÁ×ÉÍ ÐÒÅÆÉËÓ
66 res[respos++] = s;
67 // ÏÂÒÅÚÁÅÍ ÐÏ ÍÉÎÉÍÕÍÕ, ÎÏ ÎÅ ÍÅÎØÛÅ, ÞÅÍ ÎÁÄÏ
68 for (; pos < found.length && pos < s.length; ++pos) if (found[pos] != s[pos]) break;
69 if (pos < found.length) {
70 found = found[0..pos];
71 if (slen > pos) slen = pos;
76 // ÐÅÒ×ÙÍ ÜÌÅÍÅÎÔÏÍ ×ÓÔÁ×ÉÍ ÍÁËÓÉÍÁÌØÎÙÊ ÐÒÅÆÉËÓ
77 res[0] = found;
78 // ×Ó£
79 return res;
83 unittest {
84 import std.stdio;
86 static immutable string[3] clist0 = ["aaz", "aabed", "aand"];
87 //writeln("--------");
88 assert(autocomplete("", clist0) == ["aa", "aaz", "aabed", "aand"]);
89 assert(autocomplete("a", clist0) == ["aa", "aaz", "aabed", "aand"]);
90 assert(autocomplete("aa", clist0) == ["aa", "aaz", "aabed", "aand"]);
91 assert(autocomplete("aab", clist0) == ["aabed"]);
94 static immutable string[3] clist1 = ["az", "abed", "and"];
95 //writeln("--------");
96 assert(autocomplete("", clist1) == ["a", "az", "abed", "and"]);
97 assert(autocomplete("a", clist1) == ["a", "az", "abed", "and"]);
98 assert(autocomplete("aa", clist1) == []);
99 assert(autocomplete("aab", clist1) == []);