mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 17:57:59 +01:00
Add 'linenumbers'.
This commit is contained in:
@@ -1841,7 +1841,15 @@ var Buffer = Module("buffer", {
|
|||||||
|
|
||||||
mappings.add([modes.NORMAL], ["G", "<End>", "<scroll-bottom>"],
|
mappings.add([modes.NORMAL], ["G", "<End>", "<scroll-bottom>"],
|
||||||
"Go to the end of the document",
|
"Go to the end of the document",
|
||||||
function (args) { buffer.scrollToPercent(null, args.count != null ? args.count : 100); },
|
function (args) {
|
||||||
|
if (args.count)
|
||||||
|
var elem = options.get("linenumbers").getLine(buffer.focusedFrame.document,
|
||||||
|
args.count);
|
||||||
|
if (elem)
|
||||||
|
elem.scrollIntoView(true);
|
||||||
|
else
|
||||||
|
buffer.scrollToPercent(null, args.count != null ? args.count : 100);
|
||||||
|
},
|
||||||
{ count: true });
|
{ count: true });
|
||||||
|
|
||||||
mappings.add([modes.NORMAL], ["%", "<scroll-percent>"],
|
mappings.add([modes.NORMAL], ["%", "<scroll-percent>"],
|
||||||
@@ -2132,6 +2140,52 @@ var Buffer = Module("buffer", {
|
|||||||
&& Object.keys(value).every(function (v) v.length == 1)
|
&& Object.keys(value).every(function (v) v.length == 1)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
options.add(["linenumbers", "ln"],
|
||||||
|
"Patterns used to determine line numbers used by G",
|
||||||
|
"sitemap", {
|
||||||
|
"code.google.com": '#nums [id^="nums_table"] a[href^="#"]',
|
||||||
|
"github.com": '.line_numbers>*',
|
||||||
|
"mxr.mozilla.org": 'a.l',
|
||||||
|
"pastebin.com": '#code_frame>div>ol>li'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
getLine: function getLine(doc, line) {
|
||||||
|
let uri = util.newURI(doc.documentURI);
|
||||||
|
for (let filter in values(this.value))
|
||||||
|
if (filter(uri, doc)) {
|
||||||
|
if (/^func:/.test(filter.result))
|
||||||
|
var res = dactyl.userEval("(" + Option.dequote(filter.result.substr(5)) + ")")(doc, line);
|
||||||
|
else
|
||||||
|
res = iter.nth(filter.matcher(doc),
|
||||||
|
function (elem) (elem.nodeValue || elem.textContent).trim() == line && DOM(elem).display != "none",
|
||||||
|
0)
|
||||||
|
|| iter.nth(filter.matcher(doc), util.identity, line - 1);
|
||||||
|
if (res)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
keepQuotes: true,
|
||||||
|
|
||||||
|
setter: function (vals) {
|
||||||
|
for (let value in values(vals))
|
||||||
|
if (!/^func:/.test(value.result))
|
||||||
|
value.matcher = DOM.compileMatcher(Option.splitList(value.result));
|
||||||
|
return vals;
|
||||||
|
},
|
||||||
|
|
||||||
|
validate: function validate(values) {
|
||||||
|
return this.testValues(values, function (value) {
|
||||||
|
if (/^func:/.test(value))
|
||||||
|
return callable(dactyl.userEval("(" + Option.dequote(value.substr(5)) + ")"));
|
||||||
|
else
|
||||||
|
return DOM.testMatcher(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
options.add(["nextpattern"],
|
options.add(["nextpattern"],
|
||||||
"Patterns to use when guessing the next page in a document sequence",
|
"Patterns to use when guessing the next page in a document sequence",
|
||||||
"regexplist", UTF8(/'\bnext\b',^>$,^(>>|»)$,^(>|»),(>|»)$,'\bmore\b'/.source),
|
"regexplist", UTF8(/'\bnext\b',^>$,^(>>|»)$,^(>|»),(>|»)$,'\bmore\b'/.source),
|
||||||
|
|||||||
@@ -111,20 +111,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @property {string} The name of the current user profile. */
|
profileName: deprecated("config.profileName", { get: function profileName() config.profileName }),
|
||||||
profileName: Class.Memoize(function () {
|
|
||||||
// NOTE: services.profile.selectedProfile.name doesn't return
|
|
||||||
// what you might expect. It returns the last _actively_ selected
|
|
||||||
// profile (i.e. via the Profile Manager or -P option) rather than the
|
|
||||||
// current profile. These will differ if the current process was run
|
|
||||||
// without explicitly selecting a profile.
|
|
||||||
|
|
||||||
let dir = services.directory.get("ProfD", Ci.nsIFile);
|
|
||||||
for (let prof in iter(services.profile.profiles))
|
|
||||||
if (prof.QueryInterface(Ci.nsIToolkitProfile).rootDir.path === dir.path)
|
|
||||||
return prof.name;
|
|
||||||
return "unknown";
|
|
||||||
}),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {Modes.Mode} The current main mode.
|
* @property {Modes.Mode} The current main mode.
|
||||||
|
|||||||
@@ -134,7 +134,9 @@
|
|||||||
<description>
|
<description>
|
||||||
<p>
|
<p>
|
||||||
Go to the end of the document. With <oa>count</oa>,
|
Go to the end of the document. With <oa>count</oa>,
|
||||||
behaves exactly the same as <oa>gg</oa>.
|
go to the <oa>count</oa>th line as determined by <o>linenumbers</o>,
|
||||||
|
or to the <oa>count</oa>th percent of the document if the line number
|
||||||
|
can't be determined.
|
||||||
</p>
|
</p>
|
||||||
</description>
|
</description>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -1034,6 +1034,25 @@
|
|||||||
</description>
|
</description>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<tags>'ln' 'linenumbers'</tags>
|
||||||
|
<spec>'linenumbers' 'ln'</spec>
|
||||||
|
<type>&option.linenumbers.type;</type>
|
||||||
|
<default>&option.linenumbers.default;</default>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
Patterns used to determine line numbers used by <k>G</k>. May be
|
||||||
|
either a selector expression as accepted by <o>hinttags</o>, in
|
||||||
|
which case the first matching element whose text content is equal to
|
||||||
|
the desired line number is used or the <oa>count</oa>th element
|
||||||
|
failing that, or the string <str delim="'">func:</str> followed by a
|
||||||
|
function which, given arguments for the document and desired line
|
||||||
|
number must return the target element.
|
||||||
|
</p>
|
||||||
|
</description>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
|
||||||
<item>
|
<item>
|
||||||
<tags>'lpl' 'loadplugins'</tags>
|
<tags>'lpl' 'loadplugins'</tags>
|
||||||
<spec>'loadplugins' 'lpl'</spec>
|
<spec>'loadplugins' 'lpl'</spec>
|
||||||
|
|||||||
@@ -122,7 +122,12 @@ if (!Object.keys)
|
|||||||
|
|
||||||
let getGlobalForObject = Cu.getGlobalForObject || function (obj) obj.__parent__;
|
let getGlobalForObject = Cu.getGlobalForObject || function (obj) obj.__parent__;
|
||||||
|
|
||||||
let jsmodules = {};
|
let jsmodules = {
|
||||||
|
lazyRequire: function lazyRequire(module, names, target) {
|
||||||
|
for each (let name in names)
|
||||||
|
memoize(target || this, name, function (name) require(module)[name]);
|
||||||
|
}
|
||||||
|
};
|
||||||
let use = {};
|
let use = {};
|
||||||
let loaded = {};
|
let loaded = {};
|
||||||
let currentModule;
|
let currentModule;
|
||||||
@@ -229,6 +234,8 @@ defineModule("base", {
|
|||||||
]
|
]
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.lazyRequire("messages", ["_", "Messages"]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all of the top-level properties of an object, by
|
* Returns a list of all of the top-level properties of an object, by
|
||||||
* way of the debugger.
|
* way of the debugger.
|
||||||
@@ -325,7 +332,7 @@ deprecated.warn = function warn(func, name, alternative, frame) {
|
|||||||
let filename = util.fixURI(frame.filename || "unknown");
|
let filename = util.fixURI(frame.filename || "unknown");
|
||||||
if (!Set.add(func.seenCaller, filename))
|
if (!Set.add(func.seenCaller, filename))
|
||||||
util.dactyl(func).warn([util.urlPath(filename), frame.lineNumber, " "].join(":")
|
util.dactyl(func).warn([util.urlPath(filename), frame.lineNumber, " "].join(":")
|
||||||
+ require("messages")._("warn.deprecated", name, alternative));
|
+ _("warn.deprecated", name, alternative));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1242,7 +1249,7 @@ var StructBase = Class("StructBase", Array, {
|
|||||||
|
|
||||||
localize: function localize(key, defaultValue) {
|
localize: function localize(key, defaultValue) {
|
||||||
let i = this.prototype.members[key];
|
let i = this.prototype.members[key];
|
||||||
Object.defineProperty(this.prototype, i, require("messages").Messages.Localized(defaultValue).init(key, this.prototype));
|
Object.defineProperty(this.prototype, i, Messages.Localized(defaultValue).init(key, this.prototype));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ defineModule("config", {
|
|||||||
require: ["dom", "protocol", "services", "storage", "util", "template"]
|
require: ["dom", "protocol", "services", "storage", "util", "template"]
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.lazyRequire("addons", ["AddonManager"]);
|
||||||
|
this.lazyRequire("highlight", ["highlight"]);
|
||||||
|
this.lazyRequire("messages", ["_"]);
|
||||||
|
|
||||||
function AboutHandler() {}
|
function AboutHandler() {}
|
||||||
AboutHandler.prototype = {
|
AboutHandler.prototype = {
|
||||||
get classDescription() "About " + config.appName + " Page",
|
get classDescription() "About " + config.appName + " Page",
|
||||||
@@ -102,9 +106,6 @@ var ConfigBase = Class("ConfigBase", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
loadStyles: function loadStyles(force) {
|
loadStyles: function loadStyles(force) {
|
||||||
const { highlight } = require("highlight");
|
|
||||||
const { _ } = require("messages");
|
|
||||||
|
|
||||||
highlight.styleableChrome = this.styleableChrome;
|
highlight.styleableChrome = this.styleableChrome;
|
||||||
|
|
||||||
highlight.loadCSS(this.CSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
|
highlight.loadCSS(this.CSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
|
||||||
@@ -145,7 +146,7 @@ var ConfigBase = Class("ConfigBase", {
|
|||||||
|
|
||||||
addon: Class.Memoize(function () {
|
addon: Class.Memoize(function () {
|
||||||
return (JSMLoader.bootstrap || {}).addon ||
|
return (JSMLoader.bootstrap || {}).addon ||
|
||||||
require("addons").AddonManager.getAddonByID(this.addonID);
|
AddonManager.getAddonByID(this.addonID);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -311,6 +312,21 @@ var ConfigBase = Class("ConfigBase", {
|
|||||||
return (/pre-hg\d+-(\S*)/.exec(this.version) || [])[1];
|
return (/pre-hg\d+-(\S*)/.exec(this.version) || [])[1];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/** @property {string} The name of the current user profile. */
|
||||||
|
profileName: Class.Memoize(function () {
|
||||||
|
// NOTE: services.profile.selectedProfile.name doesn't return
|
||||||
|
// what you might expect. It returns the last _actively_ selected
|
||||||
|
// profile (i.e. via the Profile Manager or -P option) rather than the
|
||||||
|
// current profile. These will differ if the current process was run
|
||||||
|
// without explicitly selecting a profile.
|
||||||
|
|
||||||
|
let dir = services.directory.get("ProfD", Ci.nsIFile);
|
||||||
|
for (let prof in iter(services.profile.profiles))
|
||||||
|
if (prof.QueryInterface(Ci.nsIToolkitProfile).rootDir.path === dir.path)
|
||||||
|
return prof.name;
|
||||||
|
return "unknown";
|
||||||
|
}),
|
||||||
|
|
||||||
/** @property {string} The Dactyl version string. */
|
/** @property {string} The Dactyl version string. */
|
||||||
version: Class.Memoize(function () {
|
version: Class.Memoize(function () {
|
||||||
if (this.VCSPath)
|
if (this.VCSPath)
|
||||||
@@ -375,7 +391,6 @@ var ConfigBase = Class("ConfigBase", {
|
|||||||
helpStyles: /^(Help|StatusLine|REPL)|^(Boolean|Dense|Indicator|MoreMsg|Number|Object|Logo|Key(word)?|String)$/,
|
helpStyles: /^(Help|StatusLine|REPL)|^(Boolean|Dense|Indicator|MoreMsg|Number|Object|Logo|Key(word)?|String)$/,
|
||||||
styleHelp: function styleHelp() {
|
styleHelp: function styleHelp() {
|
||||||
if (!this.helpStyled) {
|
if (!this.helpStyled) {
|
||||||
const { highlight } = require("highlight");
|
|
||||||
for (let k in keys(highlight.loaded))
|
for (let k in keys(highlight.loaded))
|
||||||
if (this.helpStyles.test(k))
|
if (this.helpStyles.test(k))
|
||||||
highlight.loaded[k] = true;
|
highlight.loaded[k] = true;
|
||||||
@@ -1064,7 +1079,6 @@ config.INIT = update(Object.create(config.INIT), config.INIT, {
|
|||||||
let img = window.Image();
|
let img = window.Image();
|
||||||
img.src = this.logo || "resource://dactyl-local-content/logo.png";
|
img.src = this.logo || "resource://dactyl-local-content/logo.png";
|
||||||
img.onload = util.wrapCallback(function () {
|
img.onload = util.wrapCallback(function () {
|
||||||
const { highlight } = require("highlight");
|
|
||||||
highlight.loadCSS(<>{"!Logo {"}
|
highlight.loadCSS(<>{"!Logo {"}
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: url({img.src});
|
background: url({img.src});
|
||||||
|
|||||||
@@ -1324,7 +1324,7 @@ var DOM = Class("DOM", {
|
|||||||
yield elem;
|
yield elem;
|
||||||
|
|
||||||
if (matcher.css)
|
if (matcher.css)
|
||||||
for (let [, elem] in iter(node.querySelectorAll(matcher.css)))
|
for (let [, elem] in iter(util.withProperErrors("querySelectorAll", node, matcher.css)))
|
||||||
yield elem;
|
yield elem;
|
||||||
}, {
|
}, {
|
||||||
css: css.join(", "),
|
css: css.join(", "),
|
||||||
@@ -1343,13 +1343,15 @@ var DOM = Class("DOM", {
|
|||||||
validateMatcher: function validateMatcher(list) {
|
validateMatcher: function validateMatcher(list) {
|
||||||
let evaluator = services.XPathEvaluator();
|
let evaluator = services.XPathEvaluator();
|
||||||
let node = services.XMLDocument();
|
let node = services.XMLDocument();
|
||||||
return this.testValues(list, function (value) {
|
return this.testValues(list, this.closure.testMatcher);
|
||||||
|
},
|
||||||
|
|
||||||
|
testMatcher: function testMatcher(value) {
|
||||||
if (/^xpath:/.test(value))
|
if (/^xpath:/.test(value))
|
||||||
evaluator.createExpression(value.substr(6), DOM.XPath.resolver);
|
evaluator.createExpression(value.substr(6), DOM.XPath.resolver);
|
||||||
else
|
else
|
||||||
node.querySelector(value);
|
node.querySelector(value);
|
||||||
return true;
|
return true;
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ defineModule("finder", {
|
|||||||
|
|
||||||
function equals(a, b) XPCNativeWrapper(a) == XPCNativeWrapper(b);
|
function equals(a, b) XPCNativeWrapper(a) == XPCNativeWrapper(b);
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
/** @instance rangefinder */
|
/** @instance rangefinder */
|
||||||
var RangeFinder = Module("rangefinder", {
|
var RangeFinder = Module("rangefinder", {
|
||||||
Local: function (dactyl, modules, window) ({
|
Local: function (dactyl, modules, window) ({
|
||||||
@@ -265,7 +263,6 @@ var RangeFinder = Module("rangefinder", {
|
|||||||
},
|
},
|
||||||
options: function (dactyl, modules, window) {
|
options: function (dactyl, modules, window) {
|
||||||
const { options, rangefinder } = modules;
|
const { options, rangefinder } = modules;
|
||||||
const { prefs } = require("prefs");
|
|
||||||
|
|
||||||
options.add(["hlfind", "hlf"],
|
options.add(["hlfind", "hlf"],
|
||||||
"Highlight all /find pattern matches on the current page after submission",
|
"Highlight all /find pattern matches on the current page after submission",
|
||||||
@@ -844,9 +841,8 @@ var RangeFind = Class("RangeFind", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch(e){ if (typeof e === "string") e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
|
// catch(e){ if (typeof e === "string") e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
|
||||||
|
|
||||||
endModule();
|
endModule();
|
||||||
|
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
|
// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||||
defineModule("storage", {
|
defineModule("storage", {
|
||||||
exports: ["File", "Storage", "storage"],
|
exports: ["File", "Storage", "storage"],
|
||||||
require: ["services", "util"]
|
require: ["config", "services", "util"]
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.lazyRequire("io", ["IO"]);
|
||||||
|
|
||||||
var win32 = /^win(32|nt)$/i.test(services.runtime.OS);
|
var win32 = /^win(32|nt)$/i.test(services.runtime.OS);
|
||||||
var myObject = JSON.parse("{}").constructor;
|
var myObject = JSON.parse("{}").constructor;
|
||||||
|
|
||||||
@@ -169,6 +171,10 @@ var Storage = Module("Storage", {
|
|||||||
this.observers = {};
|
this.observers = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
infoPath: Class.Memoize(function ()
|
||||||
|
File(IO.runtimePath.replace(/,.*/, ""))
|
||||||
|
.child("info").child(config.profileName)),
|
||||||
|
|
||||||
exists: function exists(name) this.infoPath.child(name).exists(),
|
exists: function exists(name) this.infoPath.child(name).exists(),
|
||||||
|
|
||||||
newObject: function newObject(key, constructor, params) {
|
newObject: function newObject(key, constructor, params) {
|
||||||
@@ -270,12 +276,6 @@ var Storage = Module("Storage", {
|
|||||||
skipXpcom: function skipXpcom(key, val) val instanceof Ci.nsISupports ? null : val
|
skipXpcom: function skipXpcom(key, val) val instanceof Ci.nsISupports ? null : val
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
init: function init(dactyl, modules) {
|
|
||||||
init.superapply(this, arguments);
|
|
||||||
storage.infoPath = File(modules.IO.runtimePath.replace(/,.*/, ""))
|
|
||||||
.child("info").child(dactyl.profileName);
|
|
||||||
},
|
|
||||||
|
|
||||||
cleanup: function (dactyl, modules, window) {
|
cleanup: function (dactyl, modules, window) {
|
||||||
overlay.setData(window, "storage-refs", null);
|
overlay.setData(window, "storage-refs", null);
|
||||||
this.removeDeadObservers();
|
this.removeDeadObservers();
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
- It's now possible to map keys in many more modes, including
|
- It's now possible to map keys in many more modes, including
|
||||||
Hint, Multi-line Output, and Menu. [b4]
|
Hint, Multi-line Output, and Menu. [b4]
|
||||||
- <C-o> and <C-i> now behave more like Vim. [b8]
|
- <C-o> and <C-i> now behave more like Vim. [b8]
|
||||||
|
- n_G now uses 'linenumbers' to determine destination if possible. [b8]
|
||||||
- Add n_s and n_S. [b8]
|
- Add n_s and n_S. [b8]
|
||||||
- Added Operator mode for motion maps, per Vim. [b8]
|
- Added Operator mode for motion maps, per Vim. [b8]
|
||||||
- Added site-specific mapping groups and related command
|
- Added site-specific mapping groups and related command
|
||||||
@@ -211,6 +212,7 @@
|
|||||||
- 'complete' now defaults to "slf" but file completion only
|
- 'complete' now defaults to "slf" but file completion only
|
||||||
triggers when the URL begins as above. [b1]
|
triggers when the URL begins as above. [b1]
|
||||||
- Added 'jumptags' option. [b7]
|
- Added 'jumptags' option. [b7]
|
||||||
|
- Added 'linenumbers' option. [b8]
|
||||||
- Added 's' flag to 'pageinfo' and changed default value. [b7]
|
- Added 's' flag to 'pageinfo' and changed default value. [b7]
|
||||||
- Added 'passkeys' option. [b3]
|
- Added 'passkeys' option. [b3]
|
||||||
- Added 'passunknown' option. [b7]
|
- Added 'passunknown' option. [b7]
|
||||||
|
|||||||
Reference in New Issue
Block a user