From 780c575e59e3108c8a07f5f64fd5804420fcb934 Mon Sep 17 00:00:00 2001 From: anekos Date: Tue, 17 Feb 2009 14:42:52 +0000 Subject: デフォルトのキーを変更 モードを追加 git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@30200 d0d07461-0603-4401-acd4-de1884942a52 --- caret-hint.js | 164 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 118 insertions(+), 46 deletions(-) (limited to 'caret-hint.js') diff --git a/caret-hint.js b/caret-hint.js index d38cc19..0f48655 100644 --- a/caret-hint.js +++ b/caret-hint.js @@ -36,9 +36,9 @@ THE POSSIBILITY OF SUCH DAMAGE. let PLUGIN_INFO = Caret Hint - Move the caret position by hint + Move caret position by hint Hint を使ってキャレット位置を移動 - 1.1.0 + 1.2.0 anekos new BSD License (Please read the source code comments of this plugin) 修正BSDライセンス (ソースコードのコメントを参照してください) @@ -46,73 +46,145 @@ let PLUGIN_INFO = 2.0pre 2.0pre 後尾) + これらの値に空文字列を与えれば、マッピングやモードは有効にされません。 + == Global Variables 2 == + let g:caret_hint_xpath = '//*': + ヒント対象要素を選択するための XPath ]]> ; // }}} +/* _\|/_ + (o o) + +----oOO-{_}-OOo------------+ + |TODO count@action の使い道 | + | 要素 A-B 間を選択 | + +---------------------------*/ + + (function () { - let headMode = liberator.globalVariables.caret_hint_key || 'c'; - let selectMode = liberator.globalVariables.caret_hint_select_key || 'C'; + // XXX 空白も有効 + let headMode = gval('caret_hint_key', 'c'); + let tailMode = gval('caret_hint_tail_key', 'C'); + let selectHeadMode = gval('caret_hint_select_key', 's'); + let selectTailMode = gval('caret_hint_select_tail_key', 'S'); + let swapKey = gval('caret_hint_swap_key', 's'); + let hintXPath = liberator.globalVariables.caret_hint_xpath || '//*'; + + [ + [[true, false], headMode], + [[false, false], tailMode], + [[true, true ], selectHeadMode], + [[false, true ], selectTailMode], + ].forEach(function ([[h, s], m, d]) { + if (!m) + return; + hints.addMode( + m, + 'Move caret position to ' + (h ? 'head' : 'tail') + (s ? ' and Select' : ''), + function (elem, loc, count) moveCaret(elem, h, s), + function () hintXPath + ); + }); + + if (swapKey) { + mappings.addUserMap( + [modes.VISUAL], + [swapKey], + 'Swap caret position head to tail', + swapCaret, + {} + ); + } - function moveCaret (elem, type) { - let doc = elem.ownerDocument; + function gval (name, def) { + let v = liberator.globalVariables[name]; + return (v === undefined) ? def : v; + } + + function swapCaret () { let win = new XPCNativeWrapper(window.content.window); - let sel = win.getSelection(); - sel.removeAllRanges(); + let s = win.getSelection(); + if (s.rangeCount <= 0) + return false; + + // 位置交換時に元の情報が失われるので保存しておく + let [a, f] = [[s.anchorNode, s.anchorOffset], [s.focusNode, s.focusOffset]]; + s.collapse.apply(s, f); + s.extend.apply(s, a); + } + + function moveCaret (elem, head, select) { + let doc = elem.ownerDocument; + let win = new XPCNativeWrapper(window.content.window); + let sel = win.getSelection(); let r = doc.createRange(); + + sel.removeAllRanges(); r.selectNodeContents(elem); - switch (type) { - case 'select': - mappings.getDefault(modes.NORMAL, 'i').action(); - mappings.getDefault(modes.CARET, 'v').action(); - break; - case 'head': + if (select) { + liberator.log('select') + mappings.getDefault(modes.NORMAL, 'i').action(); + mappings.getDefault(modes.CARET, 'v').action(); + } else { + liberator.log('not select') + if (head) { r.setEnd(r.startContainer, r.startOffset); - mappings.getDefault(modes.NORMAL, 'i').action(); - break; + } else { + r.setStart(r.endContainer, r.endOffset); + } + mappings.getDefault(modes.NORMAL, 'i').action(); } sel.addRange(r); - } - - hints.addMode( - headMode, - 'Move the caret position', - function (elem, _, count) { - moveCaret(elem, 'head'); - }, - function () '//*' - ); - - hints.addMode( - selectMode, - 'Move the caret position and select', - function (elem, _, count) { - moveCaret(elem, 'select'); - }, - function () '//*' - ); + if (select && head) + swapCaret(); + } })(); // vim:sw=2 ts=2 et si fdm=marker: -- cgit v1.2.3