mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 20:22:26 +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:
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)}</>;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user