Skip to content

Keybindings ​

The keymap follows PhpStorm wherever the terminal allows. Every action is rebindable — see Custom keymap below, or use Settings → Keybindings (Ctrl+,) to capture a new key interactively.

Heavily modified chords (e.g. Alt+Shift+↑) work best in terminals with the Kitty keyboard protocol (kitty, WezTerm, iTerm2 3.5+, foot, Ghostty).

On macOS the function keys are media keys unless System Settings → Keyboard → Use F1, F2, etc. as standard function keys is on — otherwise F11 dims the display rather than dropping a bookmark, and the app never sees it. Either turn that setting on, hold Fn, or rebind: this map uses F2, F5–F12 for problems, run/debug, bookmarks, the menu, panes and the context menu, so a Mac with the default keyboard setting will feel like several of them do nothing.

macOS: Cmd keys ​

On a Mac the main shortcuts also answer to Cmd. Every key in the tables below keeps working, and these chords are added:

Cmd keyActionCmd keyAction
Cmd+CCopy (editor and file tree)Cmd+FFind in file
Cmd+XCut (editor and file tree)Cmd+RReplace in file
Cmd+ASelect allCmd+DDuplicate line or selection
Cmd+ZUndoCmd+/Toggle comment
Cmd+Shift+ZRedoCmd+LGo to line
Cmd+SSaveCmd+ERecent files
Cmd+Alt+SSave allCmd+Shift+CCopy path

Cmd+V is not among them on purpose: the terminal turns it into a paste of the system clipboard, which lands at every caret like Ctrl+V does and joins the paste history. On the keymap page in Settings → Keybindings, the Mac's delete key (⌫) resets an action to its default.

A terminal only passes a Cmd chord on when it speaks the Kitty keyboard protocol and does not keep the chord for itself. Terminal.app never passes one on, and iTerm2 keeps nearly all of them; Ghostty, kitty and WezTerm each keep a few. Menus and hints therefore name the Ctrl key until a Cmd chord has actually reached Porta, and from then on name that chord. To hand a chord to Porta, unbind it in the terminal — or, in Ghostty (and cmux, which reads the same settings), make it performable, so it still copies when the terminal has a selection of its own:

# Ghostty: ~/.config/ghostty/config — cmux: ~/Library/Application Support/com.cmuxterm.app/config.ghostty
keybind = performable:super+c=copy_to_clipboard
keybind = super+a=unbind
keybind = super+f=unbind
keybind = super+d=unbind

In other terminals, remove the chord from the terminal's own key settings.

Write Cmd chords as cmd+… (or super+…) in a custom keymap. The macOS keymap applies on its own on a Mac; the Keymap setting (keymapPlatform) picks another platform's, or the Mac's when you reach a Linux machine over SSH from a Mac keyboard.

Windows and Linux: keys the terminal keeps ​

A terminal keeps some chords for itself, and Porta never sees them. Where one of those is a Porta key, the action gains a second key the terminal passes on, and the hints name that one:

ActionWindowsLinuxKept by
Show quick fixesAlt+I (and Alt+Enter)Alt+EnterWindows Terminal: Alt+Enter is full screen
Paste from historyAlt+Y (and Ctrl+Shift+V)Alt+Y (and Ctrl+Shift+V)every major terminal: Ctrl+Shift+V is its paste
Git: PushAlt+K (and Ctrl+Shift+K)Alt+K (and Ctrl+Shift+K)Windows Terminal and Konsole: clear the screen

Without the Kitty keyboard protocol a terminal cannot tell Ctrl+Shift+K from Ctrl+K at all, which is one more reason the Alt keys lead. Other chords a terminal keeps — Ctrl+Shift+F, Ctrl+Shift+T, Ctrl+Shift+N and Ctrl+- in GNOME Terminal and Konsole, Ctrl+Shift+A, Ctrl+Shift+F and Ctrl+, in Windows Terminal — have no free key to move to; reach those actions from the menu bar or Find Action, or remove the chord from the terminal's own key settings.

Application ​

KeyAction
Ctrl+QQuit (twice within 3 s to discard unsaved changes)
Ctrl+TSwitch focus between file tree and editor
F6 / Ctrl+F6Cycle focus forward / backward across panes (in the git and settings views, cycles their panes)
Ctrl+F10Open the context menu for the focused pane (editor: at the caret; tree: at the selected node; image/help tab: the tab menu)
Alt+HomeThe breadcrumb trail as a menu: a folder or file is shown in the tree, a symbol is gone to
Alt+EndThe status bar's menus — the branch's, a remote server's, a participant's — in one menu
Shift+F11 / Shift+F12Shrink / grow the focused pane (file tree, git and settings sidebars, the bottom panels, and the editor beside a live preview)
Ctrl+Shift+'Maximize the open bottom panel; press again to put it back at the height it had
Ctrl+Shift+LCycle the line-number mode (absolute → relative → off)
Alt+PageDown / Alt+PageUpNext / previous panel on the bottom dock
Ctrl+Shift+F4Close the bottom dock's tab on display — a results tab, or a terminal session (its process stops)
Alt+ZToggle soft wrap — the softWrap setting, so it is saved (off by default; horizontal scroll is disabled while it is on, in the editor and the diffs alike)
Alt+VToggle code vision — the server's "3 usages" lines above declarations (off by default)
Ctrl+Alt+VStep a previewed file (Markdown, SVG, a Graphviz or PlantUML diagram) through the text alone, the text beside its live preview, and the preview alone — the same as the Editor Split Preview toggles at the right of the breadcrumbs bar
F10Arm the application menu: File is lit, ←/→ move along the titles, ↓/Enter/Space or a title's underlined letter opens one; F10 or Esc again lets go
a menu's underlined letterRun that item (in a select's list, a letter jumps to the next option starting with it)
F1Open the documentation browser (these guides, fully rendered; see the Help viewer table below)
Ctrl+Shift+AFind Action (command palette)
Ctrl+Shift+ESearch Everywhere
Ctrl+,Settings (inside: Ctrl+F finds a setting — or filters the Keybindings list in place, R resets the selected row, 2 jumps to Keybindings and 1 back to General, [/] change a value, Tab switches pane)
Ctrl+Alt+DGit view (changes, staging, history)
Ctrl+\`` / Alt+F12`Toggle the integrated terminal
Ctrl+Shift+\`` / Alt+F11`Open a new terminal session
Ctrl+PageDown / Ctrl+PageUpNext / previous terminal session (Ctrl+Shift+W closes one)
Alt+1Focus the project tree
Ctrl+X / Ctrl+C / Ctrl+VIn the file tree: cut / copy / paste the selected files. The same chords move text in the editor — which you get depends on what has focus
Delete (Cmd+Backspace on a Mac)In the file tree: delete the selected files, or the folder under the cursor — after a y/N question
Ctrl+Shift+CIn the file tree: copy the selected row's path (elsewhere, the open file's)
Alt+Insert / Ctrl+NIn the file tree: new file or folder in the selected folder
Shift+F6In the file tree: rename the selected file or folder (in the editor it renames the symbol)
Alt+6Problems panel
Alt+9Notification log — every flash the status bar showed and you missed
Alt+DDismiss the newest notification (the top card)
Ctrl+Alt+HLocal history
Ctrl+Alt+ZUndo the last multi-file refactoring, across every file it touched (Ctrl+Z is per file); refuses and names the file if anything changed since

Files and buffers ​

KeyAction
Ctrl+SSave
Ctrl+Alt+SSave all
Ctrl+Shift+CCopy the active file's path, relative to the project
Ctrl+Alt+Shift+CCopy a reference to the caret — the enclosing symbol (App\Svc::run), or path:line when there is none
Ctrl+Alt+Shift+SNew scratch file — pick a language, get an empty buffer in <home>/.porta/scratches/
Ctrl+Shift+OOpen project — pick one you have opened before, or type a path. The current session ends the way a quit does (buffers saved, session written) and the IDE reopens on the new root
Ctrl+Alt+Shift+OOpen remote project — type user@host:/path or an ssh://, sftp://, ftp:// or ftps:// URL; the SSH and FTP plugins serve it. Open Project's path prompt takes the same
Ctrl+Shift+N / Ctrl+PGo to file (fuzzy finder) — from anywhere: the tree, a viewer, the editor
Ctrl+ERecent files popup (Ctrl+E again cycles, Enter opens, and typing filters)
Ctrl+← / Ctrl+→Previous / next editor tab
Ctrl+Shift+← / Ctrl+Shift+→Move the active tab left / right
Ctrl+F4 / Alt+WClose the active buffer (unsaved changes prompt)
Ctrl+Alt+W / Ctrl+Alt+Shift+WClose the other tabs / close all tabs (unsaved changes prompt). Close Tabs to the Left/Right and Pin / Unpin Tab have no default key — they are in Find Action, and bindable
Ctrl+Alt+XReopen the active tab as text (for a file a viewer plugin claimed)

Editing ​

KeyAction
Ctrl+Z / Ctrl+Shift+ZUndo / redo (typing runs coalesce)
Shift+EnterStart a new line below this one, whatever column the caret is in (plain Enter still splits the line)
Ctrl+Alt+EnterStart a new line above this one
Ctrl+Shift+EnterComplete the current statement — close its brackets, add the terminator (or open a block for if/for/…), and move to the next line
Ctrl+C / Ctrl+X / Ctrl+VCopy / cut / paste (also the system clipboard via OSC 52)
Ctrl+Shift+VPaste from clipboard history — the last 20 things you copied, newest first, filterable; newlines show as ⏎
Ctrl+DDuplicate line or selection
Ctrl+Y / Ctrl+Shift+KDelete line or selected lines
Ctrl+KDelete to end of line
Alt+BackspaceDelete word backwards
Ctrl+/ / Ctrl+-Toggle line comment (in a language whose only comment form is a block — Twig, CSS, HTML, Markdown — each line is wrapped in that block instead)
Ctrl+Shift+/Toggle block comment around the selection, or the current line's content; falls back to the line comment where the language has no block form
Alt+Shift+↑/↓Move line or selection up / down
Ctrl+Shift+↑/↓Move statement up / down (hops blank-line gaps)
Ctrl+Shift+JJoin the selected lines (or this line and the next) into one
Ctrl+Shift+SSort the selected lines
Ctrl+Shift+UToggle the case of the selected lines
Ctrl+Shift+MJump to the bracket matching the one at the caret
Ctrl+W / Ctrl+Shift+WExtend / shrink selection (word → brackets → line → file)
Ctrl+Alt+TSurround selection (bracket pair, quotes, if/foreach/try)
Ctrl+.Collapse / expand the code fold at the caret
Ctrl+Shift+-Fold all — collapse every region in the file
Ctrl+Shift+=Unfold all — PhpStorm's Ctrl+Shift+Plus, as the terminal reports it (unshifted)
Ctrl+ASelect all
HomeSmart home (first non-blank, then column 0)
Tab / Shift+TabIndent; next / previous tab stop while a snippet is active

Multiple carets ​

KeyAction
Ctrl+Alt+↑ / Ctrl+Alt+↓Add a caret above / below
Alt+JAdd a caret at the next occurrence of the word
Ctrl+Alt+Shift+JAdd carets at all occurrences
EscCollapse back to a single caret
Alt+ClickAdd / remove a caret (mouse)
Alt+CColumn selection mode — then Shift+arrows build the rectangle (COLUMN shows in the status bar)
Alt+Shift+dragColumn (rectangular) selection (mouse)

Code intelligence (LSP) ​

KeyAction
Ctrl+SpaceTrigger completion (auto after -> and ::)
PgUp / PgDnA page of the completion list
Ctrl+↓ / Ctrl+↑Scroll the completion's docblock
Alt+↓ / Alt+↑Next / previous overload, while the signature popup shows more than one
Ctrl+B / F12Go to declaration
Ctrl+Alt+BGo to implementation (chooser when several)
Ctrl+Shift+BGo to type definition
Ctrl+Alt+LeftNavigate back after a definition jump
Ctrl+Shift+IPeek definition (inline; Enter jumps)
Alt+F7Find usages
Ctrl+Shift+H / Ctrl+Alt+Shift+HCallers of / calls from the symbol at the caret
Shift+F6Rename symbol (cross-file WorkspaceEdit)
Alt+EnterQuick fixes / code actions (headed by the line's problems when diagnostic messages are set to menu)
Alt+Shift+EnterApply the first fix for the problem at the caret, without the list — the one the problem card's Fix: line names. Needs a terminal that reports modifiers on Enter (kitty's keyboard protocol, or xterm's modifyOtherKeys); elsewhere it arrives as Alt+Enter and opens the list
Ctrl+Alt+Shift+TRefactor This
Ctrl+Alt+NInline
Ctrl+Alt+OOptimize imports (source.organizeImports; applied straight away when the server offers one)
Ctrl+Shift+PParameter info — re-summon the signature popup (PhpStorm's Ctrl+P, which Go to File owns here)
Shift+F1Quick documentation, in a popup under the caret, headed by the problems there when the caret is on one (↑/↓, PgUp/PgDn or the wheel scroll it; Esc or any other key closes it)
Ctrl+F1 / Alt+QError description: the problems at the caret, in full, with their fix. On macOS, where Ctrl+F1 is the system's, the hint names Alt+Q
Ctrl+F12File structure popup (type to filter — the symbol's KIND counts, so method narrows a class to its methods)
Alt+7Structure panel (persistent, on the dock)
F2 / Shift+F2Next / previous problem in this file (wraps, and says so)
Alt+↓ / Alt+↑Next / previous declaration — class or method (wraps, and says so)
F11Toggle a bookmark on the caret's line
Alt+2Bookmarks — every mark across the project
Alt+8TODOs — the bundled scan of TODO/FIXME comments
Alt+5Recent Locations — the places you jumped away from
Ctrl+Shift+BackspaceLast edit location — back to what you were writing; press again to walk further back
Alt+F1Select the opened file in the tree
Ctrl+Alt+Shift+NGo to symbol in project
Ctrl+Alt+LReformat file (or the selection when one exists)
KeyAction
Ctrl+F / Ctrl+RFind / find-and-replace in file (F3/Shift+F3 cycle, Tab switches field, Alt+X regex, Alt+W whole word, Alt+C match case, Alt+R replace, Alt+A replace all, Alt+Enter select all occurrences, Alt+↑/Alt+↓ recall an earlier query)
Ctrl+Shift+FFind in Files — see the table below
Ctrl+GGo to line
Ctrl+Shift+TGo to test / go to tested class
Ctrl+UGo to the super method — the parent class, interface or trait that declares the one under the caret (resolved from the project's own files; no language server answers this)

Both find surfaces share one query history — what you looked for in this project, whichever surface you looked from — kept in .porta/search-history.json and recorded when you press Enter, not as you type.

Inside Find in Files ​

The option toggles above the results are clickable, and these are their keys. Note that regex is Alt+X in the in-file find bar and Alt+R here: Alt+R replaces in the bar, and neither surface can have both.

KeyAction
Alt+R / Alt+C / Alt+WRegex (.*) / match case (Aa) / whole word (\b)
Alt+VPreserve case when replacing (Pc) — replacing foo in Foo writes Bar, not bar
Alt+TCycle where matches count: anywhere (·"), only inside comments and strings (i"), or everywhere except them (x") — the classification is per file and language-aware
Alt+SCycle the search scope (whole project, or one you saved)
Alt+↑ / Alt+↓Recall an earlier query into the field
Shift+EnterA literal newline in the query — how you search for text spanning two lines
Enter / Alt+EnterOpen the selected result / send every result to the Find panel
TabMove between the find, replace and file-mask fields
DeleteExclude the selected match from Alt+A's bulk replace
Alt+AReplace across the project (every match still included)

Run, debug, git ​

KeyAction
Ctrl+Shift+RRun… (current file, composer script, Makefile target)
Shift+F10Repeat the last run
Shift+F9Debug the current file
Ctrl+F8Toggle a breakpoint (also: click the gutter)
F8 / F7 / Shift+F8Step over / into / out (while paused)
F9Resume (while paused)
Ctrl+F9Pause the program where it is (while it runs)
Ctrl+F2Stop the debugger (while a session runs)
Alt+F8Evaluate an expression (while paused)
Ctrl+Shift+F5Restart the debugger (while a session runs)
Ctrl+Shift+F8Edit the breakpoint's condition, hit count or log message
Ctrl+Shift+F9Add a watch expression
eEdit the selected variable's value (in the Debug panel's Variables)
Alt+F9Run to the caret's line (while paused)
F7 / Shift+F7Next / previous merge conflict (when not debugging)
Alt+MResolve the conflict under the caret (ours / theirs / both)
Ctrl+Alt+Shift+↓ / Ctrl+Alt+Shift+↑Next / previous change against HEAD (click a gutter change mark to see it and revert it)

The debugger's F7/F8/F9/Shift+F8/Ctrl+F2 keys are gated on a running session — without one they fall through to their editor meanings.

Results panels ​

The shared list at the bottom — Find in Files, Problems, Usages, Structure, TODOs, Bookmarks and a plugin's own. Whichever tool filled it, these are its keys.

KeyAction
↑ / ↓, PageUp / PageDownMove the selection (in the Debug panel's call stack, watches and variables too)
EnterOpen the row's file at its line
Alt+GCycle how rows are grouped: by file, by directory, or nested
Alt+ECollapse every group, or expand them all when they are already collapsed
Alt+MShow or hide the source lines around the selected match
F5Run the search again and refresh the rows
Alt+XWrite a Find in Files result set to a file and open it (inert on the other tools, which have no export to offer)
typeFilter the rows, where the tool offers a filter (Find in Files, Problems, Usages, Structure)
EscClear the filter, or close the panel when there is none

File tree ​

KeyAction
↑ / ↓, PageUp / PageDownMove the selection
Shift+↑ / Shift+↓Extend the selection to more than one file
← / →Collapse / expand a directory
EnterOpen file / toggle directory
rReload the tree

Several files can be selected at once — Shift+↑/Shift+↓, or Ctrl+Click to add one and Shift+Click to take a range. A modified click only selects: it does not open the file, because the point of a pair is to act on both. Moving the cursor without a modifier drops back to one file.

With exactly two selected, Compare Selected Files — on the Git menu and on a tree row's right-click — diffs them into a Compare panel (git diff --no-index, so neither file has to be tracked, though the git plugin still wants a repository around it). Right-clicking inside the selection keeps it; right-clicking elsewhere collapses to the row under the pointer.

Help viewer ​

When the F1 documentation browser is active:

KeyAction
Tab / Shift+TabCycle through the page's links (scrolling the focused one into view)
Enter (or a click)Follow the focused link — doc pages render in place, http(s) links open in the browser
Backspace / Ctrl+Alt+LeftBack to the previous page (scroll position restored)
Arrows, PageUp/PageDown, Home/End, wheelScroll

The header row above the page is clickable: ‹ / › navigate back and forward through the history, and the breadcrumb mirrors the page's place in the docs file tree (Documentation › folder › page) — the root and any folder with a README.md index navigate on click, and clicking the current page scrolls back to the top. Following a link clears the forward trail, like a browser. All navigation happens inside the single Documentation tab.

Tab-management keys (Ctrl+←/→, Ctrl+F4…) keep working on the help tab, and Go to File (Ctrl+P) works there as it does everywhere.

A Markdown file's live preview reads the same way once it has the keys (F6, or a click on its navigation bar — a click on its text instead puts the editor's caret on the word clicked): the same keys, the same header — its breadcrumb walks the project instead (project › folder › page) — and Ctrl+F finds in the rendered page. A link to another Markdown file opens that file's tab, with the preview keeping the keys; Backspace walks back through the files followed that way. Any other file opens in the editor.

Plugin keys ​

A bundled plugin's keys are in its own guide, beside what they do: the Git view, the Review view, the image and graph viewers, agent changes, and the analyzers' and formatters' run commands — Mago, PHPStan, Psalm, PHP CS Fixer and PHPantom. Every one of them is rebindable here like a core key.

Mouse ​

Every list popup filters as you type — file structure, recent files, quick fixes, Run…, the scratch-file languages, a plugin's own list. The typed text shows above the rows, Backspace widens it again, and Esc clears the filter before it closes the popup, so a typo never costs you the list. The match is case-insensitive and covers the row's label and its right-hand hint.

SGR mouse reporting (modes 1000/1003/1006) is enabled: click to place the cursor, drag to select (double-click a word, triple-click a line, Shift+Click extends), wheel to scroll, hover highlights, click tree entries / tabs / menu items / panel rows, drag pane separators to resize, and right-click for a context menu. In the file tree, Ctrl+Click adds an entry to the selection and Shift+Click takes the range from the last one. Right-click the project name at the top of the tree for every folder beside the project: pick one to close this project and open that one (the same switch as Ctrl+Shift+O, unsaved edits and the trust question included). A results row, or a debugger frame, offers Copy Path and Copy Relative Path for the file it names, with whatever plugins add for a file.

Dragging in the file tree moves files: onto a folder to move, onto the editor to open, Alt held at the release to copy, Esc to abandon. The tree scrolls while you hold the pointer at its top or bottom edge, and a collapsed folder opens if you rest on it, so the destination need not be on screen when you start. docs/editor.md has the rest.

The status bar's right-hand cells are clickable too: the error/warning counts open Problems, the line:col position opens Go to Line, and the LSP:<status> cell opens the LSP server log. On the left, the file's path is a way back to the tree: double-click it to expand the tree down to the file and select it (focus stays in the editor, as with a double-clicked tab), or right-click it for Select Opened File in Tree (Alt+F1), Copy Path and Copy Relative Path.

Custom keymap ​

Override any action in .porta.json (project root):

json
{
    "keymap": {
        "duplicate_line": ["ctrl+shift+d"],
        "save": ["f10", "ctrl+s"]
    }
}

Action ids are listed in Porta\Config\ActionCatalog::ACTIONS (they match the tables above); unknown ids are reported in the status bar at startup. Plugin commands are rebindable through their namespaced id ("php-cs-fixer:fix": ["ctrl+alt+f"]). Changes made in the file apply on the next launch; Settings → Keybindings writes the same block for you after capturing a keypress, and applies it at once.

On that page, Enter captures a new key and Del (⌫ on a Mac) puts the action back to its shipped default, at once, removing its line from the file — and dropping the whole keymap block once its last line goes. Rows a config file overrides are drawn in the modified colour, so the ones you have changed are the ones you can pick out. This matters beyond tidiness: an override is a pin. Whatever the file says survives every future change to the default, silently, including a binding you set to the value it already had.

Released under the MIT License.