grep その3
grep 更新しました
主に標準の検索っぽくしました。
- 標準の検索のように 選択を緑っぽい色に変更
- use_highlight_option
true で option に h を 追加
実行時に全ての結果 を マゼンダ っぽい 色で選択
- typo を修正
- 「nN」の移動を 現状フォーカス位置から開始するように変更
- highlight を 消す「cleargrep」コマンドを追加
highlightのマゼンダは、目が痛いです。
これ変更する方法あるのでしょうか?
コード
全文
差分
diff -r 66b576f6fade grep.js --- a/grep.js Mon Jan 25 22:38:12 2010 +0900 +++ b/grep.js Sun Jan 31 23:58:34 2010 +0900 @@ -7,14 +7,17 @@ const grep_info_attr = "__vmp_grep_cmd"; const use_hook_search_map = true; const use_show_echo = false; + const use_highlight_option = true; var screen_position = [50, -1];//[垂直,水平] - var default_option = liberator.globalVariables.vimp_grep_default_option|| "imx"; + var default_option = liberator.globalVariables.vimp_grep_default_option|| "imxh"; //{{{core const vimp = "liberator-completions"; var finder = Cc["@mozilla.org/embedcomp/rangefind;1"] .getService(Ci.nsIFind); - const option_list = "imxnr"; + const option_list = "imxnr" + (use_highlight_option ? "h" : ""); + const gFm = Cc["@mozilla.org/focus-manager;1"] + .getService(Ci.nsIFocusManager); //}}} //}}} @@ -129,7 +132,6 @@ for([,w] in Iterator(words)){ list = list.concat(normal_find(win, w)); } - //list.sort(function(a,b) a.compareBoundaryPoints(Range.START_TOSTART, b)); list.sort(range_compare); ret = ret.concat(list); } @@ -147,22 +149,38 @@ //}}} function range_compare(a,b) - a.compareBoundaryPoints(Range.START_TOSTART, b) - || a.compareBoundaryPoints(Range.END_TOEND, b) + a.compareBoundaryPoints(Range.START_TO_START, b) + || a.compareBoundaryPoints(Range.END_TO_END, b) + + function range_compare_d(win){ + win = win || content.window; + let list = [w.document for(w in iteratorFrame(win))]; + return function(a,b){ + var n1 = a.startContainer.ownerDocument; + var n2 = b.startContainer.ownerDocument; + + if(n1 === n2) return a.compareBoundaryPoints(Range.START_TO_START, b) + || a.compareBoundaryPoints(Range.END_TO_END, b); + var ret=0; + for(let [,n] in Iterator(list)){ + if(n===n1) return -1; + else if(n===n2) return 1; + } + }; + } var mode_func = { }; mode_func.n = normal_grep; mode_func.r = regexp_grep; mode_func.x = migemo_grep; - //{{{ range cache function get_cache(){ return content.document[grep_info_attr]; } function get_grep_info(arg){ - let m,word,flags,mode,num; + let m,word,flags,mode,num,opt; let re = new RegExp( <>^((\d*)([{option_list}]*)/)?([^/]+)(/([{option_list}]*))?$</>.toString() ,"i"); @@ -178,16 +196,18 @@ s = m[3]; } flags = ""; + opt = ""; if(/i/.test(s)) flags += "i"; if(/m/.test(s)) flags += "m"; + if(/h/.test(s)) opt += "h"; if(m=/.+([xnr])/.exec("n"+default_option+s)){ mode = m[1]; } } - var query = <>{flags}{mode}/{word}</>.toString(); + let option = <>{flags}{mode}{opt}</>.toString(); var info = get_cache(); if(info){ - if(info.query === query){ + if(info.word === word && info.option === option){ info.index = num; info.enabled = false; return info; @@ -201,14 +221,24 @@ } var list = func(word, flags + "g"); - info = {list:list, index:num, query: query, enabled:false}; + info = {list:list, index:num, word: word, option: option}; content.document[grep_info_attr] = info; return info; } + function getSelectionController(view){ + return view + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShell) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsISelectionDisplay) + .QueryInterface(Ci.nsISelectionController); + } + function grep_jump(info){ if(info.list.length == 0){ - liberator.echoerr(<>no match "{info.query}"</>); + liberator.echoerr(<>no match "{info.option}/{info.word}"</>); return; } var n = info.list[info.index]; @@ -217,16 +247,29 @@ return; } var win = n.startContainer.ownerDocument.defaultView; - var selection = win.getSelection(); + + if(gFm.focusedWindow){ + gFm.focusedWindow.getSelection().removeAllRanges(); + } + var selection = getSelectionController(win) + .getSelection(Ci.nsISelectionController.SELECTION_NORMAL); selection.removeAllRanges(); selection.addRange(n); + { + gFm.moveFocus(win, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, + Ci.nsIFocusManager.FLAG_NOSCROLL | Ci.nsIFocusManager.FLAG_NOSWITCHFRAME); + + let ctrl = getSelectionController(win); + ctrl.setDisplaySelection(Ci.nsISelectionController.SELECTION_ATTENTION); + ctrl.repaintSelection(Ci.nsISelectionController.SELECTION_NORMAL); + } info.enabled = true; selection .QueryInterface(Ci.nsISelection2) .scrollIntoView(Ci.nsISelectionController.SELECTION_ANCHOR_REGION,true,screen_position[0],screen_position[1]); - //.scrollIntoView(Ci.nsISelectionController.SELECTION_FOCUS_REGION,true,50,50) + win.focus();// nsIFocusManager の focusedWindow を 更新 if(use_show_echo){ range2string.max = get_word_max(); @@ -234,9 +277,46 @@ } } + function bi_search(list, n, isReverse){ + var lhs = 0,rhs = list.length,mid=0,ret; + var comp = range_compare_d(content.window); + while(1){ + if(mid===(mid=Math.floor((lhs+rhs)/2))){ + if(mid === 0 && ret < 0) return -1; + else if(mid === list.length-1 && ret > 0 && !isReverse) return mid+1; + else return mid; + } + ret = comp(n, list[mid]); + if(ret < 0) rhs = mid; + else if(ret > 0) lhs = mid; + else{ + return isReverse ? mid - 1 : mid; + } + } + } + + function get_grep_list_index(info, isReverse){ + info = info || get_cache(); + + let win = gFm.focusedWindow; + let selection = win.getSelection(); + let r; + if(selection.rangeCount === 0){ + r = win.document.createRange(); + r.setStart(win.document.body, 0); + }else{ + r = selection.getRangeAt(0); + } + let index = bi_search(info.list, r, isReverse); + + return index; + } + function grep_next(){ var info = get_cache(); if(!info) return; + info.index = get_grep_list_index(info); + if(++info.index >= info.list.length){ info.index = 0; liberator.echoerr("bottom!"); @@ -245,25 +325,56 @@ return true; } + function grep_prev(){ var info = get_cache(); if(!info) return; - if(--info.index < 0){ + info.index = get_grep_list_index(info, true); + if(info.index < 0){ info.index = info.list.length-1; liberator.echoerr("top!"); } - grep_jump(info); + grep_jump(info); return true; } //}}} + //{{{ highlight + function show_highlight(list){ + for(let [,r] in Iterator(list)){ + let selection = getSelectionController(r.startContainer.ownerDocument.defaultView) + .getSelection(Ci.nsISelectionController.SELECTION_FIND); + selection.addRange(r); + } + } + + function clear_selection_find(win){ + win = win||content.window; + var selection = getSelectionController(win) + .getSelection(Ci.nsISelectionController.SELECTION_FIND); + if(selection) selection.removeAllRanges(); + } + + function clear_highlight(){ + for(let w in iteratorFrame(content.window)){ + clear_selection_find(w); + } + } + //}}} + var T={ name : cmd_name , desc :"grep page", action:function(args){ var info = get_grep_info(args[0]); - if(info) grep_jump(info); + if(info){ + if(/h/.test(info.option)){ + clear_highlight(); + show_highlight(info.list); + } + grep_jump(info); + } }, option:{ } }; @@ -283,7 +394,7 @@ var query = info.query; context.completions = info.list.map(function(n,i){ return { - text: <>{i}{query}</>.toString(), + text: <>{i}{info.option}/{info.word}</>.toString(), range: n } }); @@ -332,4 +443,12 @@ } }); } //}}} + if(use_highlight_option)//{{{ + { + function clear_action(){ + clear_highlight(); + } + + commands.addUserCommand(["cleargrep","cgrep"],"clear grep highlight", function() clear_action(), null, true); + }//}}} })();