Diff mode¶
Diff mode switches the whole editor into a view for reviewing changes. How you open it decides what you compare against (the comparison base).
| Key | Comparison base | Requires |
|---|---|---|
Space G, Ctrl+G, :gitdiff |
HEAD |
git |
Space g, :pr, :pr <number> |
The base of a pull request | git, gh (after gh auth login) |
- Pressing the same key while diff mode is open closes it.
- Pressing the other key switches the comparison base.
- With either base, you can edit and save the right side (the working tree file) in place.
Screen¶
From top to bottom:
| Area | Content |
|---|---|
| Header | The base and the target. For a pull request, it also shows PR #number, the title, the state and the author |
| Left sidebar | The file tree in the upper 70%, CHANGES (the list of changed files) in the lower 30% |
| Center | The diff. A change-position bar runs along the right edge |
| Help line | The keys available now |
| Status line | The mode and messages |
- Files with no changes open in the normal editor.
- Files with changes open as a whole-file Split (the base on the left, the current file on the right).
- A new file (including untracked files when the base is
HEAD) opens in a single editor, whether the base isHEADor a PR base. Lines are not colored. The bar on the right edge is all green, and the file name row above shows+N/-N. When the base isHEAD, once you commit the file it is displayed like the other changed files. - When the base is a PR base, PR comments also appear on the correct lines of a new file opened in a single editor. You can add comments and replies too.
- The diff updates immediately when you edit.
- CHANGES updates when you save, when an external change is detected, and every few seconds.
CHANGES¶
It is shown as a folder tree, like the file tree.
A folder with only one child is collapsed into one row, such as internal/config.
A file row shows a status letter, the file name, the number of added lines +N and the number of removed lines -N.
| Letter | Status |
|---|---|
M |
Modified |
A |
Added (including untracked) |
D |
Deleted |
R |
Renamed |
The right end of the heading shows the current base. DIFF is HEAD, and PR is the base of a pull request.
When you open a file from CHANGES, the cursor is placed on the first changed line of the file. For a change that only removes lines, it is placed on the line after it. A file already open in a tab keeps its cursor position.
In Helix mode, Space E moves to CHANGES. From the file tree, Tab also moves there.
Split and Unified¶
Switch with any of these:
sin CHANGES:gitdiff split,:gitdiff unified- Click the file name row above the diff (for a new file opened in a single editor there is nothing to switch to, so
[split ⇄ unified]at the right of the row is not shown and clicking does nothing)
You can edit in Unified too. Deleted lines are interleaved as read-only lines.
Change-position bar¶
One column at the right edge of the diff shows where the changes are in the whole file.
| Color | Kind of change |
|---|---|
| Green | Additions only |
| Red | Deletions only |
| Blue | Rewrites (lines exist on both sides). Also blue when one cell mixes several kinds |
- The height of the bar corresponds to the whole file. When the file is longer than the screen, one cell groups several lines.
- The range currently displayed has a lighter bar background.
- Clicking the bar scrolls to that position.
Intra-line diff¶
On a line where only part of it changed, the changed part is highlighted in a color stronger than the line background. The left (base) uses the deletion color, and the right (current file) uses the addition color.
- The comparison is between the lines paired side by side in Split. Unified uses the same pairs.
- A pair with less than half of its characters in common is treated as unrelated, and only the whole-line color is used.
- Lines longer than 400 characters use only the whole-line color.
- When very many lines changed, the amount compared at once is limited. The remaining lines are compared little by little on each edit or refresh.
Comparison base¶
| Base | Content |
|---|---|
HEAD |
Compares HEAD with the working tree. Includes untracked files |
| The base of a pull request | Compares git merge-base <PR base> HEAD with the working tree |
Comparing with the base of a pull request gives the diff shown on GitHub's PR page plus your uncommitted changes. Even if you merge the base branch, the diff shows only your own changes.
The pull request opened with Space g is chosen as follows:
- If the current branch has exactly one pull request, it opens that one without showing a list.
- If it has several, you choose from a list of only those pull requests.
- If it has none, you choose from the repository's pull request list.
:pr <number>opens the pull request with that number.:pralone lets you choose from the repository's list.
A pull request on a different branch¶
If you choose a pull request that differs from the current branch, shijimi runs gh pr checkout <number> and then opens it.
- If there are uncommitted changes, the status line asks "Stash the uncommitted changes and switch? (y/n)".
y: runsgit stash push -u -m "shijimi: changes before switching to PR #<number>", then checks out.n: cancels the switch.
- If
gh pr checkoutfails and you stay on the original branch, the stashed changes are restored withgit stash pop. If they cannot be restored, the status line tells you the changes are in the stash. - If there are unsaved files, it does not switch. Save them first.
- If there are unsent comments for another pull request, it asks "PR #N has M unsent comments. Discard them and open PR #N? (y/n)". Merely switching the base to
HEADdoes not discard unsent comments. - In other situations (switching the base, closing diff mode, quitting shijimi), it never stashes or commits automatically.
PR and local divergence¶
When the local HEAD differs from the latest commit of the PR, the status line shows the following:
| State | Display | r in CHANGES |
|---|---|---|
| The PR is ahead | "The PR was updated. Press r to pull" | Runs git pull --ff-only, then reloads |
| The local branch is ahead | "There are N unpushed commits" | Reloads only |
| Both are ahead | "The local branch and the PR have diverged" | Reloads only (does not pull) |
To compare, it runs git fetch for the latest commit of the PR and the base branch.
Review¶
When the base is a pull request base, Space v opens the review menu.
The right side is an editor, so review operations are gathered in this menu to avoid clashing with editing keys.
| Key | Action |
|---|---|
Space v c |
Comment on the cursor line or the selected range |
Space v C |
Comment on the whole current file |
Space v t |
Open the thread on the cursor line as a card. If there is none on the line, choose from the file's comment list |
Space v v |
Mark as viewed / unmark |
Space v A |
Approve and submit |
Space v R |
Request changes and submit |
Space v S |
Submit as comments only |
Space v y |
Copy the PR URL |
Space v o |
Open the PR in the external browser. Over SSH, or if it cannot be opened, the URL is copied instead |
- The range is the editor selection (made with
xand so on) as is. - With the VS Code keymap, the same operations are available in the command palette (
F1) under "Review:". - When CHANGES has focus,
Space v C,tandvact on the selected file.
Files you can comment on¶
GitHub comments attach to line numbers of the PR's latest commit. If you edit or commit locally, the working tree's line numbers drift from them. So you can comment only on files whose working tree content is the same as the PR's latest commit. The same applies to applying suggestions.
Files whose content differs are displayed as follows:
- A
✎appears next to the file name in CHANGES and in the file name row above the diff. - Existing comments are not shown beside lines. The file name row summarizes them as "● 3 comments (not shown on lines; list with Space v t)".
- If you try to comment, the status line says "This file has local changes, so you cannot comment on its lines".
This is re-evaluated on every save and every reload. If you revert the local changes, you can comment again. You cannot comment on files with unsaved changes either.
GitHub accepts comments only around the diff (the changed lines and 3 lines before and after). On other lines, the status line says so.
Showing comments¶
| Place | Display |
|---|---|
| Left of the line number | ● on lines with comments |
| File name row above the diff | "● 2 file comments" if there are comments on the whole file |
| CHANGES row | ✓ (viewed), ●N (number of comments) |
| CHANGES heading | viewed 2/5 (✓2/5 when narrow) |
| Right of the status line | "3 unsent comments" |
Cards¶
Comments are shown in a card, similar to the LSP hover.
Open it by clicking ● or with Space v t.
It also opens when you hover the mouse over ● (when mouse-hover is enabled). This card is read-only and takes no keys. Pressing a key closes it and passes that key to the editor. It also closes when the pointer leaves the card.
- Comments are rendered as Markdown.
- Mermaid code blocks are rendered as diagrams (using the same component as the Markdown preview; without
mermaid-command, the source is shown).
While a card is open, it receives the following keys:
| Key | Action |
|---|---|
r |
Reply (edit, for an unsent comment) |
x |
Resolve / mark unresolved (delete, for an unsent comment) |
s |
Apply the suggestion to the local file and save |
Enter |
Move the cursor to that line |
j / k, Ctrl+D / Ctrl+U |
Scroll |
Esc |
Close the card |
Any other key closes the card and is passed to the editor.
Writing comments¶
The body of a comment, reply or review is written in an input box. Below the input box is a preview that looks like a card.
| Key | Action |
|---|---|
Enter |
Submit (a comment goes into the unsent list) |
Shift+Enter / Alt+Enter / Ctrl+J |
New line |
Ctrl+S |
Insert a ```suggestion block containing the original lines of the selected range |
Esc |
Cancel |
- Comments on lines, ranges and files are not sent immediately. You send them together as a review with
Space v A/R/S. - Replies and resolving are sent immediately.
- When sending fails, the partially built review on GitHub is deleted and the unsent comments are kept.
- If your own draft review (pending) remains on GitHub, shijimi does not send. Submit or discard it on GitHub's PR page.
- For comments on the left (base) side of a file and for outdated comments,
Enteronly opens the file and does not move the cursor.
CHANGES keys¶
| Key | Action |
|---|---|
j / k |
Move (stops on folder rows too; skips the inside of closed folders) |
g / G |
Top / bottom |
h |
Close the folder. On a closed folder or a file row, moves to the parent folder |
Enter |
Open the file. On a folder row, toggle open/closed |
l |
Open the file. On a folder row, open it |
s |
Toggle split / unified |
r |
Refresh the list (for a pull request, it may pull as in the table above) |
Space G / Space g |
Switch the comparison base, or close |
Space v |
Review menu |
Tab |
To the file tree |
Esc |
To the editor |
Mouse¶
- Clicking a folder row in CHANGES toggles it (
▾when open,▸when closed). The open/closed state is kept across list refreshes and base switches. - Dragging the border between the sidebar and the diff changes the sidebar width.
- Dragging the border between the file tree and CHANGES (the CHANGES heading row) changes the ratio of their heights. In the
Alt+Rresize mode,↑↓also move it while the explorer or CHANGES has focus. Pressing=restores 7:3. - In split view, dragging the
│between left and right changes the widths of the base and the working tree. In theAlt+Rresize mode,←→also move it while the editor has focus. The widths are kept until you quit the editor, and pressing=in resize mode restores an even split. It has no effect in unified view.