main ui: action-based hotkey system, add swap_jk plugin
This commit is contained in:
parent
43e706238a
commit
e218c5f56f
4 changed files with 192 additions and 437 deletions
|
@ -16,6 +16,7 @@ class PluginHost {
|
|||
const HOOK_FEED_PARSED = 6;
|
||||
const HOOK_UPDATE_TASK = 7;
|
||||
const HOOK_AUTH_USER = 8;
|
||||
const HOOK_HOTKEY_MAP = 9;
|
||||
|
||||
const KIND_ALL = 1;
|
||||
const KIND_SYSTEM = 2;
|
||||
|
|
|
@ -1972,55 +1972,73 @@
|
|||
|
||||
function get_hotkeys($link) {
|
||||
$hotkeys = array(
|
||||
"navigation" => array(
|
||||
"next_feed" => "k",
|
||||
"prev_feed" => "j",
|
||||
"next_article" => "n",
|
||||
"prev_article" => "p",
|
||||
"search_dialog" => "/"),
|
||||
"article" => array(
|
||||
"toggle_mark" => "s",
|
||||
"toggle_publ" => "S",
|
||||
"toggle_unread" => "u",
|
||||
"edit_tags" => "T",
|
||||
"dismiss_selected" => "D",
|
||||
"dismiss_read" => "X",
|
||||
"open_in_new_window" => "o",
|
||||
"catchup_below" => "c p",
|
||||
"catchup_above" => "c n",
|
||||
"email_article" => "e"),
|
||||
"article_selection" => array(
|
||||
"select_all" => "a a",
|
||||
"select_unread" => "a u",
|
||||
"select_marked" => "a U",
|
||||
"select_published" => "a p",
|
||||
"select_invert" => "a i",
|
||||
"select_none" => "a n"),
|
||||
"feed" => array(
|
||||
"feed_refresh" => "f r",
|
||||
"feed_unhide_read" => "f a",
|
||||
"feed_subscribe" => "f s",
|
||||
"feed_edit" => "f e",
|
||||
"feed_catchup" => "f q",
|
||||
"feed_reverse" => "f x",
|
||||
"catchup_all" => "Q",
|
||||
"cat_toggle_collapse" => "x"),
|
||||
"goto" => array(
|
||||
"goto_all" => "g a",
|
||||
"goto_fresh" => "g f",
|
||||
"goto_marked" => "g s",
|
||||
"goto_published" => "g p",
|
||||
"goto_tagcloud" => "g t",
|
||||
"goto_prefs" => "g P"),
|
||||
"other" => array(
|
||||
"select_article_cursor" => "(9)", // tab
|
||||
"create_label" => "c l",
|
||||
"create_filter" => "c f",
|
||||
"collapse_sidebar" => "c s",
|
||||
"help_dialog" => "(191)")
|
||||
// "navigation" => array(
|
||||
"k" => "next_feed",
|
||||
"j" => "prev_feed",
|
||||
"n" => "next_article",
|
||||
"p" => "prev_article",
|
||||
"/" => "search_dialog",
|
||||
// "article" => array(
|
||||
"s" => "toggle_mark",
|
||||
"S" => "toggle_publ",
|
||||
"u" => "toggle_unread",
|
||||
"T" => "edit_tags",
|
||||
"D" => "dismiss_selected",
|
||||
"X" => "dismiss_read",
|
||||
"o" => "open_in_new_window",
|
||||
"c p" => "catchup_below",
|
||||
"c n" => "catchup_above",
|
||||
"N" => "article_scroll_down",
|
||||
"P" => "article_scroll_up",
|
||||
"e" => "email_article",
|
||||
// "article_selection" => array(
|
||||
"a a" => "select_all",
|
||||
"a u" => "select_unread",
|
||||
"a U" => "select_marked",
|
||||
"a p" => "select_published",
|
||||
"a i" => "select_invert",
|
||||
"a n" => "select_none",
|
||||
// "feed" => array(
|
||||
"f r" => "feed_refresh",
|
||||
"f a" => "feed_unhide_read",
|
||||
"f s" => "feed_subscribe",
|
||||
"f e" => "feed_edit",
|
||||
"f q" => "feed_catchup",
|
||||
"f x" => "feed_reverse",
|
||||
"f D" => "feed_debug_update",
|
||||
"Q" => "catchup_all",
|
||||
"x" => "cat_toggle_collapse",
|
||||
// "goto" => array(
|
||||
"g a" => "goto_all",
|
||||
"g f" => "goto_fresh",
|
||||
"g s" => "goto_marked",
|
||||
"g p" => "goto_published",
|
||||
"g t" => "goto_tagcloud",
|
||||
"g P" => "goto_prefs",
|
||||
// "other" => array(
|
||||
"(9)" => "select_article_cursor", // tab
|
||||
"c l" => "create_label",
|
||||
"c f" => "create_filter",
|
||||
"c s" => "collapse_sidebar",
|
||||
"(191)" => "help_dialog",
|
||||
);
|
||||
|
||||
return $hotkeys;
|
||||
global $pluginhost;
|
||||
foreach ($pluginhost->get_hooks($pluginhost::HOOK_HOTKEY_MAP) as $plugin) {
|
||||
$hotkeys = $plugin->hook_hotkey_map($hotkeys);
|
||||
}
|
||||
|
||||
$prefixes = array();
|
||||
|
||||
foreach (array_keys($hotkeys) as $hotkey) {
|
||||
$pair = explode(" ", $hotkey, 2);
|
||||
|
||||
if (count($pair) > 1 && !in_array($pair[0], $prefixes)) {
|
||||
array_push($prefixes, $pair[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return array($prefixes, $hotkeys);
|
||||
}
|
||||
|
||||
function make_runtime_info($link) {
|
||||
|
|
487
js/tt-rss.js
487
js/tt-rss.js
|
@ -649,7 +649,9 @@ function hotkey_handler(e) {
|
|||
|
||||
if (!shift_key) keychar = keychar.toLowerCase();
|
||||
|
||||
if (!hotkey_prefix && ["a", "f", "g", "c"].indexOf(keychar) != -1) {
|
||||
var hotkeys = getInitParam("hotkeys");
|
||||
|
||||
if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
|
||||
|
||||
var date = new Date();
|
||||
var ts = Math.round(date.getTime() / 1000);
|
||||
|
@ -672,482 +674,187 @@ function hotkey_handler(e) {
|
|||
var hotkey_action = false;
|
||||
var hotkeys = getInitParam("hotkeys");
|
||||
|
||||
for (cat in hotkeys) {
|
||||
for (action in hotkeys[cat]) {
|
||||
if (hotkeys[cat][action] == hotkey) {
|
||||
hotkey_action = action;
|
||||
break;
|
||||
}
|
||||
for (sequence in hotkeys[1]) {
|
||||
if (sequence == hotkey) {
|
||||
hotkey_action = hotkeys[1][sequence];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (hotkey_action) {
|
||||
case "next_feed":
|
||||
var rv = dijit.byId("feedTree").getNextFeed(
|
||||
getActiveFeedId(), activeFeedIsCat());
|
||||
|
||||
if (rv) viewfeed(rv[0], '', rv[1]);
|
||||
return true;
|
||||
case "prev_feed":
|
||||
var rv = dijit.byId("feedTree").getPreviousFeed(
|
||||
getActiveFeedId(), activeFeedIsCat());
|
||||
|
||||
if (rv) viewfeed(rv[0], '', rv[1]);
|
||||
return true;
|
||||
case "next_article":
|
||||
moveToPost('next');
|
||||
return true;
|
||||
case "prev_article":
|
||||
moveToPost('prev');
|
||||
return true;
|
||||
case "search_dialog":
|
||||
return true;
|
||||
search();
|
||||
return ;
|
||||
case "toggle_mark":
|
||||
selectionToggleMarked(undefined, false, true);
|
||||
return true;
|
||||
case "toggle_publ":
|
||||
selectionTogglePublished(undefined, false, true);
|
||||
return true;
|
||||
case "toggle_unread":
|
||||
selectionToggleUnread(undefined, false, true);
|
||||
return true;
|
||||
case "edit_tags":
|
||||
var id = getActiveArticleId();
|
||||
if (id) {
|
||||
editArticleTags(id, getActiveFeedId(), isCdmMode());
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
case "dismiss_selected":
|
||||
dismissSelectedArticles();
|
||||
return true;
|
||||
case "dismiss_read":
|
||||
return true;
|
||||
case "open_in_new_window":
|
||||
if (getActiveArticleId()) {
|
||||
openArticleInNewWindow(getActiveArticleId());
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
case "catchup_below":
|
||||
catchupRelativeToArticle(1);
|
||||
return true;
|
||||
case "catchup_above":
|
||||
catchupRelativeToArticle(0);
|
||||
return true;
|
||||
case "article_scroll_down":
|
||||
scrollArticle(50);
|
||||
return true;
|
||||
case "article_scroll_up":
|
||||
scrollArticle(-50);
|
||||
return true;
|
||||
case "email_article":
|
||||
emailArticle();
|
||||
return true;
|
||||
case "select_all":
|
||||
selectArticles('all');
|
||||
return true;
|
||||
case "select_unread":
|
||||
selectArticles('unread');
|
||||
return true;
|
||||
case "select_marked":
|
||||
selectArticles('marked');
|
||||
return true;
|
||||
case "select_published":
|
||||
selectArticles('published');
|
||||
return true;
|
||||
case "select_invert":
|
||||
selectArticles('invert');
|
||||
return true;
|
||||
case "select_none":
|
||||
selectArticles('none');
|
||||
return true;
|
||||
case "feed_refresh":
|
||||
if (getActiveFeedId() != undefined) {
|
||||
viewfeed(getActiveFeedId(), '', activeFeedIsCat());
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
case "feed_unhide_read":
|
||||
toggleDispRead();
|
||||
return true;
|
||||
case "feed_subscribe":
|
||||
quickAddFeed();
|
||||
return true;
|
||||
case "feed_debug_update":
|
||||
window.open("backend.php?op=feeds&method=view&feed=" + getActiveFeedId() +
|
||||
"&view_mode=adaptive&order_by=default&update=&m=ForceUpdate&cat=" +
|
||||
activeFeedIsCat() + "&DevForceUpdate=1&debug=2&xdebug=2&csrf_token=" +
|
||||
getInitParam("csrf_token"));
|
||||
return true;
|
||||
case "feed_edit":
|
||||
if (activeFeedIsCat())
|
||||
alert(__("You can't edit this kind of feed."));
|
||||
else
|
||||
editFeed(getActiveFeedId());
|
||||
return true;
|
||||
case "feed_catchup":
|
||||
if (getActiveFeedId() != undefined) {
|
||||
catchupCurrentFeed();
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
case "feed_reverse":
|
||||
reverseHeadlineOrder();
|
||||
return true;
|
||||
case "catchup_all":
|
||||
catchupAllFeeds();
|
||||
return true;
|
||||
case "cat_toggle_collapse":
|
||||
if (activeFeedIsCat()) {
|
||||
dijit.byId("feedTree").collapseCat(getActiveFeedId());
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
case "goto_all":
|
||||
viewfeed(-4);
|
||||
return true;
|
||||
case "goto_fresh":
|
||||
viewfeed(-3);
|
||||
return true;
|
||||
case "goto_marked":
|
||||
viewfeed(-1);
|
||||
return true;
|
||||
case "goto_published":
|
||||
viewfeed(-2);
|
||||
return true;
|
||||
case "goto_tagcloud":
|
||||
displayDlg("printTagCloud");
|
||||
return true;
|
||||
case "goto_prefs":
|
||||
gotoPreferences();
|
||||
return true;
|
||||
case "select_article_cursor":
|
||||
var id = getArticleUnderPointer();
|
||||
if (id) {
|
||||
var cb = dijit.byId("RCHK-" + id);
|
||||
if (cb) {
|
||||
cb.attr("checked", !cb.attr("checked"));
|
||||
toggleSelectRowById(cb, "RROW-" + id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case "create_label":
|
||||
addLabel();
|
||||
return true;
|
||||
case "create_filter":
|
||||
quickAddFilter();
|
||||
return true;
|
||||
case "collapse_sidebar":
|
||||
collapse_feedlist();
|
||||
return true;
|
||||
case "help_dialog":
|
||||
return true;
|
||||
new Ajax.Request("backend.php", {
|
||||
parameters: "?op=backend&method=help&topic=main",
|
||||
onComplete: function(transport) {
|
||||
$("hotkey_help_overlay").innerHTML = transport.responseText;
|
||||
Effect.Appear("hotkey_help_overlay", {duration : 0.3});
|
||||
} });
|
||||
return false;
|
||||
default:
|
||||
console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey);
|
||||
}
|
||||
|
||||
|
||||
/* if ((keycode == 70 || keycode == 67 || keycode == 71 || keycode == 65)
|
||||
&& !hotkey_prefix) {
|
||||
|
||||
var date = new Date();
|
||||
var ts = Math.round(date.getTime() / 1000);
|
||||
|
||||
hotkey_prefix = keychar;
|
||||
hotkey_prefix_pressed = ts;
|
||||
|
||||
cmdline.innerHTML = keychar;
|
||||
Element.show(cmdline);
|
||||
|
||||
console.log("KP: PREFIX=" + keycode + " CHAR=" + keychar + " TS=" + ts);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Element.visible("hotkey_help_overlay")) {
|
||||
Element.hide("hotkey_help_overlay");
|
||||
}
|
||||
|
||||
Element.hide(cmdline);
|
||||
|
||||
|
||||
/* Global hotkeys */
|
||||
return;
|
||||
|
||||
if (!hotkey_prefix) {
|
||||
|
||||
if (keycode == 27) { // escape
|
||||
closeArticlePanel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 69) { // e
|
||||
emailArticle();
|
||||
}
|
||||
|
||||
if ((keycode == 191 || keychar == '?') && shift_key) { // ?
|
||||
|
||||
new Ajax.Request("backend.php", {
|
||||
parameters: "?op=backend&method=help&topic=main",
|
||||
onComplete: function(transport) {
|
||||
$("hotkey_help_overlay").innerHTML = transport.responseText;
|
||||
Effect.Appear("hotkey_help_overlay", {duration : 0.3});
|
||||
} });
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 191 || keychar == '/') { // /
|
||||
search();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 74 && !shift_key) { // j
|
||||
var rv = dijit.byId("feedTree").getPreviousFeed(
|
||||
getActiveFeedId(), activeFeedIsCat());
|
||||
|
||||
if (rv) viewfeed(rv[0], '', rv[1]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 75) { // k
|
||||
var rv = dijit.byId("feedTree").getNextFeed(
|
||||
getActiveFeedId(), activeFeedIsCat());
|
||||
|
||||
if (rv) viewfeed(rv[0], '', rv[1]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift_key && keycode == 40) { // shift-down
|
||||
catchupRelativeToArticle(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift_key && keycode == 38) { // shift-up
|
||||
catchupRelativeToArticle(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift_key && keycode == 78) { // N
|
||||
scrollArticle(50);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift_key && keycode == 80) { // P
|
||||
scrollArticle(-50);
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 68 && shift_key) { // shift-D
|
||||
dismissSelectedArticles();
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 88 && shift_key) { // shift-X
|
||||
dismissReadArticles();
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 78 || keycode == 40) { // n, down
|
||||
if (typeof moveToPost != 'undefined') {
|
||||
moveToPost('next');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 80 || keycode == 38) { // p, up
|
||||
if (typeof moveToPost != 'undefined') {
|
||||
moveToPost('prev');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 83 && shift_key) { // S
|
||||
selectionTogglePublished(undefined, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 83) { // s
|
||||
selectionToggleMarked(undefined, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 85) { // u
|
||||
selectionToggleUnread(undefined, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 84 && shift_key) { // T
|
||||
var id = getActiveArticleId();
|
||||
if (id) {
|
||||
editArticleTags(id, getActiveFeedId(), isCdmMode());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 9) { // tab
|
||||
var id = getArticleUnderPointer();
|
||||
if (id) {
|
||||
var cb = dijit.byId("RCHK-" + id);
|
||||
|
||||
if (cb) {
|
||||
cb.attr("checked", !cb.attr("checked"));
|
||||
toggleSelectRowById(cb, "RROW-" + id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 79) { // o
|
||||
if (getActiveArticleId()) {
|
||||
openArticleInNewWindow(getActiveArticleId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 81 && shift_key) { // Q
|
||||
if (typeof catchupAllFeeds != 'undefined') {
|
||||
catchupAllFeeds();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 88 && !shift_key) { // x
|
||||
if (activeFeedIsCat()) {
|
||||
dijit.byId("feedTree").collapseCat(getActiveFeedId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Prefix a */
|
||||
|
||||
if (hotkey_prefix == 65) { // a
|
||||
hotkey_prefix = false;
|
||||
|
||||
if (keycode == 65) { // a
|
||||
selectArticles('all');
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 85 && !shift_key) { // u
|
||||
selectArticles('unread');
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 80) { // p
|
||||
selectArticles('published');
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 85 && shift_key) { // u
|
||||
selectArticles('marked');
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 73) { // i
|
||||
selectArticles('invert');
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 78) { // n
|
||||
selectArticles('none');
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Prefix f */
|
||||
|
||||
if (hotkey_prefix == 70) { // f
|
||||
|
||||
hotkey_prefix = false;
|
||||
|
||||
if (keycode == 81) { // q
|
||||
if (getActiveFeedId() != undefined) {
|
||||
catchupCurrentFeed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 82) { // r
|
||||
if (getActiveFeedId() != undefined) {
|
||||
viewfeed(getActiveFeedId(), '', activeFeedIsCat());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 65) { // a
|
||||
toggleDispRead();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 85) { // u
|
||||
if (getActiveFeedId() != undefined) {
|
||||
viewfeed(getActiveFeedId(), '');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 68 && shift_key) { // D
|
||||
|
||||
window.open("backend.php?op=feeds&method=view&feed=" + getActiveFeedId() +
|
||||
"&view_mode=adaptive&order_by=default&update=&m=ForceUpdate&cat=" +
|
||||
activeFeedIsCat() + "&DevForceUpdate=1&debug=2&xdebug=2&csrf_token=" +
|
||||
getInitParam("csrf_token"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 69) { // e
|
||||
|
||||
if (activeFeedIsCat())
|
||||
alert(__("You can't edit this kind of feed."));
|
||||
else
|
||||
editFeed(getActiveFeedId());
|
||||
return;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 83) { // s
|
||||
quickAddFeed();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 67 && shift_key) { // C
|
||||
if (typeof catchupAllFeeds != 'undefined') {
|
||||
catchupAllFeeds();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 67) { // c
|
||||
if (getActiveFeedId() != undefined) {
|
||||
catchupCurrentFeed();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 88) { // x
|
||||
reverseHeadlineOrder();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prefix c */
|
||||
|
||||
if (hotkey_prefix == 67) { // c
|
||||
hotkey_prefix = false;
|
||||
|
||||
if (keycode == 70) { // f
|
||||
quickAddFilter();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 76) { // l
|
||||
addLabel();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 83) { // s
|
||||
if (typeof collapse_feedlist != 'undefined') {
|
||||
collapse_feedlist();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == 77) { // m
|
||||
// TODO: sortable feedlist
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 78) { // n
|
||||
catchupRelativeToArticle(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (keycode == 80) { // p
|
||||
catchupRelativeToArticle(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Prefix g */
|
||||
|
||||
if (hotkey_prefix == 71) { // g
|
||||
|
||||
hotkey_prefix = false;
|
||||
|
||||
|
||||
if (keycode == 65) { // a
|
||||
viewfeed(-4);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 83) { // s
|
||||
viewfeed(-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 80 && shift_key) { // P
|
||||
gotoPreferences();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 80) { // p
|
||||
viewfeed(-2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 70) { // f
|
||||
viewfeed(-3);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keycode == 84) { // t
|
||||
displayDlg("printTagCloud");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cmd */
|
||||
|
||||
if (hotkey_prefix == 224 || hotkey_prefix == 91) { // f
|
||||
hotkey_prefix = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (hotkey_prefix) {
|
||||
console.log("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
|
||||
} else {
|
||||
console.log("KP: CODE=" + keycode + " CHAR=" + keychar);
|
||||
}
|
||||
|
||||
|
||||
} catch (e) {
|
||||
exception_error("hotkey_handler", e);
|
||||
}
|
||||
|
|
29
plugins/swap_jk/swap_jk.php
Normal file
29
plugins/swap_jk/swap_jk.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
class Swap_JK extends Plugin {
|
||||
|
||||
private $link;
|
||||
private $host;
|
||||
|
||||
function about() {
|
||||
return array(1.0,
|
||||
"Swap j and k hotkeys (for vi brethren)",
|
||||
"fox");
|
||||
}
|
||||
|
||||
function init($host) {
|
||||
$this->link = $host->get_link();
|
||||
$this->host = $host;
|
||||
|
||||
$host->add_hook($host::HOOK_HOTKEY_MAP, $this);
|
||||
}
|
||||
|
||||
function hook_hotkey_map($hotkeys) {
|
||||
|
||||
$hotkeys["j"] = "next_feed";
|
||||
$hotkeys["k"] = "prev_feed";
|
||||
|
||||
return $hotkeys;
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in a new issue