From 3372fee9e940ac02e5f493959838a0267a5af189 Mon Sep 17 00:00:00 2001 From: Doug Kearns Date: Mon, 2 Jul 2007 07:40:42 +0000 Subject: [PATCH] allow :marks to take an argument and sort its output properly --- chrome/content/vimperator/bookmarks.js | 171 ++++++++++++++++--------- chrome/content/vimperator/commands.js | 8 +- 2 files changed, 115 insertions(+), 64 deletions(-) diff --git a/chrome/content/vimperator/bookmarks.js b/chrome/content/vimperator/bookmarks.js index fb2690e3..d4ae7cf1 100644 --- a/chrome/content/vimperator/bookmarks.js +++ b/chrome/content/vimperator/bookmarks.js @@ -7,6 +7,7 @@ function Bookmarks() //{{{ //////////////////////////////////////////////////////////////////////////////// ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ + const search_service = Components.classes["@mozilla.org/browser/search-service;1"]. getService(Components.interfaces.nsIBrowserSearchService); const rdf_service = Components.classes["@mozilla.org/rdf/rdf-service;1"]. @@ -15,7 +16,7 @@ function Bookmarks() //{{{ var bookmarks = null; var keywords = null; - if(vimperator.options["preload"]) + if (vimperator.options["preload"]) setTimeout(function() { load(); } , 100); function load() @@ -27,13 +28,13 @@ function Bookmarks() //{{{ var bmarks = []; // here getAllChildren will store the bookmarks BookmarksUtils.getAllChildren(root, bmarks); - for(var bm in bmarks) + for (var bm in bmarks) { if (bmarks[bm][0] && bmarks[bm][1]) bookmarks.push([bmarks[bm][1].Value, bmarks[bm][0].Value ]); // keyword - if(bmarks[bm][1] && bmarks[bm][2]) + if (bmarks[bm][1] && bmarks[bm][2]) keywords.push([bmarks[bm][2].Value, bmarks[bm][0].Value, bmarks[bm][1].Value]); } } @@ -41,6 +42,7 @@ function Bookmarks() //{{{ /////////////////////////////////////////////////////////////////////////////}}} ////////////////////// PUBLIC SECTION ////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ + /* * @return a new Array() of our bookmarks */ @@ -57,7 +59,7 @@ function Bookmarks() //{{{ */ this.add = function (title, uri, keyword) { - if(!bookmarks) + if (!bookmarks) load(); folder = rdf_service.GetResource("NC:BookmarksRoot"); @@ -78,7 +80,7 @@ function Bookmarks() //{{{ this.remove = function(url) { var deleted = 0; - if(!url) + if (!url) return 0; // gNC_NS for trunk, NC_NS for 1.X @@ -119,7 +121,7 @@ function Bookmarks() //{{{ } // also update bookmark cache, if we removed at least one bookmark - if(deleted > 0) + if (deleted > 0) load(); return deleted; @@ -130,7 +132,7 @@ function Bookmarks() //{{{ { var search_engines = new Array(); var firefox_engines = search_service.getVisibleEngines({ }); - for(var i in firefox_engines) + for (var i in firefox_engines) { if (!firefox_engines[i].alias || !firefox_engines[i].alias.match(/^[a-z0-9_]+$/)) { @@ -147,7 +149,7 @@ function Bookmarks() //{{{ // [keyword, helptext, url] this.getKeywords = function() { - if(!keywords) + if (!keywords) load(); return keywords; @@ -158,26 +160,26 @@ function Bookmarks() //{{{ this.getSearchURL = function(text, engine_name) { var url = null; - if(!engine_name || engine_name == "") + if (!engine_name || engine_name == "") engine_name = vimperator.options["defsearch"]; // first checks the search engines for a match var engine = search_service.getEngineByAlias(engine_name); - if(engine) + if (engine) { - if(text) + if (text) url = engine.getSubmission(text, null).uri.spec; else url = engine.searchForm; } else // check for keyword urls { - if(!keywords) + if (!keywords) load(); for (var i in keywords) { - if(keywords[i][0] == engine_name) + if (keywords[i][0] == engine_name) { if (text == null) text = ""; @@ -213,11 +215,11 @@ function Bookmarks() //{{{ var match_title = null; var match_url = null; - while(!str.match(/^\s*$/)) + while (!str.match(/^\s*$/)) { /* first check for --tags */ match_tags = str.match(re_tags); - if(match_tags != null) + if (match_tags != null) { str = match_tags[match_tags.length-1]; // the last captured parenthesis is the rest of the string tags = match_tags[3].split(","); @@ -227,7 +229,7 @@ function Bookmarks() //{{{ { match_title = str.match(re_title); - if(match_title != null) + if (match_title != null) { // only one title allowed if (res.title != null) @@ -235,7 +237,7 @@ function Bookmarks() //{{{ str = match_title[match_title.length-1]; // the last captured parenthesis is the rest of the string var title = match_title[3]; - if(title.charAt(0) == '"') + if (title.charAt(0) == '"') title = title.substring(1,title.length-1); res.title = title; } @@ -250,7 +252,7 @@ function Bookmarks() //{{{ str = match_url[match_url.length-1]; // the last captured parenthesis is the rest of the string url = match_url[1]; - if(url.charAt(0) == '"') + if (url.charAt(0) == '"') url = url.substring(1,url.length-1); res.url = url; } @@ -269,6 +271,7 @@ function History() //{{{ //////////////////////////////////////////////////////////////////////////////// ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ + const rdf_service = Components.classes["@mozilla.org/rdf/rdf-service;1"]. getService( Components.interfaces.nsIRDFService ); const global_history_service = Components.classes["@mozilla.org/browser/global-history;2"]. @@ -276,7 +279,7 @@ function History() //{{{ var history = null; - if(vimperator.options["preload"]) + if (vimperator.options["preload"]) setTimeout(function() { load(); } , 100); function load() @@ -310,7 +313,7 @@ function History() //{{{ continue; var titleLiteral = titleRes.QueryInterface(Components.interfaces.nsIRDFLiteral); - if(titleLiteral) + if (titleLiteral) title = titleLiteral.Value; else title = ""; @@ -318,9 +321,11 @@ function History() //{{{ history.push([url, title]); } } + /////////////////////////////////////////////////////////////////////////////}}} ////////////////////// PUBLIC SECTION ////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ + /* * @return a new Array() of our bookmarks */ @@ -334,7 +339,7 @@ function History() //{{{ this.add = function (url, title) { - if(!history) + if (!history) load(); history = history.filter(function(elem) { @@ -384,7 +389,7 @@ function Marks() //{{{ { if (local_marks[mark][i].location == win.location.href) { - vimperator.log("Deleting local mark: " + mark + " | " + local_marks[mark][i].location + " | (" + local_marks[mark][i].position.x + ", " + local_marks[mark][i].position.y + ") | tab: " + vimperator.tabs.index(local_marks[mark][i].tab)); + vimperator.log("Deleting local mark: " + mark + " | " + local_marks[mark][i].location + " | (" + local_marks[mark][i].position.x + ", " + local_marks[mark][i].position.y + ") | tab: " + vimperator.tabs.index(local_marks[mark][i].tab), 5); local_marks[mark].splice(i, 1); if (local_marks[mark].length == 0) delete local_marks[mark]; @@ -398,7 +403,7 @@ function Marks() //{{{ { if (mark in url_marks) { - vimperator.log("Deleting URL mark: " + mark + " | " + url_marks[mark].location + " | (" + url_marks[mark].position.x + ", " + url_marks[mark].position.y + ") | tab: " + vimperator.tabs.index(url_marks[mark].tab)); + vimperator.log("Deleting URL mark: " + mark + " | " + url_marks[mark].location + " | (" + url_marks[mark].position.x + ", " + url_marks[mark].position.y + ") | tab: " + vimperator.tabs.index(url_marks[mark].tab), 5); delete url_marks[mark]; } } @@ -413,6 +418,37 @@ function Marks() //{{{ return /^[A-Z0-9]$/.test(mark); } + function getSortedMarks() + { + // local marks + var lmarks = []; + for (var mark in local_marks) + { + for (var i = 0; i < local_marks[mark].length; i++) + { + if (local_marks[mark][i].location == window.content.location.href) + lmarks.push([mark, local_marks[mark][i]]); + } + } + lmarks.sort(); + + // 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; + return 0 + }); + + return lmarks.concat(umarks); + } + /////////////////////////////////////////////////////////////////////////////}}} ////////////////////// PUBLIC SECTION ////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ @@ -433,7 +469,7 @@ function Marks() //{{{ 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())); + vimperator.log("Adding URL mark: " + mark + " | " + win.location.href + " | (" + position.x + ", " + position.y + ") | tab: " + vimperator.tabs.index(vimperator.tabs.getTab()), 5); url_marks[mark] = { location: win.location.href, position: position, tab: vimperator.tabs.getTab() }; } else if (isLocalMark(mark)) @@ -442,12 +478,12 @@ function Marks() //{{{ removeLocalMark(mark); if (!local_marks[mark]) local_marks[mark] = []; - vimperator.log("Adding local mark: " + mark + " | " + win.location.href + " | (" + position.x + ", " + position.y + ")"); + vimperator.log("Adding local mark: " + mark + " | " + win.location.href + " | (" + position.x + ", " + position.y + ")", 5); local_marks[mark].push({ location: win.location.href, position: position }); } } - this.remove = function(marks_str, special) + this.remove = function(filter, special) { if (special) { @@ -457,7 +493,7 @@ function Marks() //{{{ } else { - var pattern = new RegExp("[" + marks_str.replace(/\s+/g, '') + "]"); + var pattern = new RegExp("[" + filter.replace(/\s+/g, '') + "]"); for (var mark in url_marks) { if (pattern.test(mark)) @@ -498,7 +534,7 @@ function Marks() //{{{ win.location.href = slice.location; return; } - vimperator.log("Jumping to URL mark: " + mark + " | " + slice.location + " | (" + slice.position.x + ", " + slice.position.y + ") | tab: " + vimperator.tabs.index(slice.tab)); + vimperator.log("Jumping to URL mark: " + mark + " | " + slice.location + " | (" + slice.position.x + ", " + slice.position.y + ") | tab: " + vimperator.tabs.index(slice.tab), 5); win.scrollTo(slice.position.x * win.scrollMaxX, slice.position.y * win.scrollMaxY); ok = true; } @@ -512,7 +548,7 @@ function Marks() //{{{ { if (win.location.href == slice[i].location) { - vimperator.log("Jumping to local mark: " + mark + " | " + slice[i].location + " | (" + slice[i].position.x + ", " + slice[i].position.y + ")"); + vimperator.log("Jumping to local mark: " + mark + " | " + slice[i].location + " | (" + slice[i].position.x + ", " + slice[i].position.y + ")", 5); win.scrollTo(slice[i].position.x * win.scrollMaxX, slice[i].position.y * win.scrollMaxY); ok = true; } @@ -523,32 +559,41 @@ function Marks() //{{{ vimperator.echoerr("E20: Mark not set"); // FIXME: move up? } - // TODO: show marks like vim does (when the multiline echo impl is done) or in the preview window right now - this.list = function() + this.list = function(filter) { - // FIXME: hashes don't have a .length property --mst -// if (local_marks.length + url_marks.length < 1) -// { -// vimperator.echoerr("No marks defined"); -// return; -// } + var marks = getSortedMarks(); + + if (marks.length == 0) + { + 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 marks matching \"" + filter + "\""); + return; + } + } var list = ""; - for (var i in local_marks) + for (var i = 0; i < marks.length; i++) { - list += ""; - } - for (var j in url_marks) - { - list += ""; + list += "" + + "" + + "" + + "" + + "" + + ""; } list += "
marklinecolfile
 " + i + "" - + Math.round(local_marks[i][0].position.y *100)+ "%" - + Math.round(local_marks[i][0].position.x *100)+ "%" - + local_marks[i][0].location + "
 " + j + "" - + Math.round(url_marks[j].position.y *100)+ "%" - + Math.round(url_marks[j].position.x *100)+ "%" - + url_marks[j].location + "
 " + marks[i][0] + "" + Math.round(marks[i][1].position.y * 100) + "%" + Math.round(marks[i][1].position.x * 100) + "%" + marks[i][1].location + "
"; + vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way } //}}} @@ -561,11 +606,11 @@ function QuickMarks() //{{{ /////////////////////////////////////////////////////////////////////////////{{{ var marks = {}; - // load the commandline history -- TODO: change to sqlite + // 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) + for (var i = 0; i < saved_marks.length - 1; i += 2) { - marks[saved_marks[i]] = saved_marks[i+1]; + marks[saved_marks[i]] = saved_marks[i + 1]; } /////////////////////////////////////////////////////////////////////////////}}} @@ -577,9 +622,9 @@ function QuickMarks() //{{{ marks[mark] = location; } - this.remove = function(marks_str) + this.remove = function(filter) { - var pattern = new RegExp("[" + marks_str.replace(/\s+/g, '') + "]"); + var pattern = new RegExp("[" + filter.replace(/\s+/g, '') + "]"); for (var mark in marks) { if (pattern.test(mark)) @@ -592,7 +637,7 @@ function QuickMarks() //{{{ var url = marks[mark]; if (url) { - if(newtab) + if (newtab) openURLsInNewTab(url, true); else openURLs(url); @@ -603,21 +648,20 @@ function QuickMarks() //{{{ this.list = function() { - // FIXME: hashes don't have a .length property --mst -// if (local_marks.length + url_marks.length < 1) -// { -// vimperator.echoerr("No marks defined"); -// return; -// } - + var is_empty = true; var list = ""; for (var i in marks) { + is_empty = false; list += ""; } list += "
markURL
 " + i + "" + marks[i] + "
"; - vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way + + if (!is_empty) + vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way + else + vimperator.echoerr("No quickmarks defined"); } this.destroy = function() @@ -633,4 +677,5 @@ function QuickMarks() //{{{ } //}}} } //}}} + // vim: set fdm=marker sw=4 ts=4 et: diff --git a/chrome/content/vimperator/commands.js b/chrome/content/vimperator/commands.js index ca12d30b..6449d5d8 100644 --- a/chrome/content/vimperator/commands.js +++ b/chrome/content/vimperator/commands.js @@ -515,7 +515,13 @@ function Commands() //{{{ )); addDefaultCommand(new Command(["marks"], function(args) { - vimperator.marks.list(args) + if (args.length > 1 && !/[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}"],