for fast bulk changes across your code
Typing the same change ten times by hand wastes time that PhpStorm's multi-cursor editing and column selection handle in seconds. Together, both techniques cover nearly every repetitive text change in the editor.
Table of Contents
- 1. Why manual bulk changes are a time and error risk
- 2. Placing cursors manually at arbitrary positions
- 3. Select All Occurrences: every match at once
- 4. Column selection: a rectangular selection independent of line content
- 5. Practical example: reformatting arrays quickly
- 6. Combining with Live Templates and structural navigation
- 7. Limits and common pitfalls
- 8. The most important shortcuts at a glance
- 9. When a regex replacement is still the better choice
- 10. Summary
- 11. FAQ
1. Why manual bulk changes are a time and error risk
Repetitive changes like renaming ten similar array keys, adding a prefix to a list of constants, or adjusting twenty nearly identical lines in a configuration file come up constantly in day-to-day PHP work. Editing line by line by hand not only costs time but also raises the risk of missing a line or introducing a typo somewhere that only surfaces at the next test run.
PhpStorm offers two complementary tools for this: multi-cursor editing places several independent carets that all react to keyboard input in parallel, while column selection allows a rectangular text selection across multiple lines, independent of the actual line content. Anyone who masters both techniques can handle changes that would be too coarse for a regex find-and-replace and too slow for manual editing, all in a single fluid step.
2. Placing cursors manually at arbitrary positions
The most direct way to get multiple cursors is Alt+Shift+Click, or Option+Shift+Click on macOS, at every position where an additional cursor should appear. Each cursor placed this way behaves completely independently: typing text inserts it at every active cursor position simultaneously, and key combinations like deleting a word or jumping to the end of a line also act on all cursors in parallel.
This is especially useful for structurally similar but not identical lines, for example when a parameter needs to be added at different positions across several method calls. Alt+J additionally adds the next occurrence of the current selection to the existing cursor set, allowing a smooth transition between manually placed cursors and automatic occurrence search, all without touching the mouse.
// Before: three separate log calls without a context prefix
$this->logger->info('Order created');
$this->logger->info('Payment captured');
$this->logger->info('Shipment sent');
// With three manually placed cursors (Alt+Shift+Click) right
// after each info(' , insert: 'Checkout: ' before every string
$this->logger->info('Checkout: Order created');
$this->logger->info('Checkout: Payment captured');
$this->logger->info('Checkout: Shipment sent');
3. Select All Occurrences: every match at once
Instead of placing cursors manually, Ctrl+Shift+Alt+J, or Cmd+Ctrl+G on macOS, instantly selects every occurrence of the currently selected text in the visible area or across the whole file and places its own cursor at each spot. This is the fastest way to, for example, consistently rename a repeated string key in an array without launching a project-wide find-and-replace that would also catch unwanted hits in other files.
The difference from Alt+J matters: Alt+J adds occurrences step by step and lets you deliberately skip individual hits, while Select All Occurrences marks every hit at once immediately. For a controlled, selective change, Alt+J is the better fit, while for a change that must apply to absolutely every occurrence without exception, Select All Occurrences is the faster and safer choice.
4. Column selection: a rectangular selection independent of line content
Column selection is activated via Alt+Shift plus dragging with the mouse, or alternatively via the shortcut that toggles column selection mode, and produces a rectangular selection based purely on visual columns rather than actual text. This is the key difference from Select All Occurrences: column selection does not care what is in the column, only where it sits.
That makes column selection ideal for situations where something needs to be inserted, deleted, or replaced at the same horizontal position across multiple lines, regardless of the actual content, for example adding a uniform prefix in front of a list of variable names of varying length, or stripping a comment character at the start of several consecutive lines column by column.
5. Practical example: reformatting arrays quickly
A classic use case in Magento modules is reformatting an array of short single-line entries into a multi-line array with consistent indentation, for example when transferring a list of constants from an external source. Column selection lets you insert a uniform indentation prefix in front of every line in one go, and Select All Occurrences can then replace every trailing comma with a uniform separator afterward, all without regex.
The benefit becomes even clearer when converting short notation into more verbose PHP array syntax, for example turning a list of store view codes from a CSV file into an associative PHP array. Column selection places the cursor at the end of every copied line, a single keystroke adds the closing quote and comma everywhere, and the entire reformatting job is done in a few seconds instead of several minutes of manual editing.
// Before: raw list, one ID per line
DE
AT
CH
// After, with column selection inserted before every line (' ) => ')
// and Select All Occurrences appended at the end of every line (', )
$allowedStoreViewCodes = [
'DE' => 'default',
'AT' => 'austria',
'CH' => 'switzerland',
];
6. Combining with Live Templates and structural navigation
Multi-cursor editing often reaches its full potential only in combination with other editor features. After placing multiple cursors, Live Templates can still be triggered normally, expanding a code snippet at several positions at once, for example a uniform PHPDoc block across several methods. Auto-completion also reacts independently at each cursor position, allowing very precise completions on structurally similar but not identical code.
Another often overlooked trick is combining this with Ctrl+D to duplicate a line or selection, followed by multi-cursor edits on the duplicates. This makes it possible to quickly generate a series of nearly identical test cases that differ only in a single parameter, without copying and adjusting every line by hand.
7. Limits and common pitfalls
Multi-cursor editing runs into trouble as soon as the structure of the affected lines differs too much, for example when some lines have an extra parameter and others don't. In such cases, blindly typing in parallel easily produces subtly wrong code that looks correct at first glance. A quick look at all affected lines before typing, ideally with soft wrap enabled, reliably prevents such silent mistakes.
A second common pitfall is accidentally leaving multi-cursor mode with a plain mouse click, which instantly collapses all extra cursors back down to a single one. Escape ends the mode in a controlled way, while a click into the editor without a held modifier key ends it uncontrolled. Anyone who accidentally clicks in the middle of a longer multi-cursor session loses all placed positions and has to rebuild the selection.
8. The most important shortcuts at a glance
For daily use, a small but well-practiced set of shortcuts is enough: Alt+Shift+Click for manual cursors, Alt+J to add the next occurrence step by step, Alt+Shift+J to remove the most recently added occurrence from the selection, Ctrl+Shift+Alt+J for all occurrences at once, and Alt+Shift plus mouse drag for column mode. In practice, these five combinations cover the vast majority of all bulk changes.
Once these shortcuts become muscle memory, they get reached for automatically at every repetitive change, instead of reaching for a regex find-and-replace that often takes longer to formulate than the actual change would take. For one-off, project-specific tweaks in particular, multi-cursor and column selection are usually noticeably faster than any regex, since no time is spent testing the pattern.
9. When a regex replacement is still the better choice
Multi-cursor techniques excel at visually or structurally clear patterns, but reach their limits when the change depends on a complex condition, for example only affecting certain numeric values above a threshold, or when hundreds of occurrences need changing across many files. In such cases, project-wide find-and-replace with regular expressions is the more robust choice, since it can be described programmatically and checked in a preview before being applied.
The rule of thumb in practice: up to a few dozen occurrences within one or a handful of files with a recognizable visual pattern belong to multi-cursor and column selection, while larger, logically more complex, or project-wide changes are better handled with regex find-and-replace including a preview. Using both tools situationally, rather than sticking to just one, saves the most time overall.
| Action | Shortcut (Win/Linux) | Shortcut (macOS) | Typical use |
|---|---|---|---|
| Place a manual cursor | Alt+Shift+Click | Option+Shift+Click | Punctual changes at several spots |
| Add next occurrence | Alt+J | Ctrl+G | Selective, controlled multi-selection |
| Select all occurrences | Ctrl+Shift+Alt+J | Cmd+Ctrl+G | Consistently renaming every match |
| Enable column selection | Alt+Shift+Drag | Option+Shift+Drag | Column-wise insert/delete |
| Duplicate line | Ctrl+D | Cmd+D | Create a base for similar follow-up lines |
Mironsoft
PhpStorm setup, Docker integration, and team productivity
PhpStorm that actually runs optimally for Magento and PHP projects?
We review existing PhpStorm setups for slow indexing, unused Docker integration, and missing team conventions, then set up a configuration that is productive from the first second.
Setup Review
Optimizing indexing, interpreter, and memory settings for large Magento projects.
Docker Integration
Cleanly connecting Xdebug, PHPUnit, and database tools to the Docker setup.
Team Conventions
Standardizing inspection profiles, code style, and live templates project-wide.
10. Summary
Multi-Cursor and Column Selection: The Essentials at a Glance
Two tools
Multi-cursor editing for content-based matches, column selection for purely position-based selection.
Select All Occurrences
Ctrl+Shift+Alt+J marks every occurrence instantly, Alt+J adds them one at a time under control.
Combinable
Live Templates, auto-completion and line duplication all keep working at every cursor position.
Know the limits
For structurally inconsistent lines or project-wide changes, regex find-and-replace is safer.