Skip to content

Instantly share code, notes, and snippets.

@xlshiz
Last active March 12, 2025 10:54
Show Gist options
  • Select an option

  • Save xlshiz/a3cd88b61b75cba40b2293b7eca13ed9 to your computer and use it in GitHub Desktop.

Select an option

Save xlshiz/a3cd88b61b75cba40b2293b7eca13ed9 to your computer and use it in GitHub Desktop.
Surfingkeys settings
//=========================enjoy !!!=============================================
// 1. 高频快速直达理念。搜索,使用独立的s关键字,使用最少的按键,来处理最高频的功能。同理,最直达的逻辑优化。h,直达历史,以及内置的b书签。通过原始的o前缀虽然也挺快,但是,还是处在一种没有优先级的状态。
// 2. 添加快速搜索的能力(可以抛弃一键切换插件)(注:xx可以表达为,域名的缩写,比如,github-gh,google-gg。自己可以改配置,加搜索引擎):
// a. ";+xx",携带当前关键字,切换搜索引擎进行搜索】(独有扩展)
// b. ";;+xx", 使用当前选中的内容,进行浏览器的搜索(内置,使用s+。这种更加易于,减轻快捷键的记忆负担。)
// c. ";;;+xx", 使用用户输入,在当前页面打开输入框,进行搜索(内置,使用s+,这种减轻记忆负担。同时因为在使用频率上,也就s频率高。所以,单独抽取了一个s键)
// d. "alt+s",快速的自动切换搜索引擎,按照顺序进行搜索
// e. "oa+xx",使用关键字,同时打开相同类型的搜索引擎,进行搜索。比如,一个关键字将同时打开,google,baidu。
//================================================================================
const {
unmap,
iunmap,
vunmap,
aceVimMap,
mapkey,
imap,
imapkey,
getClickableElements,
vmapkey,
map,
cmap,
addSearchAlias,
removeSearchAlias,
tabOpenLink,
readText,
Clipboard,
Front,
Hints,
Visual,
RUNTIME
} = api;
//历史记录搜索,不使用默认的MU排序。MU排序太鸡肋。
settings.historyMUOrder = false;
// 1.冲突修改
//与浏览器冲突部分,个人认为它更好
// 移除与浏览器的冲突 查看下载历史,历史记录
unmap('<Ctrl-j>');
iunmap('<Ctrl-j>');
vunmap('<Ctrl-j>');
unmap('<Ctrl-h>');
iunmap('<Ctrl-h>');
vunmap('<Ctrl-h>');
// 2.vimium兼容。个人认为vimium逻辑更好
// 相当于是<Shift-[jkhl]>
map('H', 'S'); // 历史后退
map('L', 'D'); // 历史前进
map('J', 'E'); // tab向左
map('K', 'R'); // tab向右
map('h', 'oh'); // 最直接的理念。
// 3.当前搜索结果选取,各种按键冲突和不灵。<ctrl-n>是个问题会打开新的窗口,而且<ctrl-.>,<ctrl-,>不起作用
cmap('<Alt-j>', '<Ctrl-n>'); //或者使用ahk来修改。参考https://github.com/brookhong/Surfingkeys/issues/1204#issuecomment-1500828389
cmap('<Alt-k>', '<Ctrl-p>');
cmap('<Alt-l>', '<Ctrl-.>');
cmap('<Alt-h>', '<Ctrl-,>');
//4 扩展js,交互其他
// os 打开简悦稍后读
function openSimpReadHtml() {
tabOpenLink("chrome-extension://ijllcpnolfcooahcekpamkbidhejabll/unreader/main.html");
}
mapkey('os', '打开简悦稍后读', openSimpReadHtml);
// 打开pocket
function openPocket() {
tabOpenLink("https://getpocket.com/my-list");
}
mapkey('op', '打开Pocket', openPocket);
//5 final.set theme 官网主题。调整字体大小
settings.theme = `
:root {
--theme-ace-bg:#282828ab; /*Note the fourth channel, this adds transparency*/
--theme-ace-bg-accent:#3c3836;
--theme-ace-fg:#ebdbb2;
--theme-ace-fg-accent:#7c6f64;
--theme-ace-cursor:#928374;
--theme-ace-select:#458588;
}
#sk_editor {
height: 50% !important; /*Remove this to restore the default editor size*/
background: var(--theme-ace-bg) !important;
}
.sk_theme {
font-size: 11pt;
}
#sk_omnibar {
width: 46%;
left: 28%;
opacity: 1;
}
#sk_omnibar_middle{
top: 25%;
}
.sk_theme #sk_omnibarSearchResult>ul>li:nth-child(odd) {
background: #cddef9;
}
.sk_theme #sk_omnibarSearchResult>ul>li.focused {
background: #93b38b;
padding: 14px;
border-left: 10px solid #ccc!important;
border-color: #ecae2d!important;
}
.ace-chrome .ace_print-margin, .ace_gutter, .ace_gutter-cell, .ace_dialog{
background: var(--theme-ace-bg-accent) !important;
}
.ace_dialog-bottom{
border-top: 1px solid var(--theme-ace-bg) !important;
}
.ace-chrome{
color: var(--theme-ace-fg) !important;
}
.ace_gutter, .ace_dialog {
color: var(--theme-ace-fg-accent) !important;
}
.ace_cursor{
color: var(--theme-ace-cursor) !important;
}
.normal-mode .ace_cursor{
background-color: var(--theme-ace-cursor) !important;
border: var(--theme-ace-cursor) !important;
}
.ace_marker-layer .ace_selection {
background: var(--theme-ace-select) !important;
} `
// 6 添加一个自己写的逻辑。实现一键切换插件的逻辑,甚至还有增强
//=====================faster search engine swither====================start
//{mapkey,siteName,keywordRegex,searchUrl} commonUseMapkey:(s,search)(v,videa)(c,code)(g,shop)
var switchSearchConfigs = [{
commonUseMapKey: 's',
mapkey: ';gg',
siteName: 'google',
keywordRegex: getRegExp('www.google.com/search', 'q'),
searchUrl: 'https://www.google.com/search?q=%s'
},
{
commonUseMapKey: 's',
mapkey: ';bd',
siteName: 'baidu',
keywordRegex: getRegExp('www.baidu.com/s', 'wd'),
searchUrl: 'https://www.baidu.com/s?wd=%s'
},
{
commonUseMapKey: 'v',
mapkey: ';yt',
siteName: 'youtube',
keywordRegex: getRegExp('www.youtube.com/results', 'search_query'),
searchUrl: 'https://www.youtube.com/results?search_query=%s'
},
{
commonUseMapKey: 'c',
mapkey: ';gh',
siteName: 'github',
keywordRegex: getRegExp('github.com/search', 'q'),
searchUrl: 'https://github.com/search?o:desc&q=%s&s:stars&type:Repositories'
},
{
commonUseMapKey: 'v',
mapkey: ';bb',
siteName: 'bilibili',
keywordRegex: getRegExp('search.bilibili.com/all', 'keyword'),
searchUrl: 'https://search.bilibili.com/all?keyword=%s'
}
];
function getRegExp(urlBeforeParam, searchParamKey) {
//ep. ^http[s]{0,1}://www.google.com/search\?.*?[&]{0,1}q=([^&]*)?.*$
var regStr = '^http[s]{0,1}://' + urlBeforeParam + '\?.*?[&]{0,1}' + searchParamKey + '=([^&]*)?.*$';
return new RegExp(regStr);
}
function getCurrentKeywordAndMapkey() {
var currentURL = window.location.href;
for (var i = 0, len = switchSearchConfigs.length; i < len; i++) {
var searchConfig = switchSearchConfigs[i];
if (searchConfig.keywordRegex.test(currentURL)) {
var currentKeywordAndMapkey = {
keyword: RegExp.$1,
mapkey: searchConfig.mapkey
};
return currentKeywordAndMapkey;
}
}
}
function getTargetSearchSiteConfig(mapkey) {
for (var i = 0, len = switchSearchConfigs.length; i < len; i++) {
var searchConfig = switchSearchConfigs[i];
if (searchConfig.mapkey == mapkey) {
return searchConfig;
}
}
}
function switchSearchEngineWithKeywordByMapKey(mapkey) {
var currentKeywordAndMapkey = getCurrentKeywordAndMapkey();
if (!currentKeywordAndMapkey || currentKeywordAndMapkey.length < 1 || !currentKeywordAndMapkey.keyword || currentKeywordAndMapkey.keyword < 1) {
return;
}
switchSearchEngin(currentKeywordAndMapkey, mapkey);
}
function switchSearchEngin(currentKeywordAndMapkey, mapkey) {
var targetSearchSiteConfig = getTargetSearchSiteConfig(mapkey);
if (!targetSearchSiteConfig || targetSearchSiteConfig.searchUrl.length < 1) {
return;
}
var targetURLHref = targetSearchSiteConfig.searchUrl.replace('%s', currentKeywordAndMapkey.keyword);
window.location.href = encodeURI(decodeURI(targetURLHref));
}
function searchWithCopyWordsByMapKey(mapkey) {
var targetSearchSiteConfig = getTargetSearchSiteConfig(mapkey);
if (!targetSearchSiteConfig || targetSearchSiteConfig.searchUrl.length < 1) {
return;
}
Clipboard.read(function (response) {
var query = window.getSelection().toString() || response.data;
if (!query || query.length < 1) {
return;
}
var targetURLHref;
if (isUrl(query)) {
//如果复制的内容本身就是一个url,那么直接跳转。代替了常规的ctrl+t,ctlr+l,ctrl+v ,enter操作
targetURLHref = query;
} else {
targetURLHref = targetSearchSiteConfig.searchUrl.replace('%s', encodeURIComponent(query));
}
tabOpenLink(targetURLHref);
});
}
function isUrl(context) {
return /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/.test(context);
}
//unmap all key with ';' prefix of default settings
// ;fsDisplay hints to focus scrollable elements
// ;m把鼠标移出最近的元素
// ;w聚焦到主窗口
// ;pj从剪贴板恢复数据
// ;pf用yf复制出来的结果填充表单
// ;pp在当前页粘贴HTML
// ;重复相应的f/F
// ;j关闭下载完毕的提示框 [保留] 不能保留了。会影响 ;jd
// ;cp复制代理信息
// ;ap应用剪贴板中的代理信息
// ;s切换PDF阅读器
// ;t用谷歌翻译选中文本 [保留] 不能保留了。会影响 ;tb
// ;dh删除30天前的所有访问历史记录
// ;db从收藏夹里删除当前网址
// '<Alt-s>' 禁用启动插件,不要,基本没用。下面自动切换搜索引擎使用。
// 取消,占用`;`的快捷键。以及取消占用`s`的快捷键。
const unmaps = [
';fs', ';m', ';w', ';pj', ';pf', ';pp', ';cp', ';ap', ';s', ';dh', ';db', '<Alt-s>', ';t', ';j', 'sg', 'sd', 'sb', 'se', 'sw', 'ss', 'sh', 'sy', 'sjd', 'stb', 'sxg'
];
unmaps.forEach((u) => {
unmap(u);
});
// 最高频的搜索,最简单的按键。
mapkey('s', "快速网络搜索s", function () {
Front.openOmnibar({
type: "SearchEngine",
extra: "gg"
});
});
//remap ';' as search engine switch prefix
function bindMapKeyForSwitchSearchEngine() {
for (var i = 0, len = switchSearchConfigs.length; i < len; i++) {
var searchConfig = switchSearchConfigs[i];
if (!searchConfig.mapkey || searchConfig.mapkey.length < 1) {
continue;
}
//notice: use let instead of var
let mk = searchConfig.mapkey;
// 1. 使用当前的搜索关键字,换新的搜索引擎 。绑定 (';'+ 两个字母)的快捷键
mapkey(mk, '搜索<当前搜索关键字>内容 - ' + searchConfig.siteName, function () {
switchSearchEngineWithKeywordByMapKey(mk);
});
// 2. 使用当前选中的内容,换新的搜索引擎。 绑定 (';;'+ 两个字母)的快捷键
var mkForCopyWord = ';' + mk;
mapkey(mkForCopyWord, '搜索<选中>内容 - ' + searchConfig.siteName, function () {
searchWithCopyWordsByMapKey(mk);
});
// 3. 在当前页面打开搜索框,输入关键字,换新的搜索引擎。 绑定(';;;'+ 两个字母)的快捷键
var mkForInput = ';;' + mk;
//addSearchAlias(alias, prompt, url, suggestionURL, listSuggestion)
let searchAlias = mk.replace(';', '');
var url = searchConfig.searchUrl.replace('%s', '{0}');
var listSuggestion = url;
addSearchAlias(searchAlias, searchConfig.siteName, url, 's', listSuggestion);
mapkey(mkForInput, '搜索<输入>内容 - ' + searchConfig.siteName, function () {
Front.openOmnibar({
type: "SearchEngine",
extra: searchAlias
});
});
}
}
// 约定,所有的新增的关键字搜索切换,使用';'前缀 。 ep. 百度= ;bd YouTube= ; yt
bindMapKeyForSwitchSearchEngine();
//auto switch by default order
function switchSearchEngineWithKeywordByOrder() {
var searchOrder = [';gg', ';bd', ';sm'];
var currentKeywordAndMapkey = getCurrentKeywordAndMapkey();
if (!currentKeywordAndMapkey && !currentKeywordAndMapkey.mapkey) {
return;
}
for (var i = 0, len = searchOrder.length; i < len; i++) {
if (currentKeywordAndMapkey.mapkey == searchOrder[i]) {
var loopIndex = (i + 1) % searchOrder.length;
var targetMapkey = searchOrder[loopIndex];
switchSearchEngin(currentKeywordAndMapkey, targetMapkey);
return;
}
}
}
mapkey('<Alt-s>', '循环切换搜索引擎', switchSearchEngineWithKeywordByOrder);
//open muti search engine
function openMutiSearchEngine(commonUseMapKey) {
if (!commonUseMapKey) {
return;
}
var currentKeywordAndMapkey = getCurrentKeywordAndMapkey();
if (!currentKeywordAndMapkey && !currentKeywordAndMapkey.mapkey) {
return;
}
var encodeKeyWord = encodeURIComponent(decodeURIComponent(currentKeywordAndMapkey.keyword));
for (var i = 0, len = switchSearchConfigs.length; i < len; i++) {
var switchSearchConfig = switchSearchConfigs[i];
if (commonUseMapKey == switchSearchConfig.commonUseMapKey && currentKeywordAndMapkey.mapkey != switchSearchConfig.mapkey) {
var targetURLHref = switchSearchConfig.searchUrl.replace('%s', encodeKeyWord);
tabOpenLink(targetURLHref);
}
}
}
function bindMapKeyForOpenMutiCommonUse() {
var commonUse = new Map();
for (var i = switchSearchConfigs.length - 1; i >= 0; i--) {
var switchSearchConfig = switchSearchConfigs[i];
if (!switchSearchConfig.commonUseMapKey || switchSearchConfig.commonUseMapKey == '') {
continue;
}
if (commonUse.has(switchSearchConfig.commonUseMapKey)) {
var str = commonUse.get(switchSearchConfig.commonUseMapKey) + "#" + switchSearchConfig.siteName;
commonUse.set(switchSearchConfig.commonUseMapKey, str);
} else {
commonUse.set(switchSearchConfig.commonUseMapKey, switchSearchConfig.siteName);
}
}
for (var [key, value] of commonUse) {
let bindkey = 'oa' + key;
let desc = '同时打开:' + value;
let k = key;
mapkey(bindkey, desc, function () {
openMutiSearchEngine(k);
});
}
}
bindMapKeyForOpenMutiCommonUse();
//=====================faster search engine swither====================end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment