1 require("minibuffer.js");
4 function apply_completion_string(str, m) {
10 * Completions is either a visit function or an array.
12 define_keywords("$completions", "$get_string", "$get_description", "$get_value");
13 function all_word_completer()
16 var completions = arguments.$completions;
17 var get_string = arguments.$get_string;
18 var get_description = arguments.$get_description;
19 var get_value = arguments.$get_value;
21 if (typeof(completions) == "function")
24 completions(function (x) { arr.push(x); });
27 return function (input, pos, conservative) {
28 if (input.length == 0 && conservative)
30 var words = input.toLowerCase().split(" ");
31 var data = arr.filter(function (x) {
32 var s = get_string(x);
33 var d = get_description(x);
34 for (var i = 0; i < words.length; ++i)
36 if (s.toLowerCase().indexOf(words[i]) == -1 && d.toLowerCase().indexOf(words[i]) == -1)
41 return {count: data.length,
42 index_of: function (x) data.indexOf(x),
43 get_string: function (i) get_string(data[i]),
44 get_description : function (i) get_description(data[i]),
45 apply : function (i, m) apply_completion_string(get_string(data[i]), m),
46 get_value : function(i) (get_value ? get_value(data[i]) : data[i])
51 function get_common_prefix_length(a, b, len) {
53 if (len != null && len < a.length)
60 for (i = 0; i < lim && a[i] == b[i]; ++i);
64 function apply_partial_completion(x, prefix_end, suffix_begin, orig_str, m) {
65 if (suffix_begin < orig_str.length) {
66 if (orig_str[suffix_begin] == " ")
68 m._input_text = orig_str.substring(0, prefix_end) + x + " " + orig_str.substring(suffix_begin);
69 let sel = x.length + prefix_end + 1;
70 m._set_selection(sel, sel);
72 m._input_text = orig_str.substring(0, prefix_end) + x;
73 let sel = x.length + prefix_end;
74 m._set_selection(sel, sel);
78 function prefix_completer()
81 var completions = arguments.$completions;
82 var get_string = arguments.$get_string;
83 var get_description = arguments.$get_description;
84 var get_value = arguments.$get_value;
86 if (typeof(completions) == "function")
89 completions(function (x) { arr.push(x); });
91 arr = completions.slice();
92 arr.sort(function (a,b) {
101 return function (input, pos, conservative) {
102 var common_prefix = null;
103 if (pos == 0 && conservative)
105 var input_prefix = input.substring(0,pos);
106 var default_completion = null;
108 var data = arr.filter(function (x) {
109 var s = get_string(x);
113 default_completion = i;
116 retval = (s.length >= pos && s.substring(0,pos) == input_prefix);
123 let a = get_string(data[0]);
124 let b = get_string(data[data.length - 1]);
125 let i = get_common_prefix_length(a, b);
127 common_prefix = a.substring(0,i);
128 if (!default_completion) {
129 for (let j = 0; j < data.length; ++j) {
130 if (get_string(data[j]) == common_prefix) {
131 default_completion = j;
138 return {count:data.length,
139 index_of: function (x) data.indexOf(x),
140 get_string: function (i) get_string(data[i]),
141 get_description : function (i) get_description(data[i]),
142 apply : function (i, m) apply_partial_completion(get_string(data[i]), 0, pos, input, m),
143 get_value : function(i) get_value(data[i]),
144 apply_common_prefix: (common_prefix &&
145 function (m) apply_partial_completion(common_prefix, 0, pos, input, m)),
146 default_completion: default_completion
151 function javascript_completer(buffer) {
152 var window = buffer.window;
154 return function (input, pos, conservative) {
155 // Derived from Vimperator JavaScript completion
156 if (pos == 0 && conservative)
158 var str = input.substr(0, pos);
159 var matches = str.match(/^(.*?)(\s*\.\s*)?(\w*)$/);
160 var filter = matches[3] || "";
161 var start = matches[1].length - 1;
162 var offset = matches[1] ? matches[1].length : 0;
163 offset += matches[2] ? matches[2].length : 0;
167 let brackets = 0, parentheses = 0;
169 for (; start >= 0; start--)
171 switch (matches[1][start])
190 if (brackets > 0 || parentheses > 0)
198 var common_prefix_len = null;
199 var common_prefix = null;
201 function add_completion(str, desc) {
202 if (common_prefix != null)
203 common_prefix_len = get_common_prefix_length(common_prefix, str, common_prefix_len);
206 data.push([str,desc]);
208 if (matches[1].substr(start+1))
211 source_obj = eval(matches[1].substr(start+1));
216 source_obj = conkeror;
217 if ("window".substring(0,filter.length) == filter)
218 add_completion("window", "object");
219 if ("buffer".substring(0,filter.length) == filter)
220 add_completion("buffer", "object");
223 if (source_obj != null) {
225 for (let i in source_obj) {
226 if (i.substring(0,filter.length) != filter)
228 let type, description;
230 type = typeof(source_obj[i]);
231 } catch (e) { type = "unknown type"; }
232 if (type == "number" || type == "string" || type == "boolean") {
233 description = type + ": " + source_obj[i];
236 add_completion(i, description);
240 if (common_prefix != null && common_prefix_len > 0)
241 common_prefix = common_prefix.substr(0, common_prefix_len);
242 else if (common_prefix_len != null)
243 common_prefix = null;
244 return {count:data.length,
245 get_string: function (i) data[i][0],
246 get_description: function (i) data[i][1],
247 apply: function (i,m) apply_partial_completion(data[i][0], offset, pos, input, m),
248 apply_common_prefix: (common_prefix &&
249 function (m) apply_partial_completion(common_prefix, offset, pos, input, m))
255 function merge_completers(completers) {
256 if(completers.length == 0)
258 return function (input, pos, conservative) {
261 var results = completers.map(function(c) {
262 var r = c(input, pos, conservative);
269 function forward(name) {
271 var args = Array.prototype.slice.call(arguments);
272 var i = args.shift();
273 for(var j=0; j < results.length; j++) {
275 if(r == null) continue;
278 return r[name].apply(this, args);
285 return {count: count,
286 get_string: forward('get_string'),
287 get_description: forward('get_description'),
288 apply: forward('apply'),
289 destroy: forward('destroy')