Last active
September 26, 2015 02:27
-
-
Save 958/1024186 to your computer and use it in GitHub Desktop.
[keysnail]Abbreviations manager
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var PLUGIN_INFO = | |
<KeySnailPlugin> | |
<name>Abbreviations manager</name> | |
<description lang="ja">Vimperator の Abbreviations みたいなもの</description> | |
<updateURL>https://gist.github.com/958/1024186/raw/abbreviations.ks.js</updateURL> | |
<iconURL>https://sites.google.com/site/958site/Home/files/abbreviations.ks.png</iconURL> | |
<license>MIT</license> | |
<minVersion>1.8.5</minVersion> | |
<author>958</author> | |
<version>0.0.6</version> | |
<detail><![CDATA[ | |
=== 概要 === | |
略語を定義して、入力時に展開します | |
Vimperator の :ab とか C-] の劣化版です | |
=== 使い方 === | |
==== 基本的な使い方 ==== | |
まず、略語を定義します | |
エクステ 'abbreviations-add' を実行して | |
>|| | |
k keysnail | |
||< | |
と入力後 Enter してみてください | |
そのあとに、どこかのテキストボックス上(たとえばナビゲーションバー) で "k" と入力後、エクステ 'abbreviations-expand' を実行してみてください | |
k が keysnail に展開されます | |
以下のようにキーバインドを設定するとよいかもしれません | |
>|javascript| | |
key.setEditKey('C-]', function (ev, arg) { | |
ext.exec('abbreviations-expand', arg, ev); | |
}, '略語を展開'); | |
||< | |
また、KeySnail のプロンプト上で、k と入力後 SPC キーを押下してみてください | |
同様に k が keysnail に展開されます | |
プロンプト上では SPC キーの他にも " ' キーでも略語展開が行われます | |
==== 略語一覧 ==== | |
保存済みの略語一覧を表示したり、削除したい場合は、エクステ 'abbreviations-show' を実行してください | |
なお、太字で表示されている略語は、後述の plugins.options['abbreviations.defined_abbreviations'] で定義されている略語の為、削除することはできません | |
==== 動的な文字列を展開する略語 ==== | |
どこかのテキストボックス上で "URL" と入力後、エクステ 'abbreviations-expand' を実行してみてください | |
現在表示中のページの URL がテキストボックス上に表示されます | |
このような動的な略語があらかじめ定義されています | |
TITLE: | |
表示中のページタイトル | |
URL: | |
表示中のページ URL | |
S-URL: | |
表示中のページの短縮 URL (goo.gl) | |
SEL: | |
表示中のページの選択テキスト | |
これらは plugins.options['abbreviations.defined_abbreviations'] を設定することで上書き可能です | |
以下のように、展開後の文字列を返却する function を指定してください | |
>|javascript| | |
plugins.options['abbreviations.defined_abbreviations'] = { | |
"TITLE" : function() content.document.title, | |
"URL" : function() content.location.href, | |
"S-URL" : function() | |
JSON.parse(util.request('POST', 'https://www.googleapis.com/urlshortener/v1/url', { | |
header: { "Content-Type": "application/json" }, | |
params: JSON.stringify({ longUrl: content.location.href }) | |
}).responseText).id || '', | |
"SEL" : function() (content.getSelection() || "").toString(), | |
}; | |
||< | |
なお plugins.options['abbreviations.defined_abbreviations'] には、通常の略語も設定可能です | |
エクステ 'abbreviations-add' で追加された略語は KeySnail の persist エリアに保存されますが、設定ファイルを統一するために plugins.options['abbreviations.defined_abbreviations'] のみ利用するのも良いかもしれません | |
>|javascript| | |
plugins.options['abbreviations.defined_abbreviations'] = { | |
// 動的な略語定義 | |
"TITLE" : function() content.document.title, | |
"URL" : function() content.location.href, | |
"S-URL" : function() | |
JSON.parse(util.request('POST', 'https://www.googleapis.com/urlshortener/v1/url', { | |
header: { "Content-Type": "application/json" }, | |
params: JSON.stringify({ longUrl: content.location.href }) | |
}).responseText).id || '', | |
"SEL" : function() (content.getSelection() || "").toString(), | |
// 通常の略語定義 | |
"k" : "KeySnail", | |
}; | |
||< | |
==== キーを送る ==== | |
エクステ 'abbreviations-add' を実行して | |
>|| | |
k keysnail<CR> | |
||< | |
と入力後 Enter してみてください | |
その後、検索ボックスなどで k と入力後、エクステ 'abbreviations-expand' を実行してみてください | |
検索が開始されたと思います | |
このように、キーイベントを送ることが可能です | |
以下のキー定義が使用可能です | |
<CR> <ESC> <f*> <right> <left> <up> <down> <prior> <next> <end> <home> <backspace> <print> <insert> <pause> <delete> <kana> <hangeul> <hangul> <kanji> <hanja> <convert> <nonconvert> <accept> <modechange> <select> <print> <execute> <l_windows> <r_windows> | |
また、"<5left>" など、"<" の直後に数字を指定するとキーを指定回数送ります | |
==== 略語内に略語を使用する ==== | |
エクステ 'abbreviations-add' を実行して | |
>|| | |
info %TITLE %URL | |
||< | |
と入力後 Enter してみてください | |
その後、検索ボックスなどで "info" と入力後、エクステ 'abbreviations-expand' を実行してみてください | |
このように "%略語" と定義することで、略語内に略語を使用することが出来ます | |
なお、略語の入れ子は 1 階層のみ対応しています | |
]]></detail> | |
</KeySnailPlugin>; | |
var pOptions = plugins.setupOptions('abbreviations', { | |
'keymap': { | |
preset: { | |
"C-z" : "prompt-toggle-edit-mode", | |
"SPC" : "prompt-next-page", | |
"b" : "prompt-previous-page", | |
"j" : "prompt-next-completion", | |
"k" : "prompt-previous-completion", | |
"g" : "prompt-beginning-of-candidates", | |
"G" : "prompt-end-of-candidates", | |
"q" : "prompt-cancel", | |
// | |
"c" : "create", | |
"r" : "remove", | |
}, | |
description: M({ | |
ja: "略語一覧の操作用キーマップ", | |
en: "Local keymap for abbreviations list" | |
}) | |
}, | |
'defined_abbreviations': { | |
preset: { | |
"TITLE" : function() content.document.title, | |
"URL" : function() content.location.href, | |
"S-URL" : function() | |
JSON.parse(util.request('POST', 'https://www.googleapis.com/urlshortener/v1/url', { | |
header: { "Content-Type": "application/json" }, | |
params: JSON.stringify({ longUrl: content.location.href }) | |
}).responseText).id || '', | |
"SEL" : function() (content.getSelection() || "").toString(), | |
}, | |
description: M({ | |
ja: "略語定義", | |
en: "Abbreviations" | |
}) | |
}, | |
'prompt_spc': { | |
preset: true, | |
description: M({ | |
ja: "プロンプトで SPC キー等押下時に略語を展開する", | |
en: "When pressing the space key at the prompt to expand the abbreviation" | |
}) | |
} | |
}, PLUGIN_INFO); | |
const GROUP = 'abbreviations'; | |
var gAbbrs = _.extend(persist.restore(GROUP) || {}, pOptions['defined_abbreviations']); | |
function getKeysRegExp() | |
new RegExp('(?:^|"|\'|\\s| )(' + Object.keys(gAbbrs).join('|') + ')$'); | |
function parseExpandText(aValue) { | |
if (typeof aValue == 'function') | |
aValue = aValue(); | |
var array = []; | |
for (var [k, v] in Iterator(gAbbrs)) { | |
if (aValue.indexOf('%' + k) == -1) | |
continue; | |
var value = v; | |
if (v && typeof v == 'function') { | |
value = v(); | |
} | |
aValue = aValue.replace('%' + k, value); | |
} | |
aValue.split('<').forEach(function(v, i) { | |
var temp = v.split('>'); | |
if (i > 0) | |
temp[0] = '<' + temp[0]; | |
temp = temp.map(function(v, i) { | |
if (i < temp.length - 1) | |
v += '>'; | |
return v; | |
}).filter(function(v) !!v); | |
Array.prototype.push.apply(array, temp); | |
}); | |
return array; | |
} | |
// Hack prompt text box | |
(function() { | |
var textbox = document.getElementById("keysnail-prompt-textbox"); | |
if (!textbox) return; | |
// clean up | |
if (my.abbrKeyHandler) | |
textbox.removeEventListener('keypress', my.abbrKeyHandler, false); | |
my.abbrKeyHandler = null; | |
if (pOptions['prompt_spc']) { | |
my.abbrKeyHandler = function(ev) { | |
if (/^(SPC|"|')$/.test(key.keyEventToString(ev))) | |
ext.exec('abbreviations-expand', null, ev); | |
}; | |
textbox.addEventListener('keypress', my.abbrKeyHandler, false); | |
} | |
})(); | |
// Add ext | |
plugins.withProvides(function (provide) { | |
provide('abbreviations-add', function (ev, arg) { | |
prompt.read('Input new abbreviation :', function(word) { | |
if (!word) | |
return; | |
var words = word.trim().split(' '); | |
if (words.length < 2) | |
return; | |
var key = words.shift(); | |
var value = words.join(' '); | |
gAbbrs[key] = value; | |
var temp = persist.restore(GROUP) || {}; | |
temp[key] = value; | |
persist.preserve(temp, GROUP); | |
}); | |
}, M({ja:'略語を追加', en:'Append abbreviation'})); | |
provide ('abbreviations-expand', function (ev, arg) { | |
var elem = ev.originalTarget; | |
var value = elem.value; | |
if (!value) | |
return; | |
var cursor = elem.selectionStart; | |
if (cursor != elem.selectionEnd) | |
return; | |
var abbr = value.substring(0, cursor).match(getKeysRegExp()); | |
abbr = (abbr && abbr[1]) ? abbr[1] : null; | |
if (abbr && abbr in gAbbrs) { | |
elem.selectionStart = cursor - abbr.length; | |
elem.selectionEnd = cursor; | |
parseExpandText(gAbbrs[abbr]).forEach(function(k) { | |
var ev = []; | |
var count = 1; | |
if (k.match(/^<(\d*)(.+)>$/)) { | |
count = parseInt(RegExp.$1, 10) || 1; | |
k = RegExp.$2; | |
switch (k) { | |
case 'CR': | |
for (var i = 0; i < count; i++) | |
ev.push(key.stringToKeyEvent('RET', false)); | |
break; | |
case 'ESC': | |
for (var i = 0; i < count; i++) | |
ev.push(key.stringToKeyEvent('ESC', false)); | |
break; | |
case 'tab': | |
k = '\t'; | |
break; | |
default: | |
try { | |
for (var i = 0; i < count; i++) | |
ev.push(key.stringToKeyEvent('<' + k + '>', false)); | |
} catch(ex) { | |
count = 1; | |
} | |
break; | |
} | |
} | |
if (ev.length > 0) { | |
for (var i = 0; i < count; i++) | |
elem.dispatchEvent(ev[i]); | |
} else { | |
for (var i = 0; i < count; i++) | |
command.insertText(k); | |
} | |
}); | |
} | |
}, M({ja:'略語を展開', en:'Expand abbreviation'})); | |
provide ('abbreviations-show', function (ev, arg) { | |
var presistCache = persist.restore(GROUP) || {}; | |
var collection = []; | |
for (var [key, value] in Iterator(gAbbrs)) { | |
var type = typeof value; | |
if (type == 'function') | |
value = 'function() { ... }'; | |
collection.push([key, value, type]); | |
} | |
prompt.selector({ | |
message : 'Abbreviations :', | |
collection : collection, | |
header : ['Key', 'Value'], | |
flags : [0, 0, HIDDEN|IGNORE], | |
keymap : pOptions['keymap'], | |
stylist : function(args, n, cur) { | |
var style = []; | |
if (!(args[0] in presistCache)) | |
style.push('font-weight: bold'); | |
if (n == 1 && args[2] == 'function') | |
style.push('font-style: italic'); | |
return style.join(';'); | |
}, | |
actions : [ | |
[ function() ext.exec('abbreviations-add'), 'Create new abbreviation', 'create' ], | |
[ function(aIndex, rows) { | |
if (rows[aIndex][0] in presistCache) { | |
delete presistCache[rows[aIndex][0]]; | |
persist.preserve(presistCache, GROUP); | |
delete gAbbrs[rows[aIndex][0]]; | |
rows.splice(aIndex, 1); | |
prompt.refresh(); | |
} | |
}, 'Remove selected abbreviation', 'remove,c' ], | |
] | |
}); | |
}, M({ja: '略語一覧を表示', en:'Show abbreviations list'})); | |
}, PLUGIN_INFO); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment