diff options
author | hogelog | 2009-04-03 23:42:20 +0000 |
---|---|---|
committer | hogelog | 2009-04-03 23:42:20 +0000 |
commit | 69b35b593e9fd705eeaddc9847c280b4f08e55f5 (patch) | |
tree | bb76525b15392ceb9c444f05f138691f9169ea7e /caret-hint.js | |
parent | 5ddb2cb0fac41547768a20a4b65456ceead5599a (diff) | |
download | vimperator-plugins-69b35b593e9fd705eeaddc9847c280b4f08e55f5.tar.bz2 |
コミットミスの修正
git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@31880 d0d07461-0603-4401-acd4-de1884942a52
Diffstat (limited to 'caret-hint.js')
-rw-r--r-- | caret-hint.js | 176 |
1 files changed, 154 insertions, 22 deletions
diff --git a/caret-hint.js b/caret-hint.js index 008affd..f4e0c76 100644 --- a/caret-hint.js +++ b/caret-hint.js @@ -36,9 +36,9 @@ THE POSSIBILITY OF SUCH DAMAGE. let PLUGIN_INFO = <VimperatorPlugin> <name>Caret Hint</name> - <description>Move the caret position by hint</description> + <description>Move caret position by hint</description> <description lang="ja">Hint を使ってキャレット位置を移動</description> - <version>1.0.0</version> + <version>1.3.0</version> <author mail="anekos@snca.net" homepage="http://d.hatena.ne.jp/nokturnalmortum/">anekos</author> <license>new BSD License (Please read the source code comments of this plugin)</license> <license lang="ja">修正BSDライセンス (ソースコードのコメントを参照してください)</license> @@ -46,46 +46,178 @@ let PLUGIN_INFO = <minVersion>2.0pre</minVersion> <maxVersion>2.0pre</maxVersion> <detail><![CDATA[ + Move caret position by hint. == Global Variables == - let g:caret_hint_key: - Hint mode key + let g:caret_hint_key = 'c': + Hint mode key. + Move caret position to the head of selected element. + let g:caret_hint_tail_key = 'C': + Hint mode key. + Move caret position to the tail of selected element. + let g:caret_hint_select_key = '' (default: disabled): + Hint mode key. + Move caret position to the head of selected element, and select. + let g:caret_hint_select_tail_key = 'S': + Hint mode key. + Move caret position to the tail of selected element, and select. + let g:caret_hint_swap_key = 's': + The key mapping for Visual-mode. + Swap caret position head to tail. + If apply empty string ('') to these variables, these mapping or mode are not enabled. + == Global Variables 2 == + let g:caret_hint_xpath = '//*': + The XPath for hint-mode selection. ]]></detail> <detail lang="ja"><![CDATA[ - == Global Variables == - let g:caret_hint_key: + Hint を使ってキャレット位置を移動 + == Global Variables 1 == + let g:caret_hint_key = 'c': + Hint モードのキー + 選択した要素の先頭にキャレットを移動する + let g:caret_hint_tail_key = 'C': + Hint モードのキー + 選択した要素の後尾にキャレットを移動する + let g:caret_hint_select_key = '' (デフォルト: 無効): + Hint モードのキー + 選択した要素の先頭にキャレットを移動し、要素を選択する + let g:caret_hint_select_tail_key = 'S': Hint モードのキー + 選択した要素の後尾にキャレットを移動し、要素を選択する + let g:caret_hint_swap_key = 's': + VISUAL モード用のキーマッピング + キャレットの位置を交換する(先頭 <=> 後尾) + これらの値に空文字列を与えれば、マッピングやモードは有効にされません。 + == Global Variables 2 == + let g:caret_hint_xpath = '//*': + ヒント対象要素を選択するための XPath ]]></detail> </VimperatorPlugin>; // }}} +/* _\|/_ + (o o) + +----oOO-{_}-OOo------------+ + |TODO count@action の使い道 | + | 要素 A-B 間を選択 | + +---------------------------*/ + + (function () { - let mode = liberator.globalVariables.caret_hint_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', ''); + let selectTailMode = gval('caret_hint_select_tail_key', 'S'); + let swapKey = gval('caret_hint_swap_key', 's'); + let extendLeader = gval('extend_leader', 'c'); + let hintXPath = liberator.globalVariables.caret_hint_xpath || '//*'; + + let extendMode = false; + + [headMode, tailMode, selectHeadMode, selectTailMode].forEach( + function(mode) { + let map = extendLeader + ';' + mode; + mappings.remove(modes.NORMAL, map); // for debug + mappings.remove(modes.VISUAL, map); // for debug + mappings.addUserMap( + [modes.NORMAL, modes.VISUAL], + [map], + 'desc', + function () { + extendMode = true; + hints.show(mode); + }, + { + } + ); + } + ); - function moveCaret (elem) { - let doc = elem.ownerDocument; + [ + [[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); + extendMode = false; + }, + function () hintXPath + ); + }); + + if (swapKey) { + mappings.addUserMap( + [modes.VISUAL], + [swapKey], + 'Swap caret position head to tail', + swapCaret, + {} + ); + } + + + 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); - r.setEnd(r.startContainer, r.startOffset); + + if (select) { + mappings.getDefault(modes.NORMAL, 'i').action(); + mappings.getDefault(modes.CARET, 'v').action(); + } else { + if (head) { + r.setEnd(r.startContainer, r.startOffset); + } else { + r.setStart(r.endContainer, r.endOffset); + } + mappings.getDefault(modes.NORMAL, 'i').action(); + } + + if (extendMode) { + let a = sel.getRangeAt(0); + if (r.compareBoundaryPoints(Range.END_TO_START, a) < 0) { + r.setEnd(a.endContainer, a.endOffset); + } else { + r.setStart(a.startContainer, a.startOffset); + } + } sel.addRange(r); - } - hints.addMode( - 'c', - 'Move the caret position', - function (elem, _, count) { - moveCaret(elem); - mappings.getDefault(modes.NORMAL, 'i').action(); - }, - function () '//*' - ); + if (select && head) + swapCaret(); + } })(); // vim:sw=2 ts=2 et si fdm=marker: |