1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 13:02:27 +01:00

Highlight substrings matching the filter in completions. Fix javascript completion and :hi. Run dump() arguments through objectToString and append "\n"

This commit is contained in:
Kris Maglione
2008-10-07 20:33:44 +00:00
parent 01e89bc6d8
commit 08ac946225
7 changed files with 109 additions and 38 deletions

View File

@@ -34,11 +34,11 @@ liberator.Buffer = function () //{{{
////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
const highlightClasses = ["Boolean", "ErrorMsg", "Function", "InfoMsg", "Keyword",
const highlightClasses = ["Boolean", "ErrorMsg", "Filter", "Function", "InfoMsg", "Keyword",
"LineNr", "ModeMsg", "MoreMsg", "Normal", "Null", "Number", "Question",
"StatusLine", "StatusLineBroken", "StatusLineSecure", "String", "Tag",
"Title", "URL", "WarningMsg",
["Hint", ".liberator-hint", "*"]
["Hint", ".liberator-hint", "*"],
["Search", ".__liberator-search", "*"],
["Bell", "#liberator-visualbell"],
];
@@ -806,7 +806,10 @@ liberator.Buffer = function () //{{{
},
{
// TODO: add this as a standard highlight completion function?
completer: function (filter) [0, liberator.completion.filter([[v, ""] for ([k, v] in Iterator(highlightClasses))], filter)],
// I agree. It could (should) be much more sophisticated. --Kris
completer: function (filter) [0,
liberator.completion.filter([[v instanceof Array ? v[0] : v, ""] for ([k, v] in Iterator(highlightClasses))], filter)
],
hereDoc: true,
bang: true,
});

View File

@@ -62,6 +62,8 @@ liberator.Completion = function () //{{{
function Javascript()
{
let json = Components.classes["@mozilla.org/dom/json;1"]
.createInstance(Components.interfaces.nsIJSON);
const OFFSET = 0, CHAR = 1, STATEMENTS = 2, DOTS = 3, FULL_STATEMENTS = 4, FUNCTIONS = 5;
let stack = [];
let top = []; /* The element on the top of the stack. */
@@ -93,6 +95,13 @@ liberator.Completion = function () //{{{
})();
try
{
// The point of 'for k in obj' is to get keys
// that are accessible via . or [] notation.
// Iterators quite often return values of no
// use whatsoever for this purpose, so, we try
// this rather dirty hack of getting a standard
// object iterator for any object that defines its
// own.
if ("__iterator__" in obj)
{
let oldIter = obj.__iterator__;
@@ -167,7 +176,7 @@ liberator.Completion = function () //{{{
{
try
{
// liberator.dump("eval(" + liberator.util.escapeString(arg) + ")");
// liberator.dump("eval(" + liberator.util.escapeString(arg) + ")\n");
return window.eval(arg);
}
catch (e)
@@ -194,9 +203,7 @@ liberator.Completion = function () //{{{
/* Push and pop the stack, maintaining references to 'top' and 'last'. */
let push = function (arg)
{
top = [i, arg, [], [], [], []];
if (arg)
top[STATEMENTS].push(firstNonwhite());
top = [i, arg, [i], [], [], []];
last = top[CHAR];
stack.push(top);
}
@@ -204,6 +211,8 @@ liberator.Completion = function () //{{{
{
if (top[CHAR] != arg)
throw new Error("Invalid JS");
if (top[STATEMENTS][top[STATEMENTS].length - 1] == i)
top[STATEMENTS].pop();
top = get(-2);
last = top[CHAR];
let ret = stack.pop();
@@ -225,6 +234,12 @@ liberator.Completion = function () //{{{
stack = [];
push("");
}
else
{
let s = top[STATEMENTS];
if (s[s.length - 1] == start)
s.pop();
}
/* Build a parse stack, discarding entries opening characters
* match closing characters. The last open entry is used to
@@ -246,6 +261,15 @@ liberator.Completion = function () //{{{
}
else
{
if (/[\w$]/.test(c) && !/[\w\d$]/.test(lastChar) || !/[\w\d\s]/.test(c))
top[STATEMENTS].push(i);
// A "." or a "[" dereferences the last "statement" and effectively
// joins it to this logical statement.
if ((c == "." || c == "[") && /[\w\d\])"']/.test(lastNonwhite)
|| lastNonwhite == "." && /[\w$]/.test(c))
top[STATEMENTS].pop();
switch (c)
{
case "(":
@@ -259,10 +283,11 @@ liberator.Completion = function () //{{{
push(c);
break;
case "[":
if (/[\])"']/.test(lastNonwhite))
top[STATEMENTS].pop();
push(c);
break;
case ".":
top[DOTS].push(i);
break;
case ")": pop("("); break;
case "]": pop("["); break;
case "}": pop("{"); /* Fallthrough */
@@ -270,20 +295,16 @@ liberator.Completion = function () //{{{
case ",":
top[FULL_STATEMENTS].push(i);
break;
case ".":
top[DOTS].push(i);
if (/[\])"']/.test(lastNonwhite))
top[STATEMENTS].pop();
break;
}
/* Could do better. */
if (!/[\w\s.([]/.test(c))
top[STATEMENTS].push(i);
if (/\S/.test(c))
lastNonwhite = c;
}
}
if (!/[\w\d$]/.test(lastChar) && lastNonwhite != ".")
top[STATEMENTS].push(i);
lastIdx = i;
}
@@ -291,12 +312,14 @@ liberator.Completion = function () //{{{
{
try
{
continuing = string.indexOf(str) == 0;
continuing = lastIdx && string.indexOf(str) == 0;
str = string;
buildStack(continuing ? lastIdx : 0);
}
catch (e)
{
liberator.dump(liberator.util.escapeString(string) + ": " + e + "\n" + e.stack + "\n");
lastIdx = 0;
return [0, []];
}
@@ -307,6 +330,7 @@ liberator.Completion = function () //{{{
let preEval = str.substring(0, end) + ";";
/* In a string. */
// TODO: Make this work with unquoted integers.
if (last == "'" || last == '"')
{
/* Stack:
@@ -316,9 +340,11 @@ liberator.Completion = function () //{{{
*/
/* Is this an object accessor? */
if (get(-2)[CHAR] != "[" /* Are inside of []? */
|| get(-3, 0, STATEMENTS) == get(-2)[OFFSET]) /* Okay. Is it an array literal? */
return [0, []]; /* No. Nothing to do. */
if (get(-2)[CHAR] != "[" // Are we inside of []?
// Okay, if the [ starts at the begining of a logical
// statement, we're in an array literal, and we're done.
|| get(-3, 0, STATEMENTS) == get(-2)[OFFSET])
return [0, []];
/*
* str = "foo[bar + 'baz"
@@ -343,12 +369,12 @@ liberator.Completion = function () //{{{
* obj = "foo.bar"
* key = "baz"
*/
let key = str.substring(dot + 1);
let [, space, key] = str.substring(dot + 1).match(/^(\s*)(.*)/);
let obj = preEval + str.substring(get(-1, 0, STATEMENTS), dot);
if (!/^(?:\w[\w\d]*)?$/.test(key))
return [0, []]; /* Not a word. Forget it. Can this even happen? */
return [dot + 1, objectKeys(obj, key)];
return [dot + 1 + space.length, objectKeys(obj, key)];
}
/* Okay, assume it's an identifier and try to complete it from the window
@@ -383,6 +409,7 @@ liberator.Completion = function () //{{{
// list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ]
function buildLongestCommonSubstring(list, filter, favicon)
{
liberator.completion.filterString = filter;
var filtered = [];
var ignorecase = false;
@@ -766,8 +793,12 @@ liberator.Completion = function () //{{{
history: function (filter) [0, liberator.history.get(filter)],
javascript: function (str)
{
try
{
return javascript.complete(str);
}
catch (e) {}
},
macro: function (filter)
@@ -789,6 +820,7 @@ liberator.Completion = function () //{{{
// XXX: Move to bookmarks.js?
searchEngineSuggest: function (filter, engineAliases)
{
this.filterString = filter;
if (!filter)
return [0, []];
@@ -875,6 +907,7 @@ liberator.Completion = function () //{{{
// if the 'complete' argument is passed like "h", it temporarily overrides the complete option
url: function (filter, complete)
{
this.filterString = filter;
var completions = [];
var start = 0;
var skip = filter.match("^(.*" + liberator.options["urlseparator"] + ")(.*)"); // start after the last 'urlseparator'

View File

@@ -737,7 +737,6 @@ lookup:
// no need (actually forbidden) to add: js <<EOF ... EOF around those files
source: function (filename, silent)
{
liberator.dump("filename: " + filename + "\n");
try
{
var file = ioManager.getFile(filename);

View File

@@ -1085,8 +1085,6 @@ const liberator = (function () //{{{
loadModule("io", liberator.IO);
loadModule("completion", liberator.Completion);
liberator.dump(liberator.io.source.toString() + "\n");
// This adds options/mappings/commands which are only valid in this particular extension
if (liberator.config.init)
liberator.config.init();

View File

@@ -80,13 +80,14 @@ liberator.template = {
{
let lcstr = str.toLowerCase();
let lcfilter = filter.toLowerCase();
str = str.replace(" ", " ");
let s = <></>;
let start = 0;
let i;
while ((i = lca.indexOf(lcfilter, start)) > -1)
while ((i = lcstr.indexOf(lcfilter, start)) > -1)
{
s += <>{str.substring(start, i)}</>;
s += <span style="font-weight: bold">{str.substr(i, filter.length)}</span>;
s += <span class="hl-Filter">{str.substr(i, filter.length)}</span>;
start = i + filter.length;
}
return s + <>{str.substr(start)}</>;

View File

@@ -1218,17 +1218,23 @@ liberator.ItemList = function (id) //{{{
// TODO: temporary, to be changed/removed
function createRow(b, c, a, dom)
{
let row =
<tr class="compitem">
<td class="favicon"/>
<td class="completion">{b}</td>
<td class="description">{c}</td>
</tr>
/* Obviously, ItemList shouldn't know or care about this. */
let filter = liberator.completion.filterString;
if (filter)
{
b = liberator.template.highlightFilter(String(b), filter);
c = liberator.template.highlightFilter(String(c), filter);
}
if (typeof a == "function")
a = a();
if (a)
row.td[0].* = <img src={a}/>;
let row =
<tr class="compitem">
<td class="favicon">{a ? <img src={a}/> : <span/>}</td>
<td class="completion">{b}</td>
<td class="description">{c}</td>
</tr>;
if (dom)
return liberator.util.xmlToDom(row, doc);

View File

@@ -42,6 +42,35 @@ the terms of any one of the MPL, the GPL or the LGPL.
right: 0;
}
.__liberator-search {
display: inline;
font-size: inherit;
padding: 0;
color: black;
background-color: yellow;
padding: 0;
display: inline;
}
.liberator-hint {
z-index:5000;
font-family:monospace;
font-size:10px;
font-weight: bold;
color:white;
background-color:red;
border-color:ButtonShadow;
border-width:0px;
border-style:solid;
padding:0px 1px 0px 1px;
position:absolute;
}
#liberator-visualbell {
border: none;
background-color: black;
}
/* Applied only to completion buffer and MOW */
@-moz-document
url-prefix(chrome://vimperator/),
@@ -51,7 +80,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
.compitem[selected=true] { background-color: yellow; }
.compitem > .favicon { width: 16px; }
.compitem > .favicon > img { width: 16px; height: 16px; }
.compitem > .favicon > * { width: 16px; height: 16px; display: block; }
.compitem > .completion { width: 45%; overflow: hidden; }
.compitem > .description { color: gray; }
@@ -70,6 +99,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
.hl-Keyword { color: red; }
.hl-Tag { color: blue; }
.hl-Filter { font-weight: bold; }
}
/* Applied to completion buffer, MOW, browser window */