Skip to content

emrearmagan/atlas.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

372 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Neovim Version Tests License

Atlas.nvim

A Neovim plugin for managing GitHub/Bitbucket PRs and Jira issues without leaving your editor.

Caution

Still in early development, will have breaking changes!


Github

Bitbucket

Edit/Create Issue

Table of Contents

Installation

Using lazy.nvim

{
  "emrearmagan/atlas.nvim",
  dependencies = {
    "MeanderingProgrammer/render-markdown.nvim", -- optional but recommended (Jira)
    "sindrets/diffview.nvim", -- optional (PullRequest diff)
    "esmuellert/codediff.nvim", -- optional (PullRequest diff alternative)
  },
  config = function()
    require("atlas").setup({
      pulls = {
        providers = {
          bitbucket = { }, -- See configuration below
          github = { },    -- See configuration below
        },
      },
      issues = {
        providers = {
          jira = { }, -- See configuration below
        },
      },
    })
  end,
}
use {
  "emrearmagan/atlas.nvim",
  config = function()
    require("atlas").setup({
      pulls = {
        providers = {
          bitbucket = { }, -- See configuration below
          github = { },    -- See configuration below
        },
      },
      issues = {
        providers = {
          jira = { }, -- See configuration below
        },
      },
    })
  end
}

Tip

It's a good idea to run :checkhealth atlas to see if everything is set up correctly. Not ready to connect yet? Run :AtlasIssues mock or :AtlasPulls mock to explore the UI with some mock data.

Requirements

  • Neovim: 0.10+
  • Jira: Jira Cloud REST API v3 (*.atlassian.net)
  • Bitbucket: Bitbucket Cloud REST API 2.0 (api.bitbucket.org)
  • GitHub: GitHub CLI (gh) authenticated with gh auth login

Note

I have only tested this with my personal and work accounts. If you encounter any issues, please feel free to open an issue. See: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/

Commands

  • :AtlasIssues [provider] - Open Atlas issues domain
  • :AtlasPulls [provider] - Open Atlas pulls domain
  • :AtlasJqlSearch {query} - Search Jira issues with JQL
  • :AtlasClearCache - Clear Atlas disk and memory cache
  • :AtlasLogs - Toggle Atlas logs

Issues

Jira

Note

If you're only looking for Jira support, check out https://github.com/letieu/jira.nvim. This plugin was the main inspiration for this project.
Jira support is included here mainly because I wanted a single tool that works with both Atlassian products.

  • Create and Edit issues
  • View and edit issues as markdown -> ADF conversion for issue descriptions (experimental)
  • Issue panel tabs: overview, comments, history
  • Jira actions: transition, change assignee, change reporter, edit title
  • Comment workflows (create, reply, edit, delete)
  • Search issues
  • JQL support and completion
  • Support for custom fields
  • Add custom actions to issues
  • Create and edit issue templates
  • Save JQL queries as custom views
  • Save and filter issues

Important

The markdown editor for issue descriptions and comments is still experimental and may not work perfectly in all cases. You can toggle between markdown and ADF view in the overview tab to see the raw ADF content and how it translates to markdown. If you encounter any issues with the markdown editor, please open an issue with details.

Configuration
return {
  "emrearmagan/atlas.nvim",
  config = function()
    require("atlas").setup({
      issues = {
        max_results = 100,
        fetch_parent_issues = true,
        custom_actions = {}, -- See Custom Actions below.

        providers = {
          jira = {
            base_url = "https://your-site.atlassian.net",
            email = "you@example.com",
            --- See: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/
            token = "your_jira_api_token",
            cache_ttl = 300,

            project_config = {
              -- The Jira custom field ID used for story points. Defaults to "customfield_10016".
              story_points_field = "customfield_10016",

              KAN = {
                customfield_10003 = {
                  name = "Approvers",
                  format = function(value)
                    if type(value) ~= "table" or #value == 0 then
                      return nil -- nil hides the field
	                    end
	                    return table.concat(value, ", ")
	                  end,
                  hl_group = "AtlasChipActive",
                  display = "chip", -- "chip" or "table"
                },
              },
            },

            ---@type AtlasJiraViewConfig[]
            views = {
              {
                name = "My Board",
                key = "M",
                jql = "project = KAN AND assignee = currentUser() ORDER BY updated DESC",
              },
              {
                name = "Team Board",
                key = "T",
                jql = "project = KAN ORDER BY updated DESC",
              },
            },
          },
        },
      },
    })
  end,
}
Custom Actions

You can add custom issue actions under issues.custom_actions.

Context type:

---@class AtlasIssuesCustomActionContext
---@field issue Issue|nil
---@field user IssueUser|nil

Example:

issues = {
  custom_actions = {
    {
      id = "copy_branch_name",
      label = "Copy branch name",
      ---@param issue Issue
      ---@param ctx AtlasIssuesCustomActionContext
      ---@param done fun(ok: boolean|nil, message: string|nil)
      run = function(issue, ctx, done)
        local branch = string.format("%s/%s", issue.key, issue.summary:lower():gsub("%s+", "-"))
        vim.fn.setreg("+", branch)
        done(true, "Copied: " .. branch)
      end,
    },
  },
  providers = {
    jira = { },
  },
}

JQL Search Command

Use :AtlasJqlSearch to run JQL directly from command mode. It also supports command-line completion while typing the query.

Examples:

:AtlasJqlSearch project = KAN AND assignee = currentUser() ORDER BY updated DESC
:AtlasJqlSearch summary ~ "login bug"

Pulls

  • Multiple views
  • PR tabs: overview, activity, comments, commits, files
  • PR actions: merge, approve, request changes
  • Comment workflows (create, reply, edit, delete)
  • Build/CI status with clickable links
  • Diffstat summary in Changes tab
  • Add custom actions to PRs
  • Open PR diff in given command
  • Switch between open, merged and closed PRs
  • Show Github Issues
  • Show Notifications
  • Pagination for API results

GitHub

Configuration
return {
  "emrearmagan/atlas.nvim",
  config = function()
    require("atlas").setup({
      pulls = {
        diff = {
          -- Command must support range input: origin/<destination>...origin/<source>
          open_cmd = "DiffviewOpen", -- e.g. "DiffviewOpen" or "CodeDiff", defaults to nil.
        },
        providers = {
          github = {
            cache_ttl = 300,

            ---@type AtlasGitHubViewConfig[]
            views = {
              {
                name = "My PRs",
                key = "1",
                search = "author:@me sort:updated-desc",
              },
              {
                name = "Team",
                key = "2",
                search = "org:your-org sort:updated-desc",
              },
              {
                name = "Repo",
                key = "3",
                search = "repo:your-org/your-repo",
              },
            },
          },
        },
      },
    })
  end,
}

Bitbucket

Configuration
return {
  "emrearmagan/atlas.nvim",
  config = function()
    require("atlas").setup({
      pulls = {
        diff = {
          -- Command must support range input: origin/<destination>...origin/<source>
          open_cmd = "DiffviewOpen", -- e.g. "DiffviewOpen" or "CodeDiff", defaults to nil.
        },
        repo_config = {
          -- Maps `workspace/repo` to local paths. Used for checkout and custom actions.
          paths = {
            ["your-workspace/*"] = "~/code/repos/*",
            ["your-workspace/atlas"] = "~/code/atlas",
          },
          settings = {
            ["your-workspace/atlas"] = {
              readme = "README.md", -- optional, defaults to README.md
            },
          },
        },
        custom_actions = {}, -- See Custom Actions below.
        providers = {
          bitbucket = {
            user = os.getenv("BITBUCKET_USER") or "",
            token = os.getenv("BITBUCKET_TOKEN") or "",
            cache_ttl = 300,

            ---@type AtlasBitbucketViewConfig[]
            views = {
              {
                name = "Me",
                key = "M",
                layout = "compact", -- "compact" or "plain"
                repos = {
                  { workspace = "your-workspace", repo = "atlas" },
                },

                ---@param pr PullRequest
                ---@param ctx { user: PullsUser|nil }
                filter = function(pr, ctx)
                  local user = ctx.user
                  return pr.author and user and pr.author.id == user.id
                end,
              },
              {
                name = "Team",
                key = "1",
                layout = "plain", -- "compact" or "plain"
                repos = {
                  { workspace = "your-workspace", repo = "atlas" },
                  { workspace = "your-workspace", repo = "other-repo" },
                },
              },
            },
          },
        },
      },
    })
  end,
}
Custom Actions

You can add custom PR actions under pulls.custom_actions.

Context type:

---@class AtlasPullsCustomActionContext
---@field repo_path string|nil
---@field pr PullRequest

Example:

pulls = {
  repo_config = {
    paths = {
      ["your-workspace/*"] = "~/code/repos/*",
    },
    settings = {},
  },
  custom_actions = {
    {
      id = "open_tmux_window",
      label = "Open repo in tmux window",
      confirmation = true, -- present a confirmation prompt before running the action
      ---@param pr PullRequest
      ---@param ctx AtlasPullsCustomActionContext
      ---@param done fun(ok: boolean|nil, message: string|nil)
      run = function(_, ctx, done)
        if not ctx.repo_path then
          done(false, "No repo path")
          return
        end

        vim.system({ "tmux", "new-window", "-c", ctx.repo_path }, { text = true }, function(res)
          vim.schedule(function()
            if res.code ~= 0 then
              done(false, "Failed to open tmux window")
              return
            end
            done(true, "Opened tmux window")
          end)
        end)
      end,
    },
  },
  providers = {
    bitbucket = { },
  },
}

CleanShot2026-03-31at20 08 06-ezgif com-video-to-gif-converter

Keymaps

Set an action to false to disable it, or set it to a list to add aliases.

require("atlas").setup({
  keymaps = {
    ui = {
      toggle_panel = false,
      next_panel_tab = { "]", "<Tab>", "gn" },
      previous_panel_tab = { "[", "<S-Tab>", "gp" },
    },
    issues = {
      transition_issue = "gs",
      change_assignee = "ga",
      edit_issue = "ge",
      search = "?",
    },
    pulls = {
      open_diff = { "go", "gd" },
    },
  },
})
General
Context Key Action
Atlas q Close Atlas
Atlas g? Toggle help popup
Atlas p Toggle detail pane
Atlas <S-Tab> Previous panel tab
Atlas <Tab> Next panel tab
Atlas R Refresh current view
Atlas r Refresh selected issue/pr
Atlas a/i / c / e / d Add / reply / edit / delete comment
Issues
Context Key Action
Issues A Open Jira actions
Issues K Show issue details
Issues c Create issue
Issues ? Search issues
Issues gs Transition issue
Issues ga Change assignee
Issues gr Change reporter
Issues ge Edit issue
Issues gx Open issue/comment in browser
Issues y / Y Copy issue key / URL
Issues za / zA Toggle fold / all folds
Issues m Toggle markdown / raw view (overview tab)
Pulls
Context Key Action
Pulls A Open PR actions
Pulls o Toggle repository panel
Pulls T Create new tasks on PR
Pulls ? Search repositories
Pulls gc Checkout selected PR
Pulls gd Open selected PR diff
Pulls gx Open pr/build/comment in browser
Pulls y / Y Copy PR id / URL
Pulls (File changes) za / zA Toggle fold / all folds
Pulls (File changes) ]h / [h Next / previous hunk

Contributors ✨

Thanks go to these wonderful people (emoji key):

Riza Khan
Riza Khan

💻
Cydralic
Cydralic

💻
franroa
franroa

💻 🐛

License

MIT License - see LICENSE for details.

About

A Neovim plugin to browse and manage GitHub/Bitbucket pull requests and Jira issues without leaving your editor.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages