{"id":19648386,"url":"https://github.com/bestpractical/rt-extension-hotkeys","last_synced_at":"2026-05-15T06:03:40.208Z","repository":{"id":2229406,"uuid":"3181974","full_name":"bestpractical/rt-extension-hotkeys","owner":"bestpractical","description":null,"archived":false,"fork":false,"pushed_at":"2012-01-29T01:58:34.000Z","size":140,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-09T22:52:10.978Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://search.cpan.org/dist/rt-extension-hotkeys","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bestpractical.png","metadata":{"files":{"readme":"README.pod","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-01-15T03:48:52.000Z","updated_at":"2019-09-30T21:25:36.000Z","dependencies_parsed_at":"2022-07-31T12:08:01.793Z","dependency_job_id":null,"html_url":"https://github.com/bestpractical/rt-extension-hotkeys","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestpractical%2Frt-extension-hotkeys","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestpractical%2Frt-extension-hotkeys/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestpractical%2Frt-extension-hotkeys/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bestpractical%2Frt-extension-hotkeys/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bestpractical","download_url":"https://codeload.github.com/bestpractical/rt-extension-hotkeys/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240958003,"owners_count":19884850,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T14:48:07.273Z","updated_at":"2026-05-15T06:03:40.149Z","avatar_url":"https://github.com/bestpractical.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"use warnings;\nuse strict;\n\npackage RT::Extension::Hotkeys;\n\nour $VERSION = \"0.01\";\n\nuse RT;\n\nRT-\u003eAddJavaScript(\n    qw/\n      jquery.hotkeys.js\n      jquery.simplemodal.js\n      hotkeys.js\n      /\n);\n\nRT-\u003eAddStyleSheets('hotkeys.css');\n\nuse RT::Config;\n\n$RT::Config::META{DisableHotkeys} = {\n    Section         =\u003e 'General',\n    Overridable     =\u003e 1,\n    SortOrder       =\u003e 10,\n    Widget          =\u003e '/Widgets/Form/Boolean',\n    WidgetArguments =\u003e {\n        Description =\u003e 'Disable hotkeys'    # loc\n    },\n};\n\nsub ConfAsJS {\n    my $conf = shift;\n    return {} unless $conf \u0026\u0026 keys %$conf;\n\n    my $str = '{';\n    for my $key ( keys %$conf ) {\n        $key =~ s!'!\\\\'!g;\n        if ( ref $conf-\u003e{$key} ) {\n            if ( exists $conf-\u003e{$key}{body} ) {\n                $str .= \"'$key': function() { $conf-\u003e{$key}{body} },\\n\";\n            }\n            else {\n                $str .= \"'$key': \" . ConfAsJS( $conf-\u003e{$key} ) . \",\\n\";\n            }\n        }\n        else {\n            $str .= \"'$key': function() { $conf-\u003e{$key} },\\n\";\n        }\n    }\n    $str =~ s!,\\n$!\\}!;    # \\} is to make vim happy\n    return $str;\n}\n\nsub Help {\n    my $conf = shift;\n    my $level = shift || 0;\n    return '' unless $conf \u0026\u0026 keys %$conf;\n\n    my $str;\n\n    if ( $level == 0 ) {\n        for my $item ( sort { $a eq 'global' ? -1 : $a cmp $b }keys %$conf ) {\n            $str .= \"===== $item =====\\\\n\\\\n\";\n            $str .= Help( $conf-\u003e{$item}, $level + 1 );\n            $str .= \"\\\\n\";\n        }\n    }\n    else {\n\n        for my $key ( sort keys %$conf ) {\n            if ( ref $conf-\u003e{$key} ) {\n                if ( !ref $conf-\u003e{$key} || exists $conf-\u003e{$key}{body} ) {\n                    my $doc = $conf-\u003e{$key}{doc} || $conf-\u003e{$key}{body};\n                    $str .= '  ' x ($level-1) . \"$key -\u003e $doc\\\\n\";\n                }\n                else {\n                    $str .=\n                        '  ' x ($level-1)\n                      . \"$key -\u003e\\\\n\"\n                      . Help( $conf-\u003e{$key}, $level + 1 );\n                }\n            }\n            else {\n                $str .= '    ' x ($level-1) . \"$key -\u003e $conf-\u003e{$key}\\\\n\";\n            }\n        }\n    }\n    return $str;\n}\n\n1;\n__END__\n\n=head1 NAME\n\nRT::Extension::Hotkeys - hotkeys for rt web interface\n\n=head1 VERSION\n\nVersion 0.01\n\n=head1 INSTALLATION\n\nThis extension only works with RT 4 or later.\n\nTo install this module, run the following commands:\n\n    perl Makefile.PL\n    make\n    make install\n\nadd RT::Extension::Hotkeys to @Plugins in RT's etc/RT_SiteConfig.pm:\n\n    Set( @Plugins, qw(... RT::Extension::Hotkeys) );\n    Set( $DisableHotkeys, 1 ); # disable it by default\n\ncustomize %Hotkeys to meet your needs:\n\n    Set(\n        %Hotkeys,\n        (\n            global =\u003e {\n                'v'       =\u003e { body =\u003e q!hotkeys.version()!, doc =\u003e 'version', },\n                'shift+/' =\u003e { body =\u003e q!hotkeys.help()!,    doc =\u003e 'help', },\n                'g'       =\u003e {\n                    'a' =\u003e {\n                        body =\u003e q!hotkeys.openLink(\"/Approvals\")!,\n                        doc  =\u003e 'approvals',\n                    },\n                    'c' =\u003e {\n                        'c' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Admin/\")!,\n                            doc  =\u003e 'admin',\n                        },\n                        'g' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Admin/Global.html\")!,\n                            doc  =\u003e 'admin global',\n                        },\n                    },\n                    'd' =\u003e {\n                        body =\u003e q!hotkeys.openLink(\"/Dashboards/index.html\")!,\n                        doc  =\u003e 'dashboards',\n                    },\n                    'h' =\u003e { body =\u003e q!hotkeys.openLink(\"/\")!, doc =\u003e 'home', },\n                    'l' =\u003e {\n                        body =\u003e q!hotkeys.openLink(\"/NoAuth/Logout.html\")!,\n                        doc  =\u003e 'logout',\n                    },\n                    'n' =\u003e {\n                        body =\u003e q!hotkeys.submit('#CreateTicketInQueue')!,\n                        doc  =\u003e 'create ticket in default queue',\n                    },\n                    'p' =\u003e {\n                        'h' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Prefs/Hotkeys.html\")!,\n                            doc  =\u003e 'customize hotkeys',\n                        },\n                        'p' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Prefs/Other.html\")!,\n                            doc  =\u003e 'customize options',\n                        },\n                    },\n                    'r' =\u003e {\n                        body =\u003e q!location.reload()!,\n                        doc  =\u003e 'reload',\n                    },\n                    's' =\u003e {\n                        body =\u003e q!hotkeys.openLink('/Search/Build.html')!,\n                        doc  =\u003e 'search builder',\n                    },\n                    't' =\u003e { body =\u003e q!hotkeys.ticket()!, doc =\u003e 'goto ticket' },\n                    'u' =\u003e {\n                        'd' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Tools/MyDay.html\")!,\n                            doc  =\u003e 'my day',\n                        },\n                        'o' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Tools/Offline.html\")!,\n                            doc  =\u003e 'offline',\n                        },\n                        'm' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Tools/MyReminders\")!,\n                            doc  =\u003e 'my reminders',\n                        },\n                        'u' =\u003e {\n                            body =\u003e q!hotkeys.openLink(\"/Tools\")!,\n                            doc  =\u003e 'tools',\n                        },\n                    },\n                },\n            },\n            '/Ticket/' =\u003e {\n                a =\u003e {\n                    'c' =\u003e {\n                        body =\u003e\n                          q!hotkeys.open('#page-menu a[href*=\"Action=Comment\"]')!,\n                        doc =\u003e 'comment',\n                    },\n                    'shift+c' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"Action=Comment\"]:last')!,\n                        doc =\u003e 'comment based on the last message',\n                    },\n                    'e' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Articles/Article/ExtractIntoClass.html\"]')!,\n                        doc =\u003e 'forward',\n                    },\n                    'f' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Ticket/Forward.html\"]')!,\n                        doc =\u003e 'forward',\n                    },\n                    'shift+f' =\u003e {\n                        body =\u003e\n                          q!hotkeys.open('a[href*=\"/Ticket/Forward.html\"]:last')!,\n                        doc =\u003e 'forward the last message',\n                    },\n                    'j' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"DefaultStatus=rejected\"]')!,\n                        doc =\u003e 'reject',\n                    },\n                    'l' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"DefaultStatus=resolved\"]')!,\n                        doc =\u003e 'resolve',\n                    },\n                    'o' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"DefaultStatus=open\"]')!,\n                        doc =\u003e 'open',\n                    },\n                    's' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"DefaultStatus=stalled\"]')!,\n                        doc =\u003e 'stall',\n                    },\n                    'r' =\u003e {\n                        body =\u003e\n                          q!hotkeys.open('#page-menu a[href*=\"Action=Respond\"]')!,\n                        doc =\u003e 'reply',\n                    },\n                    'shift+r' =\u003e {\n                        body =\u003e q!hotkeys.open('a[href*=\"Action=Respond\"]:last')!,\n                        doc  =\u003e 'reply based on the last message',\n                    },\n                    't' =\u003e {\n                        body =\u003e\n                          q!hotkeys.open('#page-menu a[href*=\"Action=take\"]')!,\n                        doc =\u003e 'open',\n                    },\n                },\n                'b' =\u003e {\n                    body =\u003e\n    q!hotkeys.click('#page-menu a[href*=\"/Helpers/Toggle/TicketBookmark\"]')!,\n                    doc =\u003e 'toggle bookmark',\n                },\n                'd' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Ticket/Display.html\"]')!,\n                    doc =\u003e 'display',\n                },\n                'h' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Ticket/History.html\"]')!,\n                    doc =\u003e 'history',\n                },\n                'm' =\u003e {\n                    'a' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Ticket/ModifyAll.html\"]')!,\n                        doc =\u003e 'modify all',\n                    },\n                    'b' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Ticket/Modify.html\"]')!,\n                        doc =\u003e 'modify basics',\n                    },\n                    'd' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Ticket/ModifyDates.html\"]')!,\n                        doc =\u003e 'modify dates',\n                    },\n                    'l' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Ticket/ModifyLinks.html\"]')!,\n                        doc =\u003e 'modify links',\n                    },\n                    'p' =\u003e {\n                        body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Ticket/ModifyPeople.html\"]')!,\n                        doc =\u003e 'modify people',\n                    },\n                },\n                'r' =\u003e {\n                    body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Ticket/Reminders.html\"]')!,\n                    doc =\u003e 'reminders',\n                },\n            },\n            '/Search/' =\u003e {\n                'a' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Search/Edit.html\"]')!,\n                    doc =\u003e 'advanced',\n                },\n                'c' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Search/Chart.html\"]')!,\n                    doc =\u003e 'chart',\n                },\n                'e' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Search/Build.html\"]')!,\n                    doc =\u003e 'edit',\n                },\n                'f' =\u003e {\n                    body =\u003e q!hotkeys.open('#page-menu a[href*=\"/NoAuth/rss\"]')!,\n                    doc  =\u003e 'rss',\n                },\n                'i' =\u003e {\n                    body =\u003e q!hotkeys.open('#page-menu a[href*=\"/NoAuth/iCal\"]')!,\n                    doc  =\u003e 'ical',\n                },\n                'r' =\u003e {\n                    body =\u003e\n    q!hotkeys.open('#page-menu a[href*=\"/Admin/Tools/Shredder\"]')!,\n                    doc =\u003e 'bulk',\n                },\n                'x' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Search/Results.tsv\"]')!,\n                    doc =\u003e 'excel',\n                },\n                's' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Search/Results.html\"]')!,\n                    doc =\u003e 'advanced',\n                },\n                'u' =\u003e {\n                    body =\u003e\n                      q!hotkeys.open('#page-menu a[href*=\"/Search/Bulk.html\"]')!,\n                    doc =\u003e 'bulk',\n                },\n            },\n        )\n    );\n\n=head1 AUTHOR\n\nsunnavy, \u003csunnavy at bestpractical.com\u003e\n\n\n=head1 LICENSE AND COPYRIGHT\n\nCopyright 2012 Best Practical Solutions, LLC\n\nThis program is free software; you can redistribute it and/or modify it\nunder the terms of either: the GNU General Public License as published\nby the Free Software Foundation; or the Artistic License.\n\nSee http://dev.perl.org/licenses/ for more information.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbestpractical%2Frt-extension-hotkeys","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbestpractical%2Frt-extension-hotkeys","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbestpractical%2Frt-extension-hotkeys/lists"}