summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/content/buffer.js2
-rw-r--r--common/content/dactyl.js8
-rw-r--r--common/content/tabs.js117
-rw-r--r--common/locale/en-US/messages.properties3
-rw-r--r--common/locale/en-US/tabs.xml26
-rw-r--r--common/modules/commands.jsm8
-rw-r--r--common/modules/util.jsm1
7 files changed, 118 insertions, 47 deletions
diff --git a/common/content/buffer.js b/common/content/buffer.js
index 34a528e6..c31b92be 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -1470,7 +1470,7 @@ var Buffer = Module("buffer", {
command: function () "tabs.select"
};
context.compare = CompletionContext.Sort.number;
- context.filters = [CompletionContext.Filter.textDescription];
+ context.filters[0] = CompletionContext.Filter.textDescription;
for (let [id, vals] in Iterator(tabGroups))
context.fork(id, 0, this, function (context, [name, browsers]) {
diff --git a/common/content/dactyl.js b/common/content/dactyl.js
index 2c79ea92..f96109b1 100644
--- a/common/content/dactyl.js
+++ b/common/content/dactyl.js
@@ -960,7 +960,13 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
if (obj instanceof Command) {
link = function (cmd) <ex>{cmd}</ex>;
args = obj.parseArgs("", CompletionContext(str || ""));
- spec = function (cmd) cmd + (obj.bang ? <oa>!</oa> : <></>);
+ spec = function (cmd) <>{
+ obj.count ? <oa>count</oa> : <></>
+ }{
+ cmd
+ }{
+ obj.bang ? <oa>!</oa> : <></>
+ }</>;
}
else if (obj instanceof Map) {
spec = function (map) obj.count ? <><oa>count</oa>{map}</> : <>{map}</>;
diff --git a/common/content/tabs.js b/common/content/tabs.js
index f8584da2..dec2dcca 100644
--- a/common/content/tabs.js
+++ b/common/content/tabs.js
@@ -527,50 +527,17 @@ var Tabs = Module("tabs", {
commands.add(["bd[elete]", "bw[ipeout]", "bun[load]", "tabc[lose]"],
"Delete current buffer",
function (args) {
- let special = args.bang;
- let count = args.count;
- let arg = args[0] || "";
-
- if (arg) {
- let removed = 0;
- let matches = arg.match(/^(\d+):?/);
-
- if (matches) {
- config.removeTab(tabs.getTab(parseInt(matches[1], 10) - 1));
- removed = 1;
- }
- else {
- let str = arg.toLowerCase();
- let browsers = config.tabbrowser.browsers;
-
- for (let i = browsers.length - 1; i >= 0; i--) {
- let host, title, uri = browsers[i].currentURI.spec;
- if (browsers[i].currentURI.schemeIs("about")) {
- host = "";
- title = "(Untitled)";
- }
- else {
- host = browsers[i].currentURI.host;
- title = browsers[i].contentTitle;
- }
-
- [host, title, uri] = [host, title, uri].map(String.toLowerCase);
-
- if (host.indexOf(str) >= 0 || uri == str ||
- (special && (title.indexOf(str) >= 0 || uri.indexOf(str) >= 0))) {
- config.removeTab(tabs.getTab(i));
- removed++;
- }
- }
- }
+ let removed = 0;
+ for (let tab in matchTabs(args, args.bang)) {
+ config.removeTab(tab);
+ removed++;
+ }
+ if (args[0])
if (removed > 0)
- dactyl.echomsg(_("buffer.fewer", removed, removed == 1 ? "" : "s"), 9);
+ dactyl.echomsg(_("buffer.fewerTab" + (removed == 1 ? "" : "s"), removed), 9);
else
dactyl.echoerr(_("buffer.noMatching", arg));
- }
- else // just remove the current tab
- tabs.remove(tabs.getTab(), Math.max(count, 1), special);
}, {
argCount: "?",
bang: true,
@@ -580,6 +547,76 @@ var Tabs = Module("tabs", {
privateData: true
});
+ function matchTabs(args, substr) {
+ let filter = args[0];
+
+ if (!filter && args.count == null)
+ yield tabs.getTab();
+ else if (!filter)
+ yield dactyl.assert(tabs.getTab(args.count - 1));
+ else {
+ let matches = /^(\d+):?/.exec(filter);
+ if (matches)
+ yield dactyl.assert(args.count == null &&
+ tabs.getTab(parseInt(matches[1], 10) - 1));
+ else {
+ let str = filter.toLowerCase();
+ for (let tab in values(tabs.allTabs)) {
+ let host, title;
+ let browser = tab.linkedBrowser;
+ let uri = browser.currentURI.spec;
+ if (browser.currentURI.schemeIs("about")) {
+ host = "";
+ title = "(Untitled)";
+ }
+ else {
+ host = browser.currentURI.host;
+ title = browser.contentTitle;
+ }
+
+ [host, title, uri] = [host, title, uri].map(String.toLowerCase);
+
+ if (host.indexOf(str) >= 0 || uri == str ||
+ (substr && (title.indexOf(str) >= 0 || uri.indexOf(str) >= 0)))
+ if (args.count == null || --args.count == 0)
+ yield tab;
+ }
+ }
+ }
+ }
+
+ commands.add(["pin[tab]"],
+ "Pin tab as an application tab",
+ function (args) {
+ for (let tab in matchTabs(args, true))
+ config.browser[!args.bang || !tab.pinned ? "pinTab" : "unpinTab"](tab);
+ },
+ {
+ argCount: "?",
+ bang: true,
+ count: true,
+ completer: function (context, args) {
+ if (!args.bang)
+ context.filters.push(function ({ item }) !item.tab.pinned);
+ completion.buffer(context);
+ }
+ });
+
+ commands.add(["unpin[tab]"],
+ "Unpin tab as an application tab",
+ function (args) {
+ for (let tab in matchTabs(args, true))
+ config.browser.unpinTab(tab);
+ },
+ {
+ argCount: "?",
+ count: true,
+ completer: function (context, args) {
+ context.filters.push(function ({ item }) item.tab.pinned);
+ completion.buffer(context);
+ }
+ });
+
commands.add(["keepa[lt]"],
"Execute a command without changing the current alternate buffer",
function (args) {
diff --git a/common/locale/en-US/messages.properties b/common/locale/en-US/messages.properties
index bd51a22b..f76e89ee 100644
--- a/common/locale/en-US/messages.properties
+++ b/common/locale/en-US/messages.properties
@@ -26,7 +26,8 @@ bookmark.removed-1 = Removed bookmark: %S
bookmark.added-1 = Added bookmark: %S
bookmark.deleted-1 = %S bookmark(s) deleted
-buffer.fewer-2 = %S fewer tab%S
+buffer.fewerTab-1 = %S fewer tab
+buffer.fewerTabs-1 = %S fewer tabs
buffer.cantDetatchLast = Can't detach the last tab
buffer.noMatching-1 = No matching buffer for %S
buffer.multipleMatching-1 = More than one match for %S
diff --git a/common/locale/en-US/tabs.xml b/common/locale/en-US/tabs.xml
index d894020c..25e668c8 100644
--- a/common/locale/en-US/tabs.xml
+++ b/common/locale/en-US/tabs.xml
@@ -381,6 +381,32 @@
</description>
</item>
+<h2 tag="app-tabs application-tabs pinned-tabs">Application Tabs</h2>
+
+<item>
+ <tags>pin pintab</tags>
+ <spec><oa>count</oa>pin<oa>tab</oa><oa>!</oa> <oa>arg</oa></spec>
+ <description>
+ <p>
+ Pin tab as an application tab. If <oa>!</oa> is given,
+ the tab's pinned state is toggled. Arguments and count
+ are the same as for <ex>:bdelete</ex> and <ex>:buffer</ex>.
+ </p>
+ </description>
+</item>
+
+<item>
+ <tags>unpin unpintab</tags>
+ <spec><oa>count</oa>pin<oa>tab</oa> <oa>arg</oa></spec>
+ <description>
+ <p>
+ Unpin tab as an application tab. Arguments and count
+ are the same as for <ex>:pintab</ex>.
+ </p>
+ </description>
+</item>
+
+
</document>
<!-- vim:se sts=4 sw=4 et: -->
diff --git a/common/modules/commands.jsm b/common/modules/commands.jsm
index 1036f20c..64c932d0 100644
--- a/common/modules/commands.jsm
+++ b/common/modules/commands.jsm
@@ -447,7 +447,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
* Adds a new command to the builtin hive. Accessible only to core
* dactyl code. Plugins should use group.commands.add instead.
*
- * @param {string[]} names The names by which this command can be
+ * @param {string[]} specs The names by which this command can be
* invoked. The first name specified is the command's canonical
* name.
* @param {string} description A description of the command.
@@ -455,7 +455,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
* @param {Object} extra An optional extra configuration hash.
* @optional
*/
- add: function add(names, description, action, extra, replace) {
+ add: function add(specs, description, action, extra, replace) {
const { commands, contexts } = this.modules;
extra = extra || {};
@@ -463,7 +463,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
extra.definedAt = contexts.getCaller(Components.stack.caller);
extra.hive = this;
- extra.parsedSpecs = Command.parseSpecs(names);
+ extra.parsedSpecs = Command.parseSpecs(specs);
let names = array.flatten(extra.parsedSpecs);
let name = names[0];
@@ -483,7 +483,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
let self = this;
let closure = function () self._map[name];
- memoize(this._map, name, function () commands.Command(names, description, action, extra));
+ memoize(this._map, name, function () commands.Command(specs, description, action, extra));
memoize(this._list, this._list.length, closure);
for (let alias in values(names.slice(1)))
memoize(this._map, alias, closure);
diff --git a/common/modules/util.jsm b/common/modules/util.jsm
index 3c01d530..f56ce948 100644
--- a/common/modules/util.jsm
+++ b/common/modules/util.jsm
@@ -158,6 +158,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
assert: function (condition, message, quiet) {
if (!condition)
throw FailedAssertion(message, 1, quiet === undefined ? true : quiet);
+ return condition;
},
/**