diff --git a/ChangeLog b/ChangeLog
index 471040d0..9c09d596 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
2007-07-02:
* version 0.5
+ * rename :qmarkadd :qmark and :qmarkdel :delqmarks
* vimperator.events.feedkeys("2zi") support for scripts
* Ctrl-U/Ctrl-D for scrolling the window up/down and the associated
'scroll' option
diff --git a/chrome/content/vimperator/bookmarks.js b/chrome/content/vimperator/bookmarks.js
index 96cc74e0..521a7e44 100644
--- a/chrome/content/vimperator/bookmarks.js
+++ b/chrome/content/vimperator/bookmarks.js
@@ -532,6 +532,7 @@ function Marks() //{{{
{
// local marks
var lmarks = [];
+
for (var mark in local_marks)
{
for (var i = 0; i < local_marks[mark].length; i++)
@@ -544,17 +545,18 @@ function Marks() //{{{
// URL marks
var umarks = [];
+
for (var mark in url_marks)
umarks.push([mark, url_marks[mark]]);
// FIXME: why does umarks.sort() cause a "Component is not available =
// NS_ERROR_NOT_AVAILABLE" exception when used here?
umarks.sort(function(a, b) {
- if (a[0] < b[0])
- return -1;
- else if (a[0] > b[0])
- return 1;
- else
- return 0;
+ if (a[0] < b[0])
+ return -1;
+ else if (a[0] > b[0])
+ return 1;
+ else
+ return 0;
});
return lmarks.concat(umarks);
@@ -578,6 +580,7 @@ function Marks() //{{{
var x = win.scrollMaxX ? win.pageXOffset / win.scrollMaxX : 0;
var y = win.scrollMaxY ? win.pageYOffset / win.scrollMaxY : 0;
var position = { x: x, y: y };
+
if (isURLMark(mark))
{
vimperator.log("Adding URL mark: " + mark + " | " + win.location.href + " | (" + position.x + ", " + position.y + ") | tab: " + vimperator.tabs.index(vimperator.tabs.getTab()), 5);
@@ -621,6 +624,7 @@ function Marks() //{{{
this.jumpTo = function(mark)
{
var ok = false;
+
if (isURLMark(mark))
{
var slice = url_marks[mark];
@@ -655,6 +659,7 @@ function Marks() //{{{
{
var win = window.content;
var slice = local_marks[mark] || [];
+
for (var i = 0; i < slice.length; i++)
{
if (win.location.href == slice[i].location)
@@ -716,70 +721,96 @@ function QuickMarks() //{{{
////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
- var marks = {};
+ var qmarks = {};
// load the saved quickmarks -- TODO: change to sqlite
var saved_marks = Options.getPref("quickmarks", "").split("\n");
+
for (var i = 0; i < saved_marks.length - 1; i += 2)
{
- marks[saved_marks[i]] = saved_marks[i + 1];
+ qmarks[saved_marks[i]] = saved_marks[i + 1];
}
+ // TODO: should we sort by a-zA-Z0-9 rather than 0-9A-Za-z?
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
- this.add = function(mark, location)
+ this.add = function(qmark, location)
{
- marks[mark] = location;
+ qmarks[qmark] = location;
}
this.remove = function(filter)
{
var pattern = new RegExp("[" + filter.replace(/\s+/g, '') + "]");
- for (var mark in marks)
+
+ for (var qmark in qmarks)
{
- if (pattern.test(mark))
- delete marks[mark];
+ if (pattern.test(qmark))
+ delete qmarks[qmark];
}
}
- this.jumpTo = function(mark, where)
+ this.jumpTo = function(qmark, where)
{
- var url = marks[mark];
+ var url = qmarks[qmark];
+
if (url)
vimperator.open(url, where);
else
vimperator.echoerr("E20: QuickMark not set");
}
- this.list = function()
+ this.list = function(filter)
{
- var is_empty = true;
- var list = "| mark | URL |
";
- for (var i in marks)
+ var marks = [];
+
+ // TODO: should we sort these in a-zA-Z0-9 order?
+ for (var mark in qmarks)
+ marks.push([mark, qmarks[mark]]);
+ marks.sort();
+
+ if (marks.length == 0)
{
- is_empty = false;
- list += "| " + i + " | "
- + marks[i] + " |
";
+ vimperator.echoerr("No marks set");
+ return;
+ }
+
+ if (filter.length > 0)
+ {
+ marks = marks.filter(function(mark) {
+ if (filter.indexOf(mark[0]) > -1)
+ return mark;
+ });
+ if (marks.length == 0)
+ {
+ vimperator.echoerr("E283: No QuickMarks matching \"" + filter + "\"");
+ return;
+ }
+ }
+
+ var list = "| QuickMark | URL |
";
+ for (var i = 0; i < marks.length; i++)
+ {
+ list += "| " + marks[i][0] + " | " + marks[i][1] + " |
";
}
list += "
";
- if (!is_empty)
- vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way
- else
- vimperator.echoerr("No quickmarks defined");
+ vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way
}
this.destroy = function()
{
- // save the marks
- var saved_marks = "";
- for (var i in marks)
+ // save the quickmarks
+ var saved_qmarks = "";
+
+ for (var i in qmarks)
{
- saved_marks += i + "\n";
- saved_marks += marks[i] + "\n";
+ saved_qmarks += i + "\n";
+ saved_qmarks += qmarks[i] + "\n";
}
- Options.setPref("quickmarks", saved_marks);
+
+ Options.setPref("quickmarks", saved_qmarks);
}
//}}}
} //}}}
diff --git a/chrome/content/vimperator/commands.js b/chrome/content/vimperator/commands.js
index 7b994428..3d8921c1 100644
--- a/chrome/content/vimperator/commands.js
+++ b/chrome/content/vimperator/commands.js
@@ -421,8 +421,8 @@ function Commands() //{{{
vimperator.marks.remove(args, special);
},
{
- usage: ["delm[arks][!] {marks}"],
- short_help: "Delete the specified marks {a-zA-Z}",
+ usage: ["delm[arks] {marks}", "delm[arks]!"],
+ short_help: "Delete the specified marks",
help: "Marks are presented as a list. Example:
" +
":delmarks Aa b p will delete marks A, a, b and p
" +
":delmarks b-p will delete all marks in the range b to p
" +
@@ -430,6 +430,32 @@ function Commands() //{{{
}
));
+ addDefaultCommand(new Command(["delqm[arks]"],
+ function(args, special)
+ {
+ // TODO: finish arg parsing - we really need a proper way to do this. :)
+ if (!special && !args)
+ {
+ vimperator.echoerr("E471: Argument required");
+ return;
+ }
+ if (special && args)
+ {
+ vimperator.echoerr("E474: Invalid argument");
+ return
+ }
+
+ vimperator.quickmarks.remove(args);
+ },
+ {
+ usage: ["delqm[arks] {marks}", "delqm[arks]!"],
+ short_help: "Delete the specified QuickMarks",
+ help: "QuickMarks are presented as a list. Example:
" +
+ ":delqmarks Aa b p will delete QuickMarks A, a, b and p
" +
+ ":delqmarks b-p will delete all QuickMarks in the range b to p
" +
+ ":delqmarks! will delete all QuickMarks"
+ }
+ ));
addDefaultCommand(new Command(["downl[oads]", "dl"],
function() { vimperator.open("chrome://mozapps/content/downloads/downloads.xul", vimperator.NEW_TAB); },
{
@@ -619,7 +645,7 @@ function Commands() //{{{
},
{
short_help: "Remove all mappings",
- help: ""
+ help: "TODO"
}
));
addDefaultCommand(new Command(["ma[rk]"],
@@ -642,24 +668,27 @@ function Commands() //{{{
vimperator.marks.add(args);
},
{
- usage: ["ma[rk] {arg}"],
+ usage: ["ma[rk] {a-zA-Z}"],
short_help: "Mark current location within the web page"
}
));
addDefaultCommand(new Command(["marks"],
function(args)
{
- if (args.length > 1 && !/[a-zA-Z]/.test(args))
+ // ignore invalid mark characters unless there are no valid mark chars
+ if (args.length > 0 && !/[a-zA-Z]/.test(args))
{
vimperator.echoerr("E283: No marks matching \"" + args + "\"");
return;
}
+
var filter = args.replace(/[^a-zA-Z]/g, '');
vimperator.marks.list(filter)
},
{
- usage: ["marks {arg}"],
- short_help: "Show all location marks of current web page"
+ usage: ["marks [arg]"],
+ short_help: "Show all location marks of current web page",
+ help: "If [arg] is specified then limit the list to the those marks mentioned."
}
));
// TODO: remove duplication in :map
@@ -771,6 +800,50 @@ function Commands() //{{{
"Works like :set!, but opens the dialog in a new window instead of a new tab. Use this, if you experience problems/crashes when using :set!"
}
));
+ addDefaultCommand(new Command(["qma[rk]"],
+ function(args)
+ {
+ if (!args) {
+ vimperator.echoerr("E471: Argument required");
+ return;
+ }
+
+ var matches1 = args.match(/([a-zA-Z0-9])\s+(.+)/);
+ var matches2 = args.match(/([a-zA-Z0-9])\s*$/);
+
+ if (matches1 && matches1[1])
+ vimperator.quickmarks.add(matches1[1], matches1[2]);
+ else if (matches2 && matches2)
+ vimperator.quickmarks.add(matches2[1], vimperator.buffer.location);
+ else
+ vimperator.echoerr("E488: Trailing characters");
+ },
+ {
+ usage: ["qma[rk] {a-zA-Z0-9} [url]"],
+ short_help: "Mark a URL with a letter for quick access",
+ help: "You can also mark whole groups like this:
"+
+ ":qmark f http://forum1.com, http://forum2.com, imdb some artist"
+ }
+ ));
+ addDefaultCommand(new Command(["qmarks"],
+ function(args)
+ {
+ // ignore invalid mark characters unless there are no valid mark chars
+ if (args.length > 0 && !/[a-zA-Z0-9]/.test(args))
+ {
+ vimperator.echoerr("E283: No QuickMarks matching \"" + args + "\"");
+ return;
+ }
+
+ var filter = args.replace(/[^a-zA-Z0-9]/g, '');
+ vimperator.quickmarks.list(filter);
+ },
+ {
+ usage: ["qmarks [arg]"],
+ short_help: "Show all QuickMarks",
+ help: "If [arg] is specified then limit the list to the those QuickMarks mentioned."
+ }
+ ));
addDefaultCommand(new Command(["q[uit]"],
function() { vimperator.tabs.remove(getBrowser().mCurrentTab, 1, false, 1); },
{
@@ -1045,42 +1118,6 @@ function Commands() //{{{
help: "If a count is given, don't close the last but the n'th last tab."
}
));
- addDefaultCommand(new Command(["qmarka[dd]", "qma[dd]"],
- function(args)
- {
- var matches1 = args.match(/([a-zA-Z0-9])\s+(.+)/);
- var matches2 = args.match(/([a-zA-Z0-9])\s*$/);
- if (matches1 && matches1[1])
- vimperator.quickmarks.add(matches1[1], matches1[2]);
- else if (matches2 && matches2)
- vimperator.quickmarks.add(matches2[1], vimperator.buffer.location);
- else
- vimperator.echoerr("E488: Trailing characters");
- },
- {
- usage: ["qmarka[dd] {a-zA-Z0-9} [url]"],
- short_help: "Mark a URL with a letter for quick access",
- help: "You can also mark whole groups like this:
"+
- ":qmarkadd f http://forum1.com, http://forum2.com, imdb some artist",
- completer: function(filter) { return [["a", ""], ["b", ""]]; }
- }
- ));
- addDefaultCommand(new Command(["qmarkd[el]", "qmd[el]"],
- function(args) { vimperator.quickmarks.remove(args); },
- {
- usage: ["qmarkd[el] {a-zA-Z0-9}"],
- short_help: "Remove a marked URL",
- help: "TODO.",
- completer: function(filter) { return [["a", ""], ["b", ""]]; }
- }
- ));
- addDefaultCommand(new Command(["qmarks", "qms"],
- function(args) { vimperator.quickmarks.list(args); },
- {
- short_help: "Show marked URLs",
- help: "TODO."
- }
- ));
addDefaultCommand(new Command(["unm[ap]"],
function(args)
{
diff --git a/chrome/content/vimperator/mappings.js b/chrome/content/vimperator/mappings.js
index b6019150..9f5678f0 100644
--- a/chrome/content/vimperator/mappings.js
+++ b/chrome/content/vimperator/mappings.js
@@ -299,8 +299,8 @@ function Mappings() //{{{
function(arg) { vimperator.marks.jumpTo(arg) },
{
short_help: "Jump to the mark in the current buffer",
- usage: ["'{a-zA-Z0-9}"],
- help: "Marks a-z are local to the buffer, whereas A-Z and 0-9 are valid between buffers.",
+ usage: ["'{a-zA-Z}"],
+ help: "Marks a-z are local to the buffer, whereas A-Z are valid between buffers.",
flags: Mappings.flags.ARGUMENT
}
));
@@ -452,16 +452,34 @@ function Mappings() //{{{
}
));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["m"],
- function(arg) { vimperator.marks.add(arg) },
+ function(arg)
+ {
+ if (/[^a-zA-Z]/.test(arg))
+ {
+ vimperator.beep();
+ return;
+ }
+
+ vimperator.marks.add(arg)
+ },
{
short_help: "Set mark at the cursor position",
- usage: ["m{a-zA-Z0-9}"],
- help: "Marks a-z are local to the buffer, whereas A-Z and 0-9 are valid between buffers.",
+ usage: ["m{a-zA-Z}"],
+ help: "Marks a-z are local to the buffer, whereas A-Z are valid between buffers.",
flags: Mappings.flags.ARGUMENT
}
));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["M"],
- function(arg) { vimperator.quickmarks.add(arg, vimperator.buffer.location) },
+ function(arg)
+ {
+ if (/[^a-zA-Z0-9]/.test(arg))
+ {
+ vimperator.beep();
+ return;
+ }
+
+ vimperator.quickmarks.add(arg, vimperator.buffer.location)
+ },
{
short_help: "Add new QuickMark for current URL",
usage: ["M{a-zA-Z0-9}"],