MCPcopy Index your code
hub / github.com/brookhong/Surfingkeys

github.com/brookhong/Surfingkeys @main sqlite

repository ↗ · DeepWiki ↗
1,454 symbols 3,715 edges 71 files 31 documented · 2%
README

Surfingkeys - Expand your browser with javascript and keyboard.

Node CI

Surfingkeys is another web browser(including Google Chrome, Chromium based browsers, Firefox, Safari) extension that provides keyboard-based navigation and control of the web in the spirit of the VIM editor. But it's not for VIM users only, it's for anyone who just needs some more shortcuts to their own functions.

Surfingkeys is created with all settings described in Javascript, so it's easy for anyone to map any keystrokes to their own defined Javascript function. For example,

api.mapkey('<Ctrl-y>', 'Show me the money', function() {
    api.Front.showPopup('a well-known phrase uttered by characters in the 1996 film Jerry Maguire (Escape to close).');
});

Surfingkeys is doing its best to make full use of keyboard for web browsing, but there are some limitations from Google Chrome itself, please see Brook Build of Chromium for a more thorough experience.

Installation

Feature availability

Features \ Browsers Chromium family (above 45) Firefox (above 57) Safari (above 15)
Follow links Y Y Y
Surfingkeys modes Y Y Y
Omnibar Y Y partly
Search selected with Y Y Y
Vim-like marks Y Y Y
Switch tabs Y Y Y
Windows management Y Y N
Commands Y Y Y
Smooth scroll Y Y Y
Session management Y Y Y
Repeats action by pressing number before mapkey Y Y Y
Hotkey to toggle Surfingkeys Y Y Y
VIM editor and Emacs editor Y Y Y
Dot to repeat previous action Y Y Y
Capture page Y Y Y
PDF viewer Y N N
Sync across devices Y N Y
Tab Groups Y Y N
Proxy Y N N
Markdown preview Y Y N

TABLE OF CONTENTS

Feature list

  • All settings are set up within a javascript file, which makes it easy to create mapping to user customized function.
  • A large cursor in visual mode, which makes visual mode better.
  • Search selected with, which works in both normal mode and visual mode.
  • Help messages are automatically generated for mappings.
  • * to search word under cursor in visual mode.
  • Scroll actions like page up/down (e d) work for not only top window but also scrollable DIV.
  • w to switch frames if there is.
  • Session management
  • A versatile bookmark/url finder
  • Count prefixes to repeat actions
  • Use vim editor to edit input on page
  • Dot to repeat previous action
  • ;pm to preview markdown
  • Emoji completion in Insert mode
  • Rich hints for keystroke
  • Everything in Surfingkeys works for PDF
  • Regional Hints mode
  • Chat with LLM

Quick start

After you install the extension from Chrome Web Store or Firefox Add-ons, open a site you'd like. Then press ? or u to take a quick look on the default mappings first. Press Esc to hide the usage popover.

Try some mappings described in the usage popover. For example, press e to scroll a page up, d to scroll a page down, ;e to open settings page.

  • ? to show help help
  • t to search bookmarks/history urls
  • / to find in current page find
  • f to follow links follow
  • v to toggle visual mode visual
  • T to switch tabs tabs

Surfingkeys modes

There are three modes in Surfingkeys: normal, visual and insert.

Normal mode, the default mode.

When you open a page, it enters normal mode automatically. All mappings added with mapkey work in this mode.

Visual mode, the mode for text selection, and actions on the selected text.

Press v to toggle visual mode. You'll see an indicator at bottom of current page - Caret or Range, and a large cursor on page. The cursor is made large for visibility, as sometimes it's not easy for human to locate a normal cursor on a web page.

Caret indicates that cursor is moved when you press jkhl, Range indicates that you'll select text when moving cursor.

Now here is a small practice,

  1. press v you'll see Caret
  2. use the VIM key bindings to move cursor to some where.
  3. press v again, you'll see Range.
  4. use the VIM key bindings to select some text.
  5. press sg to see what will happen.
  6. press v again to back to normal mode.

All mappings added with vmapkey work in this mode, with some built-in mappings like those in VIM - j k h l b w 0 $ etc.

search_selected

  • zz make cursor at center of window.
  • f forward to next char.
  • F backward to next char.
  • ; repeat latest f, F.
  • , repeat latest f, F in opposite direction.

Hints mode

Press f to enter Hints mode to follow links. There are several other keystrokes to enter Hints mode with some different behavior, such as cf for continuous following, af for active following.

Default hint characters for links are asdfgqwertzxcvb, it quits when a non-hint key is pressed. Add below line to your settings to make it right hand:

api.Hints.setCharacters('yuiophjklnm'); // for right hand

When hints are overlapped, press Shift to flip them. Hold space to hold hints temporarily, release space to restore hints.

Hints are placed in center of target links, you could add below line in your settings to let them aligned left.

settings.hintAlign = "left";

Regional Hints mode

Press L to enter regional Hints mode by picking a visually large element. There are some built-in actions in regional Hints mode,

  • Esc to exit regional hints mode
  • ct to copy text from target element
  • ch to copy HTML from target element
  • d to delete target element
  • l to chat with AI about the text of the element

Demo on YouTube

Insert mode

When focus is switched into any editable element by whatever means(i hints or f hints or mouse click), Insert mode is on.

All mappings added with imapkey work in this mode.

  • Ctrl - i to open vim editor to edit.
  • Ctrl - ' to toggle quotes in an input element, this is useful for search engines like google.
  • Ctrl-e move the cursor to the end of the line.
  • Ctrl-a move the cursor to the beginning of the line, use Ctrl-f in Windows to avoid conflict with select all.
  • Ctrl-u delete all entered characters before the cursor.
  • Alt-b move the cursor Backward 1 word.
  • Alt-f move the cursor Forward 1 word.
  • Alt-w delete a word backwards.
  • Alt-d delete a word forwards.

imap and iunmap for insert mode.

api.imap(',,', "<Esc>");        // press comma twice to leave current input box.
api.imap(';;', "<Ctrl-'>");     // press semicolon twice to toggle quote.

Emoji completion

When user inputs a colon and 2(set by settings.startToShowEmoji) characters such as :gr in insert mode, Surfingkeys will try to find matched emoji, and list them out if there are some found.

emoji

If you want this feature disabled completely, use below settings:

api.iunmap(":");

If you'd like emoji suggestions popup as soon as you input colon, use below:

settings.startToShowEmoji = 0;

Complete list of Emoji

Find

Find is not actually a mode, it just another way to enter visual mode. Press / to open find bar, which sits at almost the same position with Mode indicator, type something there. All occurrences of your input will be highlighted. Press Enter to finish the finding, and you're in Caret visual mode now, press n to find next, N to find previous.

Press Ctrl-Enter to find exactly the whole word input, like with the input \bkeyword\b.

PassThrough mode

To press Alt-i to enter PassThrough mode gives you a chance to temporarily suppress SurfingKeys, which means Surfingkeys will not care any key press until leaving this mode by pressing Esc. In this mode, you could use built-in shortcuts from any site itself. Please see Feature Request: implement Vimium-style insert mode · Issue #656 for why we brought this in and the difference between Alt-i and Alt-s.

To press p to enter ephemeral PassThrough mode, which will automatically quit after 1 second.

Lurk mode

User can specify the pages where Surfingkeys will lurk until it is called out by Alt-i or p(for ephemeral case), such as

settings.lurkingPattern = /https:\/\/github\.com|.*confluence.*/i;

If the loading page matches with the lurkingPattern, Surfingkeys will enter lurk mode by default, in which mode only Alt-i and p are registered by Surfingkeys to activate normal mode. When user presses Esc or timeout, Surfingkeys reverts back to lurk mode.

API lmap can be used to change the shortcuts, for example,

api.lmap("<Alt-j>", "<Alt-i>");

The extension icon in toolbar reflects current status of Surfingkeys,

  • Grey -- disabled.
  • Half Grey/Half Color -- lurking.
  • Color -- enabled.

Omnibar

The omnibar provides kinds of functions that need user input, for example,

  • Open url(from both bookmarks and history) with t
  • Open bookmarks with b
  • Open search engines with og / ow ...
  • Open commands with :

key bindings in Omnibar

  • Enter to open selected item and close omnibar.
  • Ctrl-Enter to open selected item, but keep omnibar open for more items to be opened.
  • Shift-Enter to open selected item in current tab and close omnibar. If you'd like to open in current tab by default, please use go.
  • Tab to forward cycle through the candidates.
  • Shift-Tab to backward cycle through the candidates.
  • Ctrl-. to show results of next page
  • Ctrl-, to show results of previous page
  • Ctrl-c to copy all listed items

In omnibar opened with t:

Ctrl - d to delete from bookmark or history

In omnibar opened with b:

Ctrl - Shift - <any letter> to create vim-like mark

search_engine

cmap could be used for Omnibar to change mappings, for example:

api.cmap('<Ctrl-n>', '<Tab>');
api.cmap('<Ctrl-p>', '<Shift-Tab>');

Add bookmark

ab is a shortcut to bookmark current page. An Omnibar is displayed for you to choose a folder to place the new bookmark after you pressed ab. If you want to place the new bookmark into a new folder, you could input folder name -- which must be ended with / in Omnibar. For example, I choose folder /Bookmarks Bar/tool/, and append abc/, then current page will be bookmarked into /Bookmarks Bar/tool/abc/. If there is no / behind abc, abc will be used as title of the new bookmark.

Search selected with

My favorite feature from when I was using Firefox. For both Firefox and Chrome, the extensions make it through context menu. Surfingkeys makes it through key mappings. By default, when you press sg in normal mode, it will search selected text with google, if there is none sel

Extension points exported contracts — how you extend this code

NvimEvents (Interface)
(no doc)
src/nvim/types.ts

Core symbols most depended-on inside this repo

push
called by 165
src/pages/pdf_viewer.mjs
RUNTIME
called by 160
src/content_scripts/common/runtime.js
mapkey
called by 147
src/content_scripts/common/api.js
get
called by 116
src/pages/pdf_viewer.mjs
dispatchSKEvent
called by 104
src/content_scripts/common/runtime.js
_on
called by 91
src/pages/pdf_viewer.mjs
dispatch
called by 75
src/pages/pdf_viewer.mjs
setSanitizedContent
called by 61
src/content_scripts/common/utils.js

Shape

Method 679
Function 628
Class 146
Interface 1

Languages

TypeScript100%

Modules by API surface

src/pages/pdf_viewer.mjs973 symbols
src/content_scripts/common/utils.js61 symbols
src/background/start.js54 symbols
src/nvim/screen.ts32 symbols
src/content_scripts/ui/frontend.js30 symbols
src/content_scripts/ui/omnibar.js27 symbols
src/content_scripts/common/api.js23 symbols
src/content_scripts/common/hints.js19 symbols
src/nvim/input/keyboard.ts16 symbols
src/background/llm.js16 symbols
src/content_scripts/options.js15 symbols
src/content_scripts/common/visual.js15 symbols

Dependencies from manifests, versioned

@babel/plugin-proposal-class-properties7.14.5 · 1×
@babel/plugin-proposal-optional-chaining7.14.5 · 1×
@babel/plugin-transform-runtime7.15.0 · 1×
@babel/preset-env7.15.0 · 1×
@babel/preset-typescript7.15.0 · 1×
@msgpack/msgpack2.7.0 · 1×
@pixi/app7.4.0 · 1×
@pixi/constants7.4.0 · 1×
@pixi/core7.4.0 · 1×
@pixi/display7.4.0 · 1×
@pixi/extensions7.4.0 · 1×
@pixi/graphics7.4.0 · 1×

For agents

$ claude mcp add Surfingkeys \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact