more tweaks

This commit is contained in:
Barrett Ruth 2026-03-27 18:17:12 -04:00
parent e31b2777f9
commit 25509a48ac
No known key found for this signature in database
GPG key ID: A6C96C9349D2FC81
7 changed files with 522 additions and 0 deletions

View file

@ -58,3 +58,32 @@ body:
label: 'Forge CLI version' label: 'Forge CLI version'
description: 'Output of `gh --version`, `glab --version`, or `tea --version`' description: 'Output of `gh --version`, `glab --version`, or `tea --version`'
render: text render: text
- type: textarea
attributes:
label: Minimal reproduction
description: |
Save the script below as `repro.lua`, edit if needed, and run:
```
nvim -u repro.lua
```
Confirm the bug reproduces with this config before submitting.
render: lua
value: |
vim.env.LAZY_STDPATH = '.repro'
load(vim.fn.system('curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua'))()
require('lazy.nvim').setup({
spec = {
{ 'barrettruth/midnight.nvim', lazy = false, config = function() vim.cmd.colorscheme('midnight') end },
{ 'tpope/vim-fugitive' },
{ 'ibhagwan/fzf-lua' },
{
'barrettruth/forge.nvim',
keys = {
{ '<c-g>', mode = { 'n', 'v' } },
},
},
},
})
validations:
required: true

3
.github/pull_request_template.md vendored Normal file
View file

@ -0,0 +1,3 @@
## Problem
## Solution

View file

@ -14,6 +14,7 @@ jobs:
lua: ${{ steps.changes.outputs.lua }} lua: ${{ steps.changes.outputs.lua }}
markdown: ${{ steps.changes.outputs.markdown }} markdown: ${{ steps.changes.outputs.markdown }}
vimdoc: ${{ steps.changes.outputs.vimdoc }} vimdoc: ${{ steps.changes.outputs.vimdoc }}
nix: ${{ steps.changes.outputs.nix }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dorny/paths-filter@v3 - uses: dorny/paths-filter@v3
@ -31,6 +32,9 @@ jobs:
- '*.md' - '*.md'
vimdoc: vimdoc:
- 'doc/**' - 'doc/**'
nix:
- '*.nix'
- 'flake.lock'
lua-format: lua-format:
name: Lua Format Check name: Lua Format Check
@ -76,6 +80,16 @@ jobs:
- uses: cachix/install-nix-action@v31 - uses: cachix/install-nix-action@v31
- run: nix develop .#ci --command vimdoc-language-server check doc/ - run: nix develop .#ci --command vimdoc-language-server check doc/
nix-format:
name: Nix Format Check
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.nix == 'true' }}
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v31
- run: nix fmt -- --check .
markdown-format: markdown-format:
name: Markdown Format Check name: Markdown Format Check
runs-on: ubuntu-latest runs-on: ubuntu-latest

66
README.md Normal file
View file

@ -0,0 +1,66 @@
# forge.nvim
**Forge-agnostic git workflow for Neovim**
PR, issue, and CI workflows across GitHub, GitLab, and more — without leaving
your editor.
## Features
- Forge detection from git remote (GitHub via `gh`, GitLab via `glab`,
Codeberg/Gitea/Forgejo via `tea`)
- PR lifecycle: list, create, checkout, review, merge, approve, close/reopen,
draft toggle
- Issue management: list, browse, close/reopen
- CI/CD: view runs, stream logs, filter by status
- PR compose buffer with diff stat, template discovery, and syntax highlighting
- Code review via [diffs.nvim](https://github.com/barrettruth/diffs.nvim)
unified/split diff with quickfix navigation
- Commit browsing with checkout, diff review, and URL yanking
- Branch browsing with diff review and remote links
- Worktree creation from PRs
- File/line permalink generation (commit and branch URLs)
- [fzf-lua](https://github.com/ibhagwan/fzf-lua) pickers with contextual
keybinds throughout
## Dependencies
- Neovim 0.10.0+
- [fzf-lua](https://github.com/ibhagwan/fzf-lua)
- At least one forge CLI:
- [`gh`](https://cli.github.com/) for GitHub
- [`glab`](https://gitlab.com/gitlab-org/cli) for GitLab
- [`tea`](https://gitea.com/gitea/tea) for Codeberg/Gitea/Forgejo
- [vim-fugitive](https://github.com/tpope/vim-fugitive) (optional, for fugitive
keymaps)
- [diffs.nvim](https://github.com/barrettruth/diffs.nvim) (optional, for review
mode)
## Installation
Install with your package manager of choice or via
[luarocks](https://luarocks.org/modules/barrettruth/forge.nvim):
```
luarocks install forge.nvim
```
## Documentation
```vim
:help forge.nvim
```
## FAQ
**Q: How do I create a PR?**
Press `<c-g>` to open the forge picker, select "Pull Requests", then `<ctrl-a>`
to create. Or from a fugitive buffer: `cpr` (create), `cpd` (draft), `cpf`
(instant), `cpw` (web).
**Q: Does forge.nvim support review diffs?**
Yes, with [diffs.nvim](https://github.com/barrettruth/diffs.nvim) installed.
Select a PR and press `<ctrl-d>` to enter review mode with unified diff. Press
`s` to toggle split/unified view. Navigate files with `]q`/`[q`.

230
doc/forge.nvim.txt Normal file
View file

@ -0,0 +1,230 @@
*forge.nvim.txt* Forge-agnostic git workflow for Neovim
Author: Barrett Ruth <br.barrettruth@gmail.com> License: MIT
==============================================================================
INTRODUCTION *forge.nvim*
forge.nvim provides PR, issue, and CI workflows across GitHub, GitLab, and
Codeberg from inside Neovim. It detects the forge from your git remote and
delegates to the appropriate CLI (`gh`, `glab`, or `tea`).
Features: ~
- Forge detection from git remote URL
- PR lifecycle (list, create, checkout, review, merge, approve, draft toggle)
- Issue management (list, browse, close/reopen)
- CI/CD run viewing, log streaming, status filtering
- PR compose buffer with diff stat and template discovery
- Code review via |diffs.nvim| with unified/split toggle
- Commit and branch browsing with forge permalinks
- Worktree creation from PRs
- fzf-lua pickers with contextual keybinds
==============================================================================
CONTENTS *forge-contents*
1. Introduction ............................................... |forge.nvim|
2. Requirements ....................................... |forge-requirements|
3. Setup ..................................................... |forge-setup|
4. Configuration ............................................ |forge-config|
5. Forge Picker ............................................ |forge-picker|
6. Pull Requests ................................................. |forge-pr|
7. Issues .................................................. |forge-issues|
8. CI/CD ...................................................... |forge-ci|
9. Commits ............................................... |forge-commits|
10. Branches .............................................. |forge-branches|
11. Review ................................................ |forge-review|
12. Compose Buffer ........................................ |forge-compose|
13. Highlight Groups .................................... |forge-highlights|
14. Health Check ............................................ |forge-health|
==============================================================================
REQUIREMENTS *forge-requirements*
- Neovim 0.10.0+
- fzf-lua (required)
- One or more forge CLIs:
- `gh` for GitHub
- `glab` for GitLab
- `tea` for Codeberg/Gitea/Forgejo
- vim-fugitive (optional, for fugitive keymaps)
- diffs.nvim (optional, for review mode)
==============================================================================
SETUP *forge-setup*
Install with lazy.nvim: >lua
{
'barrettruth/forge.nvim',
keys = {
{ '<c-g>', mode = { 'n', 'v' } },
},
}
<
Run `:checkhealth forge` to verify CLIs and dependencies.
==============================================================================
CONFIGURATION *forge-config*
Configuration is done via `vim.g.forge`: >lua
vim.g.forge = {
ci = { lines = 10000 },
}
<
*forge-config-ci-lines*
ci.lines ~
Number of log lines to fetch for CI runs. Default: `10000`.
==============================================================================
FORGE PICKER *forge-picker*
*<c-g>*
Press `<c-g>` in normal or visual mode to open the main forge picker. The
picker adapts based on the detected forge and current buffer state.
Available entries: ~
- Pull Requests / Merge Requests
- Issues
- CI / Pipelines
- Browse Remote
- Open File (current file on remote)
- Yank Commit URL / Yank Branch URL
- Commits
- Branches
- Worktrees
==============================================================================
PULL REQUESTS *forge-pr*
The PR picker lists open PRs by default. Toggle state with `<ctrl-o>` to
cycle through open/closed/all.
PR picker keybinds: ~
`<enter>` Checkout PR branch
`<ctrl-d>` Review diff (requires diffs.nvim)
`<ctrl-w>` Create worktree from PR
`<ctrl-t>` View checks/CI status
`<ctrl-x>` Open in browser
`<ctrl-e>` Manage (merge, approve, close, draft toggle)
`<ctrl-a>` Create new PR
`<ctrl-o>` Toggle state filter (open/closed/all)
`<ctrl-r>` Refresh list
PR management actions: ~
Approve, Merge (per available method), Close/Reopen, Draft toggle.
==============================================================================
ISSUES *forge-issues*
Issue picker keybinds: ~
`<enter>` Open in browser
`<ctrl-s>` Close/reopen issue
`<ctrl-o>` Toggle state filter
`<ctrl-r>` Refresh list
==============================================================================
CI/CD *forge-ci*
CI picker shows workflow runs for the current branch.
CI picker keybinds: ~
`<enter>` View logs (tail for in-progress, full for completed)
`<ctrl-x>` Open in browser
`<ctrl-r>` Refresh
Checks picker (from PR): ~
`<enter>` View check logs
`<ctrl-x>` Open in browser
`<ctrl-f>` Filter to failed
`<ctrl-p>` Filter to passed
`<ctrl-n>` Filter to running
`<ctrl-a>` Show all
==============================================================================
COMMITS *forge-commits*
Commit picker keybinds: ~
`<enter>` Checkout commit (detached HEAD)
`<ctrl-d>` Review diff
`<ctrl-x>` Open in browser (requires forge)
`<ctrl-y>` Yank commit hash
==============================================================================
BRANCHES *forge-branches*
Branch picker keybinds: ~
`<ctrl-d>` Review diff against branch
`<ctrl-x>` Open branch on remote (requires forge)
==============================================================================
REVIEW *forge-review*
Review mode requires diffs.nvim. Enter review via `<ctrl-d>` on a PR or
commit.
Review keybinds: ~
`s` Toggle unified/split view
`]q` / `[q` Next/previous quickfix entry (file navigation)
`]l` / `[l` Next/previous loclist entry
Review mode ends automatically when the review buffer is wiped.
==============================================================================
COMPOSE BUFFER *forge-compose*
Creating a PR opens a compose buffer (`forge://pr/new`) with:
- Line 1: PR title (pre-filled from commit subject or branch name)
- Line 3+: PR body (pre-filled from commit body or PR template)
- HTML comment block: metadata (branch info, draft, reviewers, diff stat)
The compose buffer is `filetype=markdown` with `buftype=acwrite`. Write the
buffer (`:w`) to push and create the PR. An empty title or body aborts.
Metadata fields (editable in the comment block): ~
`Draft:` Set to `yes` or `true` to create as draft
`Reviewers:` Comma-separated list of reviewer usernames
Template discovery: ~
forge.nvim searches for PR templates in the repository:
- `.github/pull_request_template.md`
- `.github/PULL_REQUEST_TEMPLATE/` (single file auto-selected, multiple
prompts for choice)
- GitLab/Codeberg equivalents
Fugitive keymaps: ~
From a fugitive buffer, the following keymaps are available:
`cpr` Create PR
`cpd` Create draft PR
`cpf` Create PR instantly (skip compose buffer)
`cpw` Create PR via web browser
==============================================================================
HIGHLIGHT GROUPS *forge-highlights*
The compose buffer uses the following highlight groups:
`ForgeComposeComment` Entire comment block Links to `Comment`
`ForgeComposeBranch` Branch names Links to `Special`
`ForgeComposeForge` Forge name Links to `Type`
`ForgeComposeDraft` Draft status value Links to `DiagnosticWarn`
`ForgeComposeFile` File paths in diff stat Links to `Directory`
`ForgeComposeAdded` Addition indicators (+) Links to `Added`
`ForgeComposeRemoved` Deletion indicators (-) Links to `Removed`
All groups are defined with `default = true` so colorschemes can override them.
==============================================================================
HEALTH CHECK *forge-health*
Run `:checkhealth forge` to verify:
- git is available
- Forge CLIs (`gh`, `glab`, `tea`) and their status
- fzf-lua is installed
- diffs.nvim is available (for review mode)
- vim-fugitive is available (for fugitive keymaps)
==============================================================================
vim:tw=78:ts=8:ft=help:norl:

134
flake.lock generated Normal file
View file

@ -0,0 +1,134 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1774273680,
"narHash": "sha256-a++tZ1RQsDb1I0NHrFwdGuRlR5TORvCEUksM459wKUA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fdc7b8f7b30fdbedec91b71ed82f36e1637483ed",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1772624091,
"narHash": "sha256-QKyJ0QGWBn6r0invrMAK8dmJoBYWoOWy7lN+UHzW1jc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "80bdc1e5ce51f56b19791b52b2901187931f5353",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"systems": "systems",
"vimdoc-language-server": "vimdoc-language-server"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"vimdoc-language-server",
"nixpkgs"
]
},
"locked": {
"lastModified": 1772852295,
"narHash": "sha256-3FB/WzLZSiU2Mc50C9q9VXU1LRUZbsU6UHKmZG1C+hU=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "c10801f59c68e14c308aea8fa6b0b3d81d43c61e",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"vimdoc-language-server": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2",
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1774450573,
"narHash": "sha256-K2oPjDWruf+QL/81SLmY01fPM8vXDycTugh3J8wEQdo=",
"owner": "barrettruth",
"repo": "vimdoc-language-server",
"rev": "6a6ecc8077a50f871b7611e1b318823925171a39",
"type": "github"
},
"original": {
"owner": "barrettruth",
"repo": "vimdoc-language-server",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

46
flake.nix Normal file
View file

@ -0,0 +1,46 @@
{
description = "forge.nvim forge-agnostic git workflow for Neovim";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
systems.url = "github:nix-systems/default";
vimdoc-language-server.url = "github:barrettruth/vimdoc-language-server";
};
outputs =
{
nixpkgs,
systems,
vimdoc-language-server,
...
}:
let
forEachSystem =
f: nixpkgs.lib.genAttrs (import systems) (system: f nixpkgs.legacyPackages.${system});
in
{
formatter = forEachSystem (pkgs: pkgs.nixfmt-tree);
devShells = forEachSystem (
pkgs:
let
vimdoc-ls = vimdoc-language-server.packages.${pkgs.system}.default;
commonPackages = [
pkgs.prettier
pkgs.stylua
pkgs.selene
pkgs.lua-language-server
vimdoc-ls
];
in
{
default = pkgs.mkShell {
packages = commonPackages;
};
ci = pkgs.mkShell {
packages = commonPackages;
};
}
);
};
}