1 require("minibuffer.js");
4 * Completions is either a visit function or an array.
6 define_keywords("$completions", "$get_string", "$get_description", "$get_value");
7 function all_word_completer()
10 var completions = arguments.$completions;
11 var get_string = arguments.$get_string ? arguments.$get_string : function (x) x;
12 var get_description = arguments.$get_description;
13 var get_value = arguments.$get_value;
15 if (typeof(completions) == "function")
18 completions(function (x) { arr.push(x); });
21 return function (input, pos, conservative) {
22 if (input.length == 0 && conservative)
24 var words = input.toLowerCase().split(" ");
25 var data = arr.filter(function (x) {
26 var s = get_string(x);
27 var d = get_description(x);
28 for (var i = 0; i < words.length; ++i)
30 if (s.toLowerCase().indexOf(words[i]) == -1 && d.toLowerCase().indexOf(words[i]) == -1)
35 return {count: data.length,
36 index_of: function (x) data.indexOf(x),
37 get_string: function (i) get_string(data[i]),
38 get_description : function (i) get_description(data[i]),
39 get_input_state: function (i) [get_string(data[i])],
40 get_value : function(i) (get_value ? get_value(data[i]) : data[i])
45 function get_common_prefix_length(a, b, len) {
47 if (len != null && len < a.length)
54 for (i = 0; i < lim && a[i] == b[i]; ++i);
58 function get_partial_completion_input_state(x, prefix_end, suffix_begin, orig_str) {
59 if (suffix_begin < orig_str.length) {
60 if (orig_str[suffix_begin] == " ")
62 let sel = x.length + prefix_end + 1;
63 return [orig_str.substring(0, prefix_end) + x + " " + orig_str.substring(suffix_begin),
66 let sel = x.length + prefix_end;
67 return [orig_str.substring(0, prefix_end) + x, sel, sel];
71 function prefix_completer()
74 var completions = arguments.$completions;
75 var get_string = arguments.$get_string ? arguments.$get_string : function (x) x;
76 var get_description = arguments.$get_description;
77 var get_value = arguments.$get_value;
79 if (typeof(completions) == "function")
82 completions(function (x) { arr.push(x); });
84 arr = completions.slice();
85 arr.sort(function (a,b) {
94 return function (input, pos, conservative) {
95 var common_prefix = null;
96 if (pos == 0 && conservative)
98 var input_prefix = input.substring(0,pos);
99 var default_completion = null;
101 var data = arr.filter(function (x) {
102 var s = get_string(x);
106 default_completion = i;
109 retval = (s.length >= pos && s.substring(0,pos) == input_prefix);
116 let a = get_string(data[0]);
117 let b = get_string(data[data.length - 1]);
118 let i = get_common_prefix_length(a, b);
120 common_prefix = a.substring(0,i);
121 if (!default_completion) {
122 for (let j = 0; j < data.length; ++j) {
123 if (get_string(data[j]) == common_prefix) {
124 default_completion = j;
131 return {count:data.length,
132 index_of: function (x) data.indexOf(x),
133 get_string: function (i) get_string(data[i]),
134 get_description : function (i) get_description(data[i]),
135 get_input_state : function (i) get_partial_completion_input_state(get_string(data[i]), 0, pos, input),
136 get_value : function(i) get_value(data[i]),
137 get common_prefix_input_state () {
138 return common_prefix && get_partial_completion_input_state(common_prefix, 0, pos, input);
140 default_completion: default_completion
145 function javascript_completer(buffer) {
146 var window = buffer.window;
148 return function (input, pos, conservative) {
149 // Derived from Vimperator JavaScript completion
150 if (pos == 0 && conservative)
152 var str = input.substr(0, pos);
153 var matches = str.match(/^(.*?)(\s*\.\s*)?(\w*)$/);
154 var filter = matches[3] || "";
155 var start = matches[1].length - 1;
156 var offset = matches[1] ? matches[1].length : 0;
157 offset += matches[2] ? matches[2].length : 0;
161 let brackets = 0, parentheses = 0;
163 for (; start >= 0; start--)
165 switch (matches[1][start])
184 if (brackets > 0 || parentheses > 0)
192 var common_prefix_len = null;
193 var common_prefix = null;
195 function add_completion(str, desc) {
196 if (common_prefix != null)
197 common_prefix_len = get_common_prefix_length(common_prefix, str, common_prefix_len);
200 data.push([str,desc]);
202 if (matches[1].substr(start+1))
205 source_obj = eval(matches[1].substr(start+1));
210 source_obj = conkeror;
211 if ("window".substring(0,filter.length) == filter)
212 add_completion("window", "object");
213 if ("buffer".substring(0,filter.length) == filter)
214 add_completion("buffer", "object");
217 if (source_obj != null) {
219 for (let i in source_obj) {
220 if (i.substring(0,filter.length) != filter)
222 let type, description;
224 type = typeof(source_obj[i]);
225 } catch (e) { type = "unknown type"; }
226 if (type == "number" || type == "string" || type == "boolean") {
227 description = type + ": " + source_obj[i];
230 add_completion(i, description);
234 if (common_prefix != null && common_prefix_len > 0)
235 common_prefix = common_prefix.substr(0, common_prefix_len);
236 else if (common_prefix_len != null)
237 common_prefix = null;
238 return {count:data.length,
239 get_string: function (i) data[i][0],
240 get_description: function (i) data[i][1],
241 get_input_state: function (i) get_partial_completion_input_state(data[i][0], offset, pos, input),
242 get common_prefix_input_state () {
243 return common_prefix && get_partial_completion_input_state(common_prefix, offset, pos, input);
250 function merge_completers(completers) {
251 if(completers.length == 0)
253 return function (input, pos, conservative) {
256 for (let i = 0; i < completers.length; ++i) {
257 let r = yield completers[i](input, pos, conservative);
258 if (r != null && r.count > 0) {
263 function forward(name) {
265 var args = Array.prototype.slice.call(arguments);
266 var i = args.shift();
267 for(var j=0; j < results.length; j++) {
271 return r[name].apply(this, args);
278 yield co_return({count: count,
279 get_string: forward('get_string'),
280 get_description: forward('get_description'),
281 get_input_state: forward('get_input_state'),
282 destroy: forward('destroy')
287 function nest_completions(completions, prefix, suffix) {
298 return [prefix + s + suffix, a + prefix.length, b + prefix.length];
301 __proto__: completions,
302 get_input_state: function (i) nest(completions.get_input_state(i)),
303 get common_prefix_input_state () {
304 let x = completions.common_prefix_input_state;