1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 20:27:58 +01:00

move global completion functions into a vimperator.completion module

This commit is contained in:
Doug Kearns
2007-08-08 16:47:31 +00:00
parent 556bdbf05d
commit 54a5ee42f4
5 changed files with 432 additions and 425 deletions

View File

@@ -257,7 +257,7 @@ function Buffer() //{{{
if (!vimperator.bufferwindow.visible()) if (!vimperator.bufferwindow.visible())
return false; return false;
var items = get_buffer_completions(""); var items = vimperator.completion.get_buffer_completions("");
vimperator.bufferwindow.show(items); vimperator.bufferwindow.show(items);
vimperator.bufferwindow.selectItem(getBrowser().mTabContainer.selectedIndex); vimperator.bufferwindow.selectItem(getBrowser().mTabContainer.selectedIndex);
} }

View File

@@ -323,7 +323,7 @@ function Commands() //{{{
help: "Deletes <b>all</b> bookmarks which matches the url AND the specified tags. Use <code>&lt;Tab&gt;</code> key on a regular expression to complete the url which you want to delete.<br/>" + help: "Deletes <b>all</b> bookmarks which matches the url AND the specified tags. Use <code>&lt;Tab&gt;</code> key on a regular expression to complete the url which you want to delete.<br/>" +
"The following options WILL be interpreted in the future:<br/>" + "The following options WILL be interpreted in the future:<br/>" +
" -T comma,separated,tag,list <br/>", " -T comma,separated,tag,list <br/>",
completer: function(filter) { return get_bookmark_completions(filter); } completer: function(filter) { return vimperator.completion.get_bookmark_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["bookm[arks]", "bm"], addDefaultCommand(new Command(["bookm[arks]", "bm"],
@@ -335,7 +335,7 @@ function Commands() //{{{
"Close this window with <code class=\"command\">:pclose</code> or open entries with double click in the current tab or middle click in a new tab.<br/>" + "Close this window with <code class=\"command\">:pclose</code> or open entries with double click in the current tab or middle click in a new tab.<br/>" +
"The following options WILL be interpreted in the future:<br/>" + "The following options WILL be interpreted in the future:<br/>" +
" -T comma,separated,tag,list <br/>", " -T comma,separated,tag,list <br/>",
completer: function(filter) { return get_bookmark_completions(filter); } completer: function(filter) { return vimperator.completion.get_bookmark_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["b[uffer]"], addDefaultCommand(new Command(["b[uffer]"],
@@ -356,7 +356,7 @@ function Commands() //{{{
usage: ["b[uffer] {url|index}"], usage: ["b[uffer] {url|index}"],
short_help: "Go to buffer from buffer list", short_help: "Go to buffer from buffer list",
help: "Argument can be either the buffer index or the full URL.", help: "Argument can be either the buffer index or the full URL.",
completer: function(filter) { return get_buffer_completions(filter); } completer: function(filter) { return vimperator.completion.get_buffer_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["buffers", "files", "ls", "tabs"], addDefaultCommand(new Command(["buffers", "files", "ls", "tabs"],
@@ -367,7 +367,7 @@ function Commands() //{{{
vimperator.bufferwindow.hide(); vimperator.bufferwindow.hide();
else else
{ {
var items = get_buffer_completions(""); var items = vimperator.completion.get_buffer_completions("");
vimperator.bufferwindow.show(items); vimperator.bufferwindow.show(items);
vimperator.bufferwindow.selectItem(getBrowser().mTabContainer.selectedIndex); vimperator.bufferwindow.selectItem(getBrowser().mTabContainer.selectedIndex);
} }
@@ -501,7 +501,7 @@ function Commands() //{{{
"<li><code class=\"command\">:help o</code> for mappings (no pre- or postfix)</li>" + "<li><code class=\"command\">:help o</code> for mappings (no pre- or postfix)</li>" +
"</ul>" + "</ul>" +
"You can however use partial stings in the tab completion, so <code class=\"command\">:help he&lt;Tab&gt;</code> will complete <code class=\"command\">:help :help</code>.", "You can however use partial stings in the tab completion, so <code class=\"command\">:help he&lt;Tab&gt;</code> will complete <code class=\"command\">:help :help</code>.",
completer: function(filter) { return get_help_completions(filter); } completer: function(filter) { return vimperator.completion.get_help_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["hist[ory]", "hs"], addDefaultCommand(new Command(["hist[ory]", "hs"],
@@ -511,7 +511,7 @@ function Commands() //{{{
short_help: "Show recently visited URLs", short_help: "Show recently visited URLs",
help: "Open the preview window at the bottom of the screen for all history items which match the filter string either in the title or URL. " + help: "Open the preview window at the bottom of the screen for all history items which match the filter string either in the title or URL. " +
"Close this window with <code class=\"command\">:pclose</code> or open entries with double click in the current tab or middle click in a new tab.", "Close this window with <code class=\"command\">:pclose</code> or open entries with double click in the current tab or middle click in a new tab.",
completer: function(filter) { return get_history_completions(filter); } completer: function(filter) { return vimperator.completion.get_history_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["javas[cript]", "js"], addDefaultCommand(new Command(["javas[cript]", "js"],
@@ -754,7 +754,7 @@ function Commands() //{{{
"The items which are completed on <code>&lt;Tab&gt;</code> are specified in the <code class=\"option\">'complete'</code> option.<br/>" + "The items which are completed on <code>&lt;Tab&gt;</code> are specified in the <code class=\"option\">'complete'</code> option.<br/>" +
"Without argument, reloads the current page.<br/>" + "Without argument, reloads the current page.<br/>" +
"Without argument but with <code class=\"command\">!</code>, reloads the current page skipping the cache.", "Without argument but with <code class=\"command\">!</code>, reloads the current page skipping the cache.",
completer: function(filter) { return get_url_completions(filter); } completer: function(filter) { return vimperator.completion.get_url_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["pc[lose]"], addDefaultCommand(new Command(["pc[lose]"],
@@ -937,7 +937,7 @@ function Commands() //{{{
"<code class=\"command\">:set option?</code> or <code class=\"command\">:set option</code> shows the current value of the option.<br/>" + "<code class=\"command\">:set option?</code> or <code class=\"command\">:set option</code> shows the current value of the option.<br/>" +
"<code class=\"command\">:set option&amp;</code> resets 'option' to the default value.<br/>" + "<code class=\"command\">:set option&amp;</code> resets 'option' to the default value.<br/>" +
"<code class=\"command\">:set option+=foo</code> and <code class=\"command\">:set option-=foo</code> WILL add/remove foo from list options.<br/>", "<code class=\"command\">:set option+=foo</code> and <code class=\"command\">:set option-=foo</code> WILL add/remove foo from list options.<br/>",
completer: function(filter) { return get_options_completions(filter); } completer: function(filter) { return vimperator.completion.get_options_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["so[urce]"], addDefaultCommand(new Command(["so[urce]"],
@@ -954,7 +954,7 @@ function Commands() //{{{
"The .vimperatorrc file in your home directory and any files in ~/.vimperator/plugin/ are always sourced at startup.<br/>" + "The .vimperatorrc file in your home directory and any files in ~/.vimperator/plugin/ are always sourced at startup.<br/>" +
"~ is supported as a shortcut for the $HOME directory.<br/>" + "~ is supported as a shortcut for the $HOME directory.<br/>" +
"If <code class=\"command\">!</code> is specified, errors are not printed.", "If <code class=\"command\">!</code> is specified, errors are not printed.",
completer: function(filter) { return get_file_completions(filter); } completer: function(filter) { return vimperator.completion.get_file_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["st[op]"], addDefaultCommand(new Command(["st[op]"],
@@ -971,7 +971,7 @@ function Commands() //{{{
short_help: "Execute {cmd} and tell it to output in a new tab", short_help: "Execute {cmd} and tell it to output in a new tab",
help: "Works for only commands that support it.<br/>" + help: "Works for only commands that support it.<br/>" +
"Example: <code class=\"command\">:tab help tab</code> opens the help in a new tab.", "Example: <code class=\"command\">:tab help tab</code> opens the help in a new tab.",
completer: function(filter) { return get_command_completions(filter); } completer: function(filter) { return vimperator.completion.get_command_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["tabl[ast]"], addDefaultCommand(new Command(["tabl[ast]"],
@@ -1019,7 +1019,7 @@ function Commands() //{{{
short_help: "Open one or more URLs in a new tab", short_help: "Open one or more URLs in a new tab",
help: "Like <code class=\"command\">:open</code> but open URLs in a new tab.<br/>" + help: "Like <code class=\"command\">:open</code> but open URLs in a new tab.<br/>" +
"If used with <code class=\"command\">!</code>, the 'tabopen' value of the <code class=\"option\">'activate'</code> option is negated.", "If used with <code class=\"command\">!</code>, the 'tabopen' value of the <code class=\"option\">'activate'</code> option is negated.",
completer: function(filter) { return get_url_completions(filter); } completer: function(filter) { return vimperator.completion.get_url_completions(filter); }
} }
)); ));
addDefaultCommand(new Command(["tabp[revious]", "tp[revious]", "tabN[ext]", "tN[ext]"], addDefaultCommand(new Command(["tabp[revious]", "tp[revious]", "tabN[ext]", "tN[ext]"],

View File

@@ -26,456 +26,463 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
// The completion substrings, used for showing the longest common match vimperator.completion = (function() // {{{
var g_substrings = [];
/*
* returns the longest common substring
* used for the 'longest' setting for wildmode
*
*/
function get_longest_substring() //{{{
{ {
if (g_substrings.length == 0) // The completion substrings, used for showing the longest common match
return ''; var g_substrings = [];
var longest = g_substrings[0];
for (var i = 1; i < g_substrings.length; i++)
{
if (g_substrings[i].length > longest.length)
longest = g_substrings[i];
}
//alert(longest);
return longest;
} //}}}
// function uses smartcase // function uses smartcase
// list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ] // list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ]
function build_longest_common_substring(list, filter) //{{{ function build_longest_common_substring(list, filter) //{{{
{
var filtered = [];
//var filter_length = filter.length;
//filter = filter.toLowerCase();
var ignorecase = false;
if(filter == filter.toLowerCase())
ignorecase = true;
for (var i = 0; i < list.length; i++)
{ {
for (var j = 0; j < list[i][0].length; j++) var filtered = [];
//var filter_length = filter.length;
//filter = filter.toLowerCase();
var ignorecase = false;
if(filter == filter.toLowerCase())
ignorecase = true;
for (var i = 0; i < list.length; i++)
{ {
var item = list[i][0][j]; for (var j = 0; j < list[i][0].length; j++)
if(ignorecase)
item = item.toLowerCase();
if (item.indexOf(filter) == -1)
continue;
if (g_substrings.length == 0)
{ {
//alert('if: ' + item); var item = list[i][0][j];
var last_index = item.lastIndexOf(filter); if(ignorecase)
var length = item.length; item = item.toLowerCase();
for (var k = item.indexOf(filter); k != -1 && k <= last_index; k = item.indexOf(filter, k + 1))
if (item.indexOf(filter) == -1)
continue;
if (g_substrings.length == 0)
{ {
for (var l = k + filter.length; l <= length; l++) //alert('if: ' + item);
g_substrings.push(list[i][0][j].substring(k, l)); var last_index = item.lastIndexOf(filter);
var length = item.length;
for (var k = item.indexOf(filter); k != -1 && k <= last_index; k = item.indexOf(filter, k + 1))
{
for (var l = k + filter.length; l <= length; l++)
g_substrings.push(list[i][0][j].substring(k, l));
}
}
else
{
//alert('else: ' + item);
g_substrings = g_substrings.filter(function($_) {
return list[i][0][j].indexOf($_) >= 0;
});
}
filtered.push([list[i][0][j], list[i][1]]);
break;
}
}
return filtered;
} //}}}
/* this function is case sensitive */
function build_longest_starting_substring(list, filter) //{{{
{
var filtered = [];
//var filter_length = filter.length;
for (var i = 0; i < list.length; i++)
{
for (var j = 0; j < list[i][0].length; j++)
{
if (list[i][0][j].indexOf(filter) != 0)
continue;
if (g_substrings.length == 0)
{
var length = list[i][0][j].length;
for (var k = filter.length; k <= length; k++)
g_substrings.push(list[i][0][j].substring(0, k));
}
else
{
g_substrings = g_substrings.filter(function($_) {
return list[i][0][j].indexOf($_) == 0;
});
}
filtered.push([list[i][0][j], list[i][1]]);
break;
}
}
return filtered;
} //}}}
/* discard all entries in the 'urls' array, which don't match 'filter */
function filter_url_array(urls, filter) //{{{
{
var filtered = [];
// completions which don't match the url but just the description
// list them add the end of the array
var additional_completions = [];
if (!filter) return urls.map(function($_) {
return [$_[0], $_[1]]
});
//var filter_length = filter.length;
var ignorecase = false;
if(filter == filter.toLowerCase())
ignorecase = true;
/*
* Longest Common Subsequence
* This shouldn't use build_longest_common_substring
* for performance reasons, so as not to cycle through the urls twice
*/
for (var i = 0; i < urls.length; i++)
{
var url = urls[i][0] || "";
var title = urls[i][1] || "";
if(ignorecase)
{
url = url.toLowerCase();
title = title.toLowerCase();
}
if (url.indexOf(filter) == -1)
{
if (title.indexOf(filter) != -1)
additional_completions.push([ urls[i][0], urls[i][1] ]);
continue;
}
if (g_substrings.length == 0) // Build the substrings
{
var last_index = url.lastIndexOf(filter);
var url_length = url.length;
for (var k = url.indexOf(filter); k != -1 && k <= last_index; k = url.indexOf(filter, k + 1))
{
for (var l = k + filter.length; l <= url_length; l++)
g_substrings.push(url.substring(k, l));
} }
} }
else else
{ {
//alert('else: ' + item);
g_substrings = g_substrings.filter(function($_) { g_substrings = g_substrings.filter(function($_) {
return list[i][0][j].indexOf($_) >= 0; return url.indexOf($_) >= 0;
}); });
} }
filtered.push([list[i][0][j], list[i][1]]); filtered.push([urls[i][0], urls[i][1]]);
break;
} }
}
return filtered;
} //}}}
/* this function is case sensitive */ return filtered.concat(additional_completions);
function build_longest_starting_substring(list, filter) //{{{ } //}}}
{
var filtered = []; return {
//var filter_length = filter.length;
for (var i = 0; i < list.length; i++) /*
{ * returns the longest common substring
for (var j = 0; j < list[i][0].length; j++) * used for the 'longest' setting for wildmode
*
*/
get_longest_substring: function() //{{{
{ {
if (list[i][0][j].indexOf(filter) != 0)
continue;
if (g_substrings.length == 0) if (g_substrings.length == 0)
return '';
var longest = g_substrings[0];
for (var i = 1; i < g_substrings.length; i++)
{ {
var length = list[i][0][j].length; if (g_substrings[i].length > longest.length)
for (var k = filter.length; k <= length; k++) longest = g_substrings[i];
g_substrings.push(list[i][0][j].substring(0, k));
} }
else //alert(longest);
return longest;
}, //}}}
/*
* filter a list of urls
*
* may consist of searchengines, filenames, bookmarks and history,
* depending on the 'complete' option
* if the 'complete' argument is passed like "h", it temporarily overrides the complete option
*/
get_url_completions: function(filter, complete) //{{{
{
var completions = new Array();
g_substrings = [];
var cpt = complete || vimperator.options["complete"];
// join all completion arrays together
for (var i = 0; i < cpt.length; i++)
{ {
g_substrings = g_substrings.filter(function($_) { if (cpt[i] == 's')
return list[i][0][j].indexOf($_) == 0; completions = completions.concat(this.get_search_completions(filter));
}); else if (cpt[i] == 'b')
completions = completions.concat(this.get_bookmark_completions(filter));
else if (cpt[i] == 'h')
completions = completions.concat(this.get_history_completions(filter));
else if (cpt[i] == 'f')
completions = completions.concat(this.get_file_completions(filter, true));
} }
filtered.push([list[i][0][j], list[i][1]]);
break;
}
}
return filtered;
} //}}}
/* return completions;
* filter a list of urls }, //}}}
*
* may consist of searchengines, filenames, bookmarks and history,
* depending on the 'complete' option
* if the 'complete' argument is passed like "h", it tempoarily overrides the complete option
*/
function get_url_completions(filter, complete) //{{{
{
var completions = new Array();
g_substrings = [];
var cpt = complete || vimperator.options["complete"]; get_search_completions: function(filter) //{{{
// join all completion arrays together
for (var i = 0; i < cpt.length; i++)
{
if (cpt[i] == 's')
completions = completions.concat(get_search_completions(filter));
else if (cpt[i] == 'b')
completions = completions.concat(get_bookmark_completions(filter));
else if (cpt[i] == 'h')
completions = completions.concat(get_history_completions(filter));
else if (cpt[i] == 'f')
completions = completions.concat(get_file_completions(filter, true));
}
return completions;
} //}}}
/* discard all entries in the 'urls' array, which don't match 'filter */
function filter_url_array(urls, filter) //{{{
{
var filtered = [];
// completions which don't match the url but just the description
// list them add the end of the array
var additional_completions = [];
if (!filter) return urls.map(function($_) {
return [$_[0], $_[1]]
});
//var filter_length = filter.length;
var ignorecase = false;
if(filter == filter.toLowerCase())
ignorecase = true;
/*
* Longest Common Subsequence
* This shouldn't use build_longest_common_substring
* for performance reasons, so as not to cycle through the urls twice
*/
for (var i = 0; i < urls.length; i++)
{
var url = urls[i][0] || "";
var title = urls[i][1] || "";
if(ignorecase)
{ {
url = url.toLowerCase(); var engines = vimperator.bookmarks.getSearchEngines().concat(vimperator.bookmarks.getKeywords());
title = title.toLowerCase();
}
if (url.indexOf(filter) == -1) if (!filter) return engines.map(function($_) {
{ return [$_[0], $_[1]];
if (title.indexOf(filter) != -1)
additional_completions.push([ urls[i][0], urls[i][1] ]);
continue;
}
if (g_substrings.length == 0) // Build the substrings
{
var last_index = url.lastIndexOf(filter);
var url_length = url.length;
for (var k = url.indexOf(filter); k != -1 && k <= last_index; k = url.indexOf(filter, k + 1))
{
for (var l = k + filter.length; l <= url_length; l++)
g_substrings.push(url.substring(k, l));
}
}
else
{
g_substrings = g_substrings.filter(function($_) {
return url.indexOf($_) >= 0;
}); });
} var mapped = engines.map(function($_) {
filtered.push([urls[i][0], urls[i][1]]); return [[$_[0]], $_[1]];
} });
return build_longest_common_substring(mapped, filter);
}, //}}}
return filtered.concat(additional_completions); get_history_completions: function(filter) //{{{
} //}}}
function get_search_completions(filter) //{{{
{
var engines = vimperator.bookmarks.getSearchEngines().concat(vimperator.bookmarks.getKeywords());
if (!filter) return engines.map(function($_) {
return [$_[0], $_[1]];
});
var mapped = engines.map(function($_) {
return [[$_[0]], $_[1]];
});
return build_longest_common_substring(mapped, filter);
} //}}}
function get_history_completions(filter) //{{{
{
var items = vimperator.history.get();
return filter_url_array(items, filter);
} //}}}
function get_bookmark_completions(filter) //{{{
{
var bookmarks = vimperator.bookmarks.get();
return filter_url_array(bookmarks, filter);
} //}}}
function get_file_completions(filter) //{{{
{
//var completions = new Array();
/* This is now also used as part of the url completion, so the substrings shouldn't be cleared for that case */
if (!arguments[1])
g_substrings = [];
var match = filter.match(/^(.*[\/\\])(.*?)$/);
var dir;
if (!match || !(dir = match[1]))
return [];
var compl = match[2] || '';
try {
var fd = vimperator.fopen(dir, "<");
} catch(e) {
// thrown if file does not exist
return [ ];
}
if (!fd)
return [];
var entries = fd.read();
var delim = fd.path.length == 1 ? '' : (fd.path.search(/\\/) != -1) ? "\\" : "/";
var new_filter = fd.path + delim + compl;
if (!filter) return entries.map(function($_) {
var path = $_.path;
if ($_.isDirectory()) path += '/';
return [path, ''];
});
var mapped = entries.map(function($_) {
var path = $_.path;
if ($_.isDirectory()) path += '/';
return [[path], ''];
});
return build_longest_starting_substring(mapped, new_filter);
} //}}}
function get_help_completions(filter) //{{{
{
var help_array = [[["introduction"], "Introductory text"],
[["mappings"], "Normal mode commands"],
[["commands"], "Ex commands"],
[["options"], "Configuration options"]]; // TODO: hardcoded until we have proper 'pages'
g_substrings = [];
for (var command in vimperator.commands)
{
help_array.push([command.long_names.map(function($_) {
return ":" + $_;
}),
command.short_help])
}
options = get_options_completions(filter, true);
help_array = help_array.concat(options.map(function($_) {
return [
$_[0].map(function($_) { return "'" + $_ + "'"; }),
$_[1]
];
}));
for (var map in vimperator.mappings)
help_array.push([map.names, map.short_help])
if (!filter) return help_array.map(function($_) {
return [$_[0][0], $_[1]]; // unfiltered, use the first command
});
return build_longest_common_substring(help_array, filter);
} //}}}
function get_command_completions(filter) //{{{
{
//g_completions = [];
g_substrings = [];
var completions = []
if (!filter)
{
for (var command in vimperator.commands)
completions.push([command.name, command.short_help]);
return completions;
}
for (var command in vimperator.commands)
completions.push([command.long_names, command.short_help]);
return build_longest_starting_substring(completions, filter);
} //}}}
function get_options_completions(filter, unfiltered) //{{{
{
g_substrings = [];
var options_completions = [];
var no_mode = false;
if (filter.indexOf("no") == 0) // boolean option
{
no_mode = true;
filter = filter.substr(2);
}
if (unfiltered)
{
var options = [];
for (var option in vimperator.options)
{ {
if (no_mode && option.type != "boolean") var items = vimperator.history.get();
continue; return filter_url_array(items, filter);
options.push([option.names, option.short_help]) }, //}}}
}
return options;
}
if (!filter) get_bookmark_completions: function(filter) //{{{
{
var options = [];
for (var option in vimperator.options)
{ {
if (no_mode && option.type != "boolean") var bookmarks = vimperator.bookmarks.get();
continue; return filter_url_array(bookmarks, filter);
var prefix = no_mode ? 'no' : ''; }, //}}}
options.push([prefix + option.name, option.short_help])
}
return options;
}
// check if filter ends with =, then complete current value get_file_completions: function(filter) //{{{
else if(filter.length > 0 && filter.lastIndexOf("=") == filter.length -1)
{
filter = filter.substr(0, filter.length-1);
for (var option in vimperator.options)
{ {
if (option.hasName(filter)) //var completions = new Array();
{ /* This is now also used as part of the url completion, so the substrings shouldn't be cleared for that case */
options_completions.push([filter + "=" + option.value, ""]); if (!arguments[1])
return options_completions; g_substrings = [];
var match = filter.match(/^(.*[\/\\])(.*?)$/);
var dir;
if (!match || !(dir = match[1]))
return [];
var compl = match[2] || '';
try {
var fd = vimperator.fopen(dir, "<");
} catch(e) {
// thrown if file does not exist
return [ ];
} }
}
return options_completions;
}
// can't use b_l_s_s, since this has special requirements (the prefix) if (!fd)
var filter_length = filter.length; return [];
for (var option in vimperator.options)
{ var entries = fd.read();
if (no_mode && option.type != "boolean") var delim = fd.path.length == 1 ? '' : (fd.path.search(/\\/) != -1) ? "\\" : "/";
continue; var new_filter = fd.path + delim + compl;
var prefix = no_mode ? 'no' : ''; if (!filter) return entries.map(function($_) {
for (var j = 0; j < option.names.length; j++) var path = $_.path;
if ($_.isDirectory()) path += '/';
return [path, ''];
});
var mapped = entries.map(function($_) {
var path = $_.path;
if ($_.isDirectory()) path += '/';
return [[path], ''];
});
return build_longest_starting_substring(mapped, new_filter);
}, //}}}
get_help_completions: function(filter) //{{{
{ {
if (option.names[j].indexOf(filter) != 0) var help_array = [[["introduction"], "Introductory text"],
continue; [["mappings"], "Normal mode commands"],
if (g_substrings.length == 0) [["commands"], "Ex commands"],
[["options"], "Configuration options"]]; // TODO: hardcoded until we have proper 'pages'
g_substrings = [];
for (var command in vimperator.commands)
{ {
var length = option.names[j].length; help_array.push([command.long_names.map(function($_) {
for (var k = filter_length; k <= length; k++) return ":" + $_;
g_substrings.push(prefix + option.names[j].substring(0, k)); }),
command.short_help])
} }
else options = this.get_options_completions(filter, true);
help_array = help_array.concat(options.map(function($_) {
return [
$_[0].map(function($_) { return "'" + $_ + "'"; }),
$_[1]
];
}));
for (var map in vimperator.mappings)
help_array.push([map.names, map.short_help])
if (!filter) return help_array.map(function($_) {
return [$_[0][0], $_[1]]; // unfiltered, use the first command
});
return build_longest_common_substring(help_array, filter);
}, //}}}
get_command_completions: function(filter) //{{{
{
//g_completions = [];
g_substrings = [];
var completions = []
if (!filter)
{ {
g_substrings = g_substrings.filter(function($_) { for (var command in vimperator.commands)
return option.names[j].indexOf($_) == 0; completions.push([command.name, command.short_help]);
}); return completions;
} }
options_completions.push([prefix + option.names[j], option.short_help]);
break; for (var command in vimperator.commands)
} completions.push([command.long_names, command.short_help]);
return build_longest_starting_substring(completions, filter);
}, //}}}
get_options_completions: function(filter, unfiltered) //{{{
{
g_substrings = [];
var options_completions = [];
var no_mode = false;
if (filter.indexOf("no") == 0) // boolean option
{
no_mode = true;
filter = filter.substr(2);
}
if (unfiltered)
{
var options = [];
for (var option in vimperator.options)
{
if (no_mode && option.type != "boolean")
continue;
options.push([option.names, option.short_help])
}
return options;
}
if (!filter)
{
var options = [];
for (var option in vimperator.options)
{
if (no_mode && option.type != "boolean")
continue;
var prefix = no_mode ? 'no' : '';
options.push([prefix + option.name, option.short_help])
}
return options;
}
// check if filter ends with =, then complete current value
else if(filter.length > 0 && filter.lastIndexOf("=") == filter.length -1)
{
filter = filter.substr(0, filter.length-1);
for (var option in vimperator.options)
{
if (option.hasName(filter))
{
options_completions.push([filter + "=" + option.value, ""]);
return options_completions;
}
}
return options_completions;
}
// can't use b_l_s_s, since this has special requirements (the prefix)
var filter_length = filter.length;
for (var option in vimperator.options)
{
if (no_mode && option.type != "boolean")
continue;
var prefix = no_mode ? 'no' : '';
for (var j = 0; j < option.names.length; j++)
{
if (option.names[j].indexOf(filter) != 0)
continue;
if (g_substrings.length == 0)
{
var length = option.names[j].length;
for (var k = filter_length; k <= length; k++)
g_substrings.push(prefix + option.names[j].substring(0, k));
}
else
{
g_substrings = g_substrings.filter(function($_) {
return option.names[j].indexOf($_) == 0;
});
}
options_completions.push([prefix + option.names[j], option.short_help]);
break;
}
}
return options_completions;
}, //}}}
get_buffer_completions: function(filter) //{{{
{
g_substrings = [];
var items = [];
var num = getBrowser().browsers.length;
var title, url;
for (var i = 0; i < num; i++)
{
try
{
title = getBrowser().getBrowserAtIndex(i).contentDocument.getElementsByTagName('title')[0].text;
}
catch (e)
{
title = "";
}
url = getBrowser().getBrowserAtIndex(i).contentDocument.location.href;
if (title.indexOf(filter) == -1 && url.indexOf(filter) == -1)
continue;
if (title.indexOf(filter) != -1 || url.indexOf(filter) != -1)
{
if (title == "")
title = "(Untitled)";
items.push([[(i + 1) + ": " + title, (i + 1) + ": " + url], url]);
}
}
if (!filter) return items.map(function($_) {
return [$_[0][0], $_[1]];
});
return build_longest_common_substring(items, filter);
}, //}}}
exTabCompletion: function(str) //{{{
{
var [count, cmd, special, args] = vimperator.commands.parseCommand(str);
var completions = new Array;
var start = 0;
// if there is no space between the command name and the cursor
// then get completions of the command name
var matches = str.match(/^(:*\d*)\w*$/);
if(matches)
{
completions = this.get_command_completions(cmd);
start = matches[1].length;
}
else // dynamically get completions as specified with the command's completer function
{
var command = vimperator.commands.get(cmd);
if (command && command.completer)
{
completions = command.completer.call(this, args);
// if (command[0][0] == "open" ||
// command[0][0] == "tabopen" ||
// command[0][0] == "winopen")
// start = str.search(/^:*\d*\w+(\s+|.*\|)/); // up to the last | or the first space
// else
matches = str.match(/^:*\d*\w+\s+/); // up to the first spaces only
start = matches[0].length;
}
}
return [start, completions];
} //}}}
} }
})(); // }}}
return options_completions;
} //}}}
function get_buffer_completions(filter) //{{{
{
g_substrings = [];
var items = [];
var num = getBrowser().browsers.length;
var title, url;
for (var i = 0; i < num; i++)
{
try
{
title = getBrowser().getBrowserAtIndex(i).contentDocument.getElementsByTagName('title')[0].text;
}
catch (e)
{
title = "";
}
url = getBrowser().getBrowserAtIndex(i).contentDocument.location.href;
if (title.indexOf(filter) == -1 && url.indexOf(filter) == -1)
continue;
if (title.indexOf(filter) != -1 || url.indexOf(filter) != -1)
{
if (title == "")
title = "(Untitled)";
items.push([[(i + 1) + ": " + title, (i + 1) + ": " + url], url]);
}
}
if (!filter) return items.map(function($_) {
return [$_[0][0], $_[1]];
});
return build_longest_common_substring(items, filter);
} //}}}
function exTabCompletion(str) //{{{
{
var [count, cmd, special, args] = vimperator.commands.parseCommand(str);
var completions = new Array;
var start = 0;
// if there is no space between the command name and the cursor
// then get completions of the command name
var matches = str.match(/^(:*\d*)\w*$/);
if(matches)
{
completions = get_command_completions(cmd);
start = matches[1].length;
}
else // dynamically get completions as specified with the command's completer function
{
var command = vimperator.commands.get(cmd);
if (command && command.completer)
{
completions = command.completer.call(this, args);
// if (command[0][0] == "open" ||
// command[0][0] == "tabopen" ||
// command[0][0] == "winopen")
// start = str.search(/^:*\d*\w+(\s+|.*\|)/); // up to the last | or the first space
// else
matches = str.match(/^:*\d*\w+\s+/); // up to the first spaces only
start = matches[0].length;
}
}
return [start, completions];
} //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -491,7 +491,7 @@ function CommandLine() //{{{
else else
{ {
if (longest && completions.length > 1) if (longest && completions.length > 1)
var compl = get_longest_substring(); var compl = vimperator.completion.get_longest_substring();
else if (full) else if (full)
var compl = completions[completion_index][0]; var compl = completions[completion_index][0];
else if (completions.length == 1) else if (completions.length == 1)

View File

@@ -532,7 +532,7 @@ const vimperator = (function() //{{{
// TODO: move elsewhere // TODO: move elsewhere
vimperator.registerCallback("submit", vimperator.modes.EX, function(command) { vimperator.execute(command); } ); vimperator.registerCallback("submit", vimperator.modes.EX, function(command) { vimperator.execute(command); } );
vimperator.registerCallback("complete", vimperator.modes.EX, function(str) { return exTabCompletion(str); } ); vimperator.registerCallback("complete", vimperator.modes.EX, function(str) { return vimperator.completion.exTabCompletion(str); } );
// first time intro message // first time intro message
if (Options.getPref("firsttime", true)) if (Options.getPref("firsttime", true))