<TAG attr="|">|</TAG>
やcss-prop:|;
のような未記入っぽい箇所1へカーソルを移動させるマクロです。
Emmet や Zen-Coding で展開後の入力サポート用です。
**マクロコード**
**下検索用**
entrySearch.js
/** 未記入箇所へ移動:マクロ *******************************
HTML・CSS系ファイル内の
<TAG attr="|">|</TAG> css-prop: |;
のような未記入箇所へカーソルを移動するマクロ。
上下セットで使用前提&使えるファイル種も限られるので、
段落/移動履歴/関数マーク等の移動系と兼用してキー割り当ての節約。
**********************************************************/
//-- 動作オプション ---------------------------------------
//検索方向 [N>0:下検索 N<0:上検索]
var MOVE_STEP = 1;
//先頭(末尾)から再検索
var LOOP_SEARCH = 0;
//空白のみの行(≠空行)も未記入箇所と見なす
var SPACE_ROW = 0;
//「.,)]」手前の空欄も未記入と見なす
var EMPTY_SEPARATE = 0;
//「見つかりませんでした。」
var NOT_FOUND = 'Entry-point not found.';
//拡張子orタイプ指定 (この拡張子と同タイプの拡張子 || この拡張子用のタイプ適用中)なら有効
var TYPES = ['html', 'css'];
//↑の指定等で無効な場合の代替動作
var DEF_FUNC = function(){
return MOVE_STEP<0?GoPrevParagraph():GoNextParagraph();//次(前)の段落へ~
};
//function put(msg){if(typeof(outp)=='undefined'){TraceOut('\r\n▼-- $t @['+ExpandParameter('$M').replace(/^.*?([^\\\/]+)$/m,'$1')+'] > $f --',1),outp=1} TraceOut((''+msg).replace(/^([\S])/gm,'\t$1'),0)}
//== メイン処理 ===========================================
function entrySearch(){
var txt=GetCookie('document','_EnTrySeArCh_ArG')||'';//外部から呼び出し用の仕込み
if(txt){MOVE_STEP=txt-0; DeleteCookie('document','_EnTrySeArCh_ArG')}
if(typeof(TYPES)!=='undefined' && (TYPES instanceof Array) && TYPES.length){//拡張子&タイプ判定
var ext=ExpandParameter('$b');
for(var i=0; i<TYPES.length; i++){if(IsSameTypeExt(TYPES[i],ext) || IsCurTypeExt(TYPES[i])){ext='ok!?'}}
if(ext!=='ok!?'){return null}
}
var ms=MOVE_STEP, mm=ms<0?-1:ms>0?1:0; if(!mm){return null}
var cx=ExpandParameter('$x')-0, cy=ny=ExpandParameter('$y')-1, ly=GetLineCount(0);
var re=[ //探索用の正規表現
/^((.*?\<[ \t]*(\w+)\b[^\>]*?\>)\<\/[ \t]*\3\b[^\>]*?\>)(.*)$/im, // <TAG>|</TAG>
/^((.*?([\"\']))\3)(.*)$/im, // attr="|"
/^((.*?(\w+)[ \t]*\:[ \t]*)[\,\;\}])(.*)$/im // prop: |;
],
re_e=[ //区切り空欄
/^(((.*?[\,\.\(\[])[ \t]*))([\.\,\)\]].*)$/im, // , |,
/^((.*?([\'\"])[ \t]*)[\,\.])(.*)$/im, // " |,
/^((.*?([\,\.])[ \t]*)[\'\"])(.*)$/im // , |"
],
re_s=/^([ \t]+)$/m; //空白のみの行
while(cx || cy!=ny){//1行ずつ該当箇所を洗い出し
var c=[]; txt=GetLineStr(cy+1).replace(/\\./g,'\\\x02'); // "\"" みたいな表記を避けとく
for(var i=0,px,t; i<re.length; i++){px=0; t=txt; while(t.match(re[i])){t=RegExp.$4; c.push(px+RegExp.$2.length); px+=RegExp.$1.length}}
for(var i=0,px,t; i<re_e.length && EMPTY_SEPARATE; i++){t=txt; px=0; while(t.match(re_e[i])){t=RegExp.$4; c.push(px+RegExp.$2.length); px+=RegExp.$1.length}}
if(SPACE_ROW && txt.match(re_s)){c.push(RegExp.$1.length)}
c.sort(function(a,b){return a<b?-1:1}); //只のsort()じゃ文字列比較;;
if(cx--){if(mm<0){while(c[c.length-1]>=cx){c.pop()}}else{while(c[0]<=cx){c.shift()}}}//開始行では余分なの除去
while(ms && c.length){ms-=mm; cx=mm<0?c.pop():c.shift()}//MOVE_STEP番目の該当箇所探し
if(!ms){break}//見つかったら抜ける
cx^=cx; cy+=mm;//次(前)の行へ
if(cy<0 || cy>=ly){if(LOOP_SEARCH){cy=(cy+ly)%ly}else{break}}
}
if(!ms){//表示位置調整のため一旦行頭移動してから該当箇所へ
SetDrawSwitch(0); MoveCursor(cy+1,1,0); MoveCursor(cy+1,cx+1,0);
SetDrawSwitch(1); ReDraw(); return true;
}
StatusMsg(NOT_FOUND,0); return false;
}
if(Editor){if(entrySearch()===null){DEF_FUNC()}}
上検索用
entrySearch_alt.js
/** 未記入箇所へ移動:マクロ(逆方向用) ********************/
function entrySearch_alt(){
SetCookie('document','_EnTrySeArCh_ArG',-1);
return ExecExternalMacro(ExpandParameter('$M').replace(/^(.*?)[^\\\/]+$/m,'$1')+'entrySearch.js');
}
if(Editor){entrySearch_alt()}
丸ごとコピペで
MOVE_STEP = -1
だけ書き換えでも良いのですが、ドキュメントクッキー経由で引数付き実行みたいな事してます。
- 用途上、下方向&上方向用セットでの使用が前提です。
- コードの始めの方に 動作オプション まとめてるので、適宜改変してご使用下さい。
- デフォルトだとHTML・CSS系のファイル、又はそれら用のタイプ設定を適用時のみ動作します。
- 上記以外の場合は、次(前)の段落へ移動 します。
- 先頭(末尾)から再検索時、一周回って同じ行にある箇所は見つけられません。
06/23: 修正
行内の該当箇所のsort()
処理の不具合修正
,.
区切りや[]``()
括りの空欄も検出可能に
-
| はカーソル位置を示してます ↩