diff options
Diffstat (limited to 'common/content/finder.js')
-rw-r--r-- | common/content/finder.js | 815 |
1 files changed, 388 insertions, 427 deletions
diff --git a/common/content/finder.js b/common/content/finder.js index 36660945..33334036 100644 --- a/common/content/finder.js +++ b/common/content/finder.js @@ -13,70 +13,192 @@ // : 'linksearch' searches should highlight link matches only // : changing any search settings should also update the search state including highlighting // : incremental searches shouldn't permanently update search modifiers +// +// TODO: Clean up this rat's nest. --Kris /** * @instance finder */ -function Finder() //{{{ -{ - //////////////////////////////////////////////////////////////////////////////// - ////////////////////// PRIVATE SECTION ///////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - var found = false; // true if the last search was successful - var backwards = false; // currently searching backwards - var searchString = ""; // current search string (without modifiers) - var searchPattern = ""; // current search string (includes modifiers) - var lastSearchPattern = ""; // the last searched pattern (includes modifiers) - var lastSearchString = ""; // the last searched string (without modifiers) - var lastSearchBackwards = false; // like "backwards", but for the last search, so if you cancel a search with <esc> this is not set - var caseSensitive = false; // search string is case sensitive - var linksOnly = false; // search is limited to link text only - - // Event handlers for search - closure is needed - commandline.registerCallback("change", modes.SEARCH_FORWARD, function (str) { finder.onKeyPress(str); }); - commandline.registerCallback("submit", modes.SEARCH_FORWARD, function (str) { finder.onSubmit(str); }); - commandline.registerCallback("cancel", modes.SEARCH_FORWARD, function () { finder.onCancel(); }); - // TODO: allow advanced myModes in register/triggerCallback - commandline.registerCallback("change", modes.SEARCH_BACKWARD, function (str) { finder.onKeyPress(str); }); - commandline.registerCallback("submit", modes.SEARCH_BACKWARD, function (str) { finder.onSubmit(str); }); - commandline.registerCallback("cancel", modes.SEARCH_BACKWARD, function () { finder.onCancel(); }); +const Finder = Module("finder", { + init: function () { + const self = this; + + this._found = false; // true if the last search was successful + this._backwards = false; // currently searching backwards + this._searchString = ""; // current search string (without modifiers) + this._searchPattern = ""; // current search string (includes modifiers) + this._lastSearchPattern = ""; // the last searched pattern (includes modifiers) + this._lastSearchString = ""; // the last searched string (without modifiers) + this._lastSearchBackwards = false; // like "backwards", but for the last search, so if you cancel a search with <esc> this is not set + this._caseSensitive = false; // search string is case sensitive + this._linksOnly = false; // search is limited to link text only + + /* Stolen from toolkit.jar in Firefox, for the time being. The private + * methods were unstable, and changed. The new version is not remotely + * compatible with what we do. + * The following only applies to this object, and may not be + * necessary, or accurate, but, just in case: + * The Original Code is mozilla.org viewsource frontend. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (c) 2003 + * by the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Blake Ross <blake@cs.stanford.edu> (Original Author) + * Masayuki Nakano <masayuki@d-toybox.com> + * Ben Basson <contact@cusser.net> + * Jason Barnabe <jason_barnabe@fastmail.fm> + * Asaf Romano <mano@mozilla.com> + * Ehsan Akhgari <ehsan.akhgari@gmail.com> + * Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk> + */ + this._highlighter = { + + doc: null, + + spans: [], + + search: function (aWord, matchCase) { + var finder = services.create("find"); + if (matchCase !== undefined) + self._caseSensitive = matchCase; + + var range; + while ((range = finder.Find(aWord, this.searchRange, this.startPt, this.endPt))) + yield range; + }, + + highlightDoc: function highlightDoc(win, aWord) { + this.doc = content.document; // XXX + Array.forEach(win.frames, function (frame) this._highlighter.highlightDoc(frame, aWord)); + + var doc = win.document; + if (!doc || !(doc instanceof HTMLDocument)) + return; + + if (!aWord) { + let elems = this._highlighter.spans; + for (let i = elems.length; --i >= 0;) { + let elem = elems[i]; + let docfrag = doc.createDocumentFragment(); + let next = elem.nextSibling; + let parent = elem.parentNode; + + let child; + while (child = elem.firstChild) + docfrag.appendChild(child); + + parent.removeChild(elem); + parent.insertBefore(docfrag, next); + parent.normalize(); + } + return; + } + + var baseNode = <span highlight="Search"/>; + baseNode = util.xmlToDom(baseNode, window.content.document); + + var body = doc.body; + var count = body.childNodes.length; + this.searchRange = doc.createRange(); + this.startPt = doc.createRange(); + this.endPt = doc.createRange(); + + this.searchRange.setStart(body, 0); + this.searchRange.setEnd(body, count); + + this.startPt.setStart(body, 0); + this.startPt.setEnd(body, 0); + this.endPt.setStart(body, count); + this.endPt.setEnd(body, count); + + liberator.interrupted = false; + let n = 0; + for (let retRange in this.search(aWord, this._caseSensitive)) { + // Highlight + var nodeSurround = baseNode.cloneNode(true); + var node = this.highlight(retRange, nodeSurround); + this.startPt = node.ownerDocument.createRange(); + this.startPt.setStart(node, node.childNodes.length); + this.startPt.setEnd(node, node.childNodes.length); + if (n++ % 20 == 0) + liberator.threadYield(true); + if (liberator.interrupted) + break; + } + }, + + highlight: function highlight(aRange, aNode) { + var startContainer = aRange.startContainer; + var startOffset = aRange.startOffset; + var endOffset = aRange.endOffset; + var docfrag = aRange.extractContents(); + var before = startContainer.splitText(startOffset); + var parent = before.parentNode; + aNode.appendChild(docfrag); + parent.insertBefore(aNode, before); + this.spans.push(aNode); + return aNode; + }, + + /** + * Clears all search highlighting. + */ + clear: function () { + this.spans.forEach(function (span) { + if (span.parentNode) { + let el = span.firstChild; + while (el) { + span.removeChild(el); + span.parentNode.insertBefore(el, span); + el = span.firstChild; + } + span.parentNode.removeChild(span); + } + }); + this.spans = []; + }, + + isHighlighted: function (doc) this.doc == doc && this.spans.length > 0 + }; + }, // set searchString, searchPattern, caseSensitive, linksOnly - function processUserPattern(pattern) - { + processUserPattern: function (pattern) { //// strip off pattern terminator and offset //if (backwards) // pattern = pattern.replace(/\?.*/, ""); //else // pattern = pattern.replace(/\/.*/, ""); - searchPattern = pattern; + this._searchPattern = pattern; // links only search - \l wins if both modifiers specified if (/\\l/.test(pattern)) - linksOnly = true; + this._linksOnly = true; else if (/\L/.test(pattern)) - linksOnly = false; + this._linksOnly = false; else if (options["linksearch"]) - linksOnly = true; + this._linksOnly = true; else - linksOnly = false; + this._linksOnly = false; // strip links-only modifiers pattern = pattern.replace(/(\\)?\\[lL]/g, function ($0, $1) { return $1 ? $0 : ""; }); // case sensitivity - \c wins if both modifiers specified if (/\c/.test(pattern)) - caseSensitive = false; + this._caseSensitive = false; else if (/\C/.test(pattern)) - caseSensitive = true; + this._caseSensitive = true; else if (options["ignorecase"] && options["smartcase"] && /[A-Z]/.test(pattern)) - caseSensitive = true; + this._caseSensitive = true; else if (options["ignorecase"]) - caseSensitive = false; + this._caseSensitive = false; else - caseSensitive = true; + this._caseSensitive = true; // strip case-sensitive modifiers pattern = pattern.replace(/(\\)?\\[cC]/g, function ($0, $1) { return $1 ? $0 : ""; }); @@ -84,414 +206,253 @@ function Finder() //{{{ // remove any modifier escape \ pattern = pattern.replace(/\\(\\[cClL])/g, "$1"); - searchString = pattern; - } + this._searchString = pattern; + }, - /* Stolen from toolkit.jar in Firefox, for the time being. The private - * methods were unstable, and changed. The new version is not remotely - * compatible with what we do. - * The following only applies to this object, and may not be - * necessary, or accurate, but, just in case: - * The Original Code is mozilla.org viewsource frontend. + /** + * Called when the search dialog is requested. * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (c) 2003 - * by the Initial Developer. All Rights Reserved. + * @param {number} mode The search mode, either modes.SEARCH_FORWARD or + * modes.SEARCH_BACKWARD. + * @default modes.SEARCH_FORWARD + */ + openPrompt: function (mode) { + this._backwards = mode == modes.SEARCH_BACKWARD; + commandline.open(this._backwards ? "?" : "/", "", mode); + // TODO: focus the top of the currently visible screen + }, + + // TODO: backwards seems impossible i fear :( + /** + * Searches the current buffer for <b>str</b>. * - * Contributor(s): - * Blake Ross <blake@cs.stanford.edu> (Original Author) - * Masayuki Nakano <masayuki@d-toybox.com> - * Ben Basson <contact@cusser.net> - * Jason Barnabe <jason_barnabe@fastmail.fm> - * Asaf Romano <mano@mozilla.com> - * Ehsan Akhgari <ehsan.akhgari@gmail.com> - * Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk> + * @param {string} str The string to find. */ - var highlighter = { - - doc: null, - - spans: [], - - search: function (aWord, matchCase) - { - var finder = services.create("find"); - if (matchCase !== undefined) - finder.caseSensitive = matchCase; - - var range; - while ((range = finder.Find(aWord, this.searchRange, this.startPt, this.endPt))) - yield range; - }, - - highlightDoc: function highlightDoc(win, aWord) - { - this.doc = content.document; // XXX - Array.forEach(win.frames, function (frame) highlighter.highlightDoc(frame, aWord)); - - var doc = win.document; - if (!doc || !(doc instanceof HTMLDocument)) - return; - - if (!aWord) - { - let elems = highlighter.spans; - for (let i = elems.length; --i >= 0;) - { - let elem = elems[i]; - let docfrag = doc.createDocumentFragment(); - let next = elem.nextSibling; - let parent = elem.parentNode; - - let child; - while (child = elem.firstChild) - docfrag.appendChild(child); - - parent.removeChild(elem); - parent.insertBefore(docfrag, next); - parent.normalize(); - } - return; - } - - var baseNode = <span highlight="Search"/>; - baseNode = util.xmlToDom(baseNode, window.content.document); - - var body = doc.body; - var count = body.childNodes.length; - this.searchRange = doc.createRange(); - this.startPt = doc.createRange(); - this.endPt = doc.createRange(); - - this.searchRange.setStart(body, 0); - this.searchRange.setEnd(body, count); - - this.startPt.setStart(body, 0); - this.startPt.setEnd(body, 0); - this.endPt.setStart(body, count); - this.endPt.setEnd(body, count); - - liberator.interrupted = false; - let n = 0; - for (let retRange in this.search(aWord, caseSensitive)) - { - // Highlight - var nodeSurround = baseNode.cloneNode(true); - var node = this.highlight(retRange, nodeSurround); - this.startPt = node.ownerDocument.createRange(); - this.startPt.setStart(node, node.childNodes.length); - this.startPt.setEnd(node, node.childNodes.length); - if (n++ % 20 == 0) - liberator.threadYield(true); - if (liberator.interrupted) - break; - } - }, - - highlight: function highlight(aRange, aNode) - { - var startContainer = aRange.startContainer; - var startOffset = aRange.startOffset; - var endOffset = aRange.endOffset; - var docfrag = aRange.extractContents(); - var before = startContainer.splitText(startOffset); - var parent = before.parentNode; - aNode.appendChild(docfrag); - parent.insertBefore(aNode, before); - this.spans.push(aNode); - return aNode; - }, - - /** - * Clears all search highlighting. - */ - clear: function () - { - this.spans.forEach(function (span) - { - if (span.parentNode) - { - let el = span.firstChild; - while (el) - { - span.removeChild(el); - span.parentNode.insertBefore(el, span); - el = span.firstChild; - } - span.parentNode.removeChild(span); - } - }); - this.spans = []; - }, - - isHighlighted: function (doc) this.doc == doc && this.spans.length > 0 - }; - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// OPTIONS ///////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - options.add(["hlsearch", "hls"], - "Highlight previous search pattern matches", - "boolean", "false", - { - setter: function (value) - { - if (value) - finder.highlight(); - else - finder.clear(); - - return value; - } - }); - - options.add(["ignorecase", "ic"], - "Ignore case in search patterns", - "boolean", true); - - options.add(["incsearch", "is"], - "Show where the search pattern matches as it is typed", - "boolean", true); - - options.add(["linksearch", "lks"], - "Limit the search to hyperlink text", - "boolean", false); - - options.add(["smartcase", "scs"], - "Override the 'ignorecase' option if the pattern contains uppercase characters", - "boolean", true); - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// MAPPINGS //////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - var myModes = config.browserModes; - myModes = myModes.concat([modes.CARET]); - - mappings.add(myModes, - ["/"], "Search forward for a pattern", - function () { finder.openPrompt(modes.SEARCH_FORWARD); }); - - mappings.add(myModes, - ["?"], "Search backwards for a pattern", - function () { finder.openPrompt(modes.SEARCH_BACKWARD); }); - - mappings.add(myModes, - ["n"], "Find next", - function () { finder.findAgain(false); }); - - mappings.add(myModes, - ["N"], "Find previous", - function () { finder.findAgain(true); }); - - mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["*"], - "Find word under cursor", - function () - { - found = false; - finder.onSubmit(buffer.getCurrentWord(), false); - }); - - mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["#"], - "Find word under cursor backwards", - function () - { - found = false; - finder.onSubmit(buffer.getCurrentWord(), true); - }); - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// COMMANDS //////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - commands.add(["noh[lsearch]"], - "Remove the search highlighting", - function () { finder.clear(); }, - { argCount: "0" }); - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// PUBLIC SECTION ////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - return { - - /** - * Called when the search dialog is requested. - * - * @param {number} mode The search mode, either modes.SEARCH_FORWARD or - * modes.SEARCH_BACKWARD. - * @default modes.SEARCH_FORWARD - */ - openPrompt: function (mode) - { - backwards = mode == modes.SEARCH_BACKWARD; - commandline.open(backwards ? "?" : "/", "", mode); - // TODO: focus the top of the currently visible screen - }, - - // TODO: backwards seems impossible i fear :( - /** - * Searches the current buffer for <b>str</b>. - * - * @param {string} str The string to find. - */ - find: function (str) - { - let fastFind = getBrowser().fastFind; + find: function (str) { + let fastFind = getBrowser().fastFind; - processUserPattern(str); - fastFind.caseSensitive = caseSensitive; - found = fastFind.find(searchString, linksOnly) != Ci.nsITypeAheadFind.FIND_NOTFOUND; + this._processUserPattern(str); + fastFind.caseSensitive = this._caseSensitive; + this._found = fastFind.find(this._searchString, this._linksOnly) != Ci.nsITypeAheadFind.FIND_NOTFOUND; - if (!found) - setTimeout(function () liberator.echoerr("E486: Pattern not found: " + searchPattern, commandline.FORCE_SINGLELINE), 0); - }, + if (!this._found) + setTimeout(function () liberator.echoerr("E486: Pattern not found: " + this._searchPattern, commandline.FORCE_SINGLELINE), 0); + }, - /** - * Searches the current buffer again for the most recently used search - * string. - * - * @param {boolean} reverse Whether to search forwards or backwards. - * @default false - */ - findAgain: function (reverse) - { - // This hack is needed to make n/N work with the correct string, if - // we typed /foo<esc> after the original search. Since searchString is - // readonly we have to call find() again to update it. - if (getBrowser().fastFind.searchString != lastSearchString) - this.find(lastSearchString); - - let up = reverse ? !lastSearchBackwards : lastSearchBackwards; - let result = getBrowser().fastFind.findAgain(up, linksOnly); - - if (result == Ci.nsITypeAheadFind.FIND_NOTFOUND) - liberator.echoerr("E486: Pattern not found: " + lastSearchPattern, commandline.FORCE_SINGLELINE); - else if (result == Ci.nsITypeAheadFind.FIND_WRAPPED) - { - // hack needed, because wrapping causes a "scroll" event which clears - // our command line - setTimeout(function () { - let msg = up ? "search hit TOP, continuing at BOTTOM" : "search hit BOTTOM, continuing at TOP"; - commandline.echo(msg, commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES | commandline.FORCE_SINGLELINE); - }, 0); - } - else - { - commandline.echo((up ? "?" : "/") + lastSearchPattern, null, commandline.FORCE_SINGLELINE); - - if (options["hlsearch"]) - this.highlight(lastSearchString); - } - }, - - /** - * Called when the user types a key in the search dialog. Triggers a - * search attempt if 'incsearch' is set. - * - * @param {string} str The search string. - */ - onKeyPress: function (str) - { - if (options["incsearch"]) - this.find(str); - }, - - /** - * Called when the <Enter> key is pressed to trigger a search. - * - * @param {string} str The search string. - * @param {boolean} forcedBackward Whether to search forwards or - * backwards. This overrides the direction set in - * (@link #openPrompt). - * @default false - */ - onSubmit: function (str, forcedBackward) - { - if (typeof forcedBackward === "boolean") - backwards = forcedBackward; - - if (str) - var pattern = str; - else - { - liberator.assert(lastSearchPattern, "E35: No previous search pattern"); - pattern = lastSearchPattern; - } - - this.clear(); - - if (!options["incsearch"] || !str || !found) - { - // prevent any current match from matching again - if (!window.content.getSelection().isCollapsed) - window.content.getSelection().getRangeAt(0).collapse(backwards); - - this.find(pattern); - } - - lastSearchBackwards = backwards; - //lastSearchPattern = pattern.replace(backwards ? /\?.*/ : /\/.*/, ""); // XXX - lastSearchPattern = pattern; - lastSearchString = searchString; - - // TODO: move to find() when reverse incremental searching is kludged in - // need to find again for reverse searching - if (backwards) - setTimeout(function () { finder.findAgain(false); }, 0); + /** + * Searches the current buffer again for the most recently used search + * string. + * + * @param {boolean} reverse Whether to search forwards or backwards. + * @default false + */ + findAgain: function (reverse) { + // This hack is needed to make n/N work with the correct string, if + // we typed /foo<esc> after the original search. Since searchString is + // readonly we have to call find() again to update it. + if (getBrowser().fastFind.searchString != this._lastSearchString) + this.find(this._lastSearchString); + + let up = reverse ? !this._lastSearchBackwards : this._lastSearchBackwards; + let result = getBrowser().fastFind.findAgain(up, this._linksOnly); + + if (result == Ci.nsITypeAheadFind.FIND_NOTFOUND) + liberator.echoerr("E486: Pattern not found: " + this._lastSearchPattern, commandline.FORCE_SINGLELINE); + else if (result == Ci.nsITypeAheadFind.FIND_WRAPPED) { + // hack needed, because wrapping causes a "scroll" event which clears + // our command line + setTimeout(function () { + let msg = up ? "search hit TOP, continuing at BOTTOM" : "search hit BOTTOM, continuing at TOP"; + commandline.echo(msg, commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES | commandline.FORCE_SINGLELINE); + }, 0); + } + else { + commandline.echo((up ? "?" : "/") + this._lastSearchPattern, null, commandline.FORCE_SINGLELINE); if (options["hlsearch"]) - this.highlight(searchString); + this.highlight(this._lastSearchString); + } + }, - modes.reset(); - }, + /** + * Called when the user types a key in the search dialog. Triggers a + * search attempt if 'incsearch' is set. + * + * @param {string} str The search string. + */ + onKeyPress: function (str) { + if (options["incsearch"]) + this.find(str); + }, - /** - * Called when the search is canceled. For example, if someone presses - * <Esc> while typing a search. - */ - onCancel: function () - { - // TODO: code to reposition the document to the place before search started - }, + /** + * Called when the <Enter> key is pressed to trigger a search. + * + * @param {string} str The search string. + * @param {boolean} forcedBackward Whether to search forwards or + * backwards. This overrides the direction set in + * (@link #openPrompt). + * @default false + */ + onSubmit: function (str, forcedBackward) { + if (typeof forcedBackward === "boolean") + this._backwards = forcedBackward; + + if (str) + var pattern = str; + else { + liberator.assert(this._lastSearchPattern, "E35: No previous search pattern"); + pattern = this._lastSearchPattern; + } - /** - * Highlights all occurances of <b>str</b> in the buffer. - * - * @param {string} str The string to highlight. - */ - highlight: function (str) - { - // FIXME: Thunderbird incompatible - if (config.name == "Muttator") - return; + this.clear(); - if (highlighter.isHighlighted(content.document)) - return; + if (!options["incsearch"] || !str || !this._found) { + // prevent any current match from matching again + if (!window.content.getSelection().isCollapsed) + window.content.getSelection().getRangeAt(0).collapse(this._backwards); - if (!str) - str = lastSearchString; + this.find(pattern); + } - highlighter.highlightDoc(window.content, str); + this._lastSearchBackwards = this._backwards; + //lastSearchPattern = pattern.replace(backwards ? /\?.*/ : /\/.*/, ""); // XXX + this._lastSearchPattern = pattern; + this._lastSearchString = this._searchString; - // recreate selection since highlightDoc collapses the selection - if (window.content.getSelection().isCollapsed) - getBrowser().fastFind.findAgain(backwards, linksOnly); + // TODO: move to find() when reverse incremental searching is kludged in + // need to find again for reverse searching + if (this._backwards) + setTimeout(function () { finder.findAgain(false); }, 0); - // TODO: remove highlighting from non-link matches (HTML - A/AREA with href attribute; XML - Xlink [type="simple"]) - }, + if (options["hlsearch"]) + this.highlight(this._searchString); - /** - * Clears all search highlighting. - */ - clear: function () - { - highlighter.clear(); - } - }; - //}}} -} //}}} + modes.reset(); + }, + + /** + * Called when the search is canceled. For example, if someone presses + * <Esc> while typing a search. + */ + onCancel: function () { + // TODO: code to reposition the document to the place before search started + }, + + /** + * Highlights all occurances of <b>str</b> in the buffer. + * + * @param {string} str The string to highlight. + */ + highlight: function (str) { + // FIXME: Thunderbird incompatible + if (config.name == "Muttator") + return; + + if (this._highlighter.isHighlighted(content.document)) + return; + + if (!str) + str = this._lastSearchString; + + this._highlighter.highlightDoc(window.content, str); + + // recreate selection since highlightDoc collapses the selection + if (window.content.getSelection().isCollapsed) + getBrowser().fastFind.findAgain(this._backwards, this._linksOnly); + + // TODO: remove highlighting from non-link matches (HTML - A/AREA with href attribute; XML - Xlink [type="simple"]) + }, + + /** + * Clears all search highlighting. + */ + clear: function () { + this._highlighter.clear(); + } +}, { + commandline: function () { + const self = this; + // Event handlers for search - closure is needed + commandline.registerCallback("change", modes.SEARCH_FORWARD, function (str) { self.onKeyPress(str); }); + commandline.registerCallback("submit", modes.SEARCH_FORWARD, function (str) { self.onSubmit(str); }); + commandline.registerCallback("cancel", modes.SEARCH_FORWARD, function () { self.onCancel(); }); + // TODO: allow advanced myModes in register/triggerCallback + commandline.registerCallback("change", modes.SEARCH_BACKWARD, function (str) { self.onKeyPress(str); }); + commandline.registerCallback("submit", modes.SEARCH_BACKWARD, function (str) { self.onSubmit(str); }); + commandline.registerCallback("cancel", modes.SEARCH_BACKWARD, function () { self.onCancel(); }); + + }, + commands: function () { + commands.add(["noh[lsearch]"], + "Remove the search highlighting", + function () { finder.clear(); }, + { argCount: "0" }); + }, + mappings: function () { + var myModes = config.browserModes; + myModes = myModes.concat([modes.CARET]); + + mappings.add(myModes, + ["/"], "Search forward for a pattern", + function () { finder.openPrompt(modes.SEARCH_FORWARD); }); + + mappings.add(myModes, + ["?"], "Search backwards for a pattern", + function () { finder.openPrompt(modes.SEARCH_BACKWARD); }); + + mappings.add(myModes, + ["n"], "Find next", + function () { finder.findAgain(false); }); + + mappings.add(myModes, + ["N"], "Find previous", + function () { finder.findAgain(true); }); + + mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["*"], + "Find word under cursor", + function () { + this._found = false; + finder.onSubmit(buffer.getCurrentWord(), false); + }); + + mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["#"], + "Find word under cursor backwards", + function () { + this._found = false; + finder.onSubmit(buffer.getCurrentWord(), true); + }); + }, + options: function () { + options.add(["hlsearch", "hls"], + "Highlight previous search pattern matches", + "boolean", "false", { + setter: function (value) { + if (value) + finder.highlight(); + else + finder.clear(); + + return value; + } + }); + + options.add(["ignorecase", "ic"], + "Ignore case in search patterns", + "boolean", true); + + options.add(["incsearch", "is"], + "Show where the search pattern matches as it is typed", + "boolean", true); + + options.add(["linksearch", "lks"], + "Limit the search to hyperlink text", + "boolean", false); + + options.add(["smartcase", "scs"], + "Override the 'ignorecase' option if the pattern contains uppercase characters", + "boolean", true); + }, +}); // vim: set fdm=marker sw=4 ts=4 et: |