https://github.com/stefanbartl/reposcope.nvim
๐ก A powerful Telescope extension for discovering and previewing code repositories directly within Neovim. Search GitHub repositories by keyword or topic and preview their README.md content in a floating window โ right from your editor. Future support planned for GitLab, Codeberg, and other platforms.
https://github.com/stefanbartl/reposcope.nvim
developer-tools fuzzy-search github github-api lua markdown-clone neovim neovim-plugin neovim-ui nvim readme-preview repositories repository-search seatch
Last synced: about 3 hours ago
JSON representation
๐ก A powerful Telescope extension for discovering and previewing code repositories directly within Neovim. Search GitHub repositories by keyword or topic and preview their README.md content in a floating window โ right from your editor. Future support planned for GitLab, Codeberg, and other platforms.
- Host: GitHub
- URL: https://github.com/stefanbartl/reposcope.nvim
- Owner: StefanBartl
- License: mit
- Created: 2025-04-30T16:48:33.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-06-16T23:07:57.000Z (7 months ago)
- Last Synced: 2025-06-17T00:19:56.423Z (7 months ago)
- Topics: developer-tools, fuzzy-search, github, github-api, lua, markdown-clone, neovim, neovim-plugin, neovim-ui, nvim, readme-preview, repositories, repository-search, seatch
- Language: Lua
- Homepage: https://github.com/StefanBartl/reposcope.nvim
- Size: 2.34 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# reposcope.nvim





> ๐ง Beta stage โ under active development. Changes possible.
```
_ __ ___ _ __ ___ ___ ___ ___ _ __ ___
| '__| / _ \| '_ \ / _ \ / __| / __| / _ \ | '_ \ / _ \
| | | __/| |_) || (_) |\__ \| (__ | (_) || |_) || __/
|_| \___|| .__/ \___/ |___/ \___| \___/ | .__/ \___|
| | | |
|_| |_|
```
Search, preview and clone GitHub repositories โ directly from inside Neovim.
Modular, minimal, Telescope-inspired interface.
---
- [Features](#features)
- [Features Demo](#features-demo)
- [Roadmap](#roadmap)
- [Installation](#installation)
- [With Lazy.nvim](#with-lazynvim)
- [With packer.nvim](#with-packernvim)
- [Configuration](#configuration)
- [Available Options](#available-options)
- [Usage](#usage)
- [UI Keymaps](#ui-keymaps)
- [Available Commands](#available-commands)
- [:ReposcopePromptReload](#reposcopepromptreload-)
- [:ReposcopeFilterRepos](#reposcopefilterrepos-text)
- [:ReposcopeFilterPrompt](#reposcopefilterprompt)
- [Authentication](#authentication)
- [Architecture Overview](#architecture-overview)
- [Development & Debugging](#development-debugging)
- [License](#license)
- [Contribution](#contribution)
---
## Features
- ๐ Dynamic GitHub repository search by topic, owner, language, etc.
- ๐ Live preview of `README.md` with inline Markdown rendering
- ๐ง Persistent README caching (RAM + file system)
- ๐ง Clone support: `git`, `gh`, `wget`, `curl`
- ๐ Debounced README fetches to avoid redundant API calls
- ๐ฆ Clean, fully modular architecture (UI, state, providers, controllers)
- ๐งช Strongly annotated with EmmyLua for LuaLS support
- ๐ Built-in request metrics and logging (optional toggle)
- ๐ README viewer (``) or README editor buffer (``)
- โจ๏ธ Keymaps for navigation, cloning, and UI control
- ๐ Customizable prompt fields (e.g. `prefix`, `keywords`, `owner`, ...)
---
## Features Demo:
https://github.com/user-attachments/assets/85dece1d-d755-4de9-9cd1-84a751901fc2
---
## Roadmap
- [x] GitHub repository search (field-based)
- [x] GitHub README rendering (raw + API fallback)
- [x] Clone repo with tool of choice (`git`, `gh`, `curl`, `wget`)
- [x] File-based README cache
- [x] Full UI (list, prompt, preview, background) in dynamic layout
- [x] Metrics, logging, and developer diagnostics
- [x] Viewer/editor for README content
- [x] Help docs via `:h reposcope`
- [ ] GitLab + Codeberg provider support
- [ ] Persistent session save/restore
---
## Installation
### With [Lazy.nvim](https://github.com/folke/lazy.nvim)
```lua
{
"StefanBartl/reposcope.nvim",
name = "reposcope",
event = ""VeryLazy,
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-telescope/telescope.nvim",
},
config = function()
require("reposcope.init").setup({})
end,
}
```
### With [packer.nvim](https://github.com/wbthomason/packer.nvim)
```lua
use {
"StefanBartl/reposcope.nvim",
name = "reposcope",
event = ""VeryLazy,
requires = {
"nvim-lua/plenary.nvim",
"nvim-telescope/telescope.nvim",
},
config = function()
require("reposcope.init").setup({})
end,
}
```
---
## Configuration
`reposcope.nvim` is fully configurable. You can start with the defaults:
```lua
require("reposcope").setup({})
```
Or define a custom setup with fine-grained control:
```lua
require("reposcope").setup({
prompt_fields = {
"prefix", "owner", "keywords", "language", "topic", "stars"
}, -- Prompt fields shown to the user
provider = "github", -- Which backend to use: "github" (default), "gitlab" (planned)
request_tool = "curl", -- Tool for API requests: "gh", "curl", "wget"
layout = "default", -- Currently only "default" supported
github_token = os.getenv("GITHUB_TOKEN"), -- If higher API Limits neeeded set the token here. If that doesn't works: [Authentication](#authentication)
keymaps = {
open = "rs", -- Mapping to open the UI
close = "rc", -- Mapping to close the UI
},
clone = {
std_dir = "~/projects", -- Default directory to clone into
type = "git", -- Clone method: "git", "gh", "wget", "curl"
},
metrics = true, -- Enables request timing and logging (for debugging)
})
```
---
### Available Options
| Option | Type | Description |
| --------------- | ---------- | ------------------------------------------------------------------ |
| `prompt_fields` | `string[]` | Controls which input fields appear in the prompt UI |
| `provider` | `string` | Active backend (currently only `"github"` supported) |
| `request_tool` | `string` | CLI tool to fetch data: `"gh"`, `"curl"`, `"wget"` |
| `layout` | `string` | UI layout style (currently only `"default"`) |
| `keymaps.open` | `string` | Keymap to open Reposcope UI |
| `keymaps.close` | `string` | Keymap to close the UI cleanly |
| `clone.std_dir` | `string` | Base path for repository cloning |
| `clone.type` | `string` | Tool used to perform clone: `"git"`, `"gh"`, `"wget"`, or `"curl"` |
| `metrics` | `boolean` | Enable internal request logging and performance tracking |
> โน๏ธ You can dynamically reload prompt fields with `:ReposcopePromptReload prefix topic`.
---
## Usage
Launch Reposcope UI:
```vim
:ReposcopeStart
```
Or map it in your Neovim config:
```lua
vim.keymap.set("n", "rs", function()
vim.cmd("ReposcopeStart")
end, { desc = "Open Reposcope" })
```
### UI Keymaps
| Key | Mode | Action |
| ------------- | ---- | ------------------------------------- |
| `` | any | Close Reposcope UI |
| `/` | n/i | Navigate repository list |
| `` | n/i | View README in floating window |
| `` | n/i | Open README in editable hidden buffer |
| `` | n/i | Clone selected repository |
| `` | i | Cycle to next prompt field |
| `` | i | Cycle to previous prompt field |
---
### Available Commands
**UI Lifecycle & Prompt Configuration**
| Command | Description |
| ---------------------------- | ------------------------------------------------------------------- |
| `:ReposcopeStart` | Opens the Reposcope UI |
| `:ReposcopeClose` | Closes all Reposcope windows and buffers |
| `:ReposcopePromptReload ...` | Dynamically sets new prompt fields (e.g. `prefix`, `keywords`, ...) |
**Repository List: Sorting & Filtering**
| Command | Description |
| ------------------------------ | ---------------------------------------------------------------------- |
| `:ReposcopeSortPrompt` | Opens an interactive selection menu to choose a sort mode |
| `:ReposcopeFilterRepos {text}` | Filters the currently shown repositories by case-insensitive substring |
| `:ReposcopeFilterPrompt` | Opens a floating prompt window to input a filter string interactively |
| `:ReposcopeFilterClear` | Clears any active filter and restores the full list of repositories |
**Debugging, Stats & Metrics**
| Command | Description |
| -------------------------- | ------------------------------------------------------------------------ |
| `:ReposcopeToggleDev` | Toggles developer mode (enables debug logging, internal info, etc.) |
| `:ReposcopePrintDev` | Prints whether developer mode is currently active |
| `:ReposcopeSkippedReadmes` | Shows number of skipped README fetches (debounced during fast scrolling) |
| `:ReposcopeStats` | Displays collected request stats and metrics |
---
#### `:ReposcopePromptReload ...`
This user command updates the active prompt fields dynamically. It closes and reopens the Reposcope UI to apply the new configuration โ the specified fields will then appear in the prompt layout.
> ๐ง Prompt fields must be chosen from: `prefix`, `keywords`, `owner`, `language`, `topic`, `stars`.
> If no fields are given, it defaults to: `keywords`, `owner`, `language`.
Example:
```vim
:ReposcopePromptReload keywords topic "prompt without prefix: ๏
:ReposcopePromptReload prefix topic stars "prompt with prefix, topice and stars field
:ReposcopePromptReload "resets to default
```
---
#### `:ReposcopeFilterRepos {text}`
Filters the current list of repositories using a case-insensitive substring
match.
The input is matched against the format: `owner/name: description`.
> If called without arguments, it resets the list to the original API result.
Examples:
```vim
:ReposcopeFilterRepos typescript bun "matches any repository with strings
:ReposcopeFilterRepos openai "filter by organization or description
:ReposcopeFilterRepos "clears filter and restores all results
```
---
#### `:ReposcopeFilterPrompt`
Opens a small floating input field where you can type a filter query.
The behavior is identical to `:ReposcopeFilterRepos`, but interactively.
Examples:
```vim
:ReposcopeFilterPrompt "opens floating input to enter 'react', 'api', etc.
```
> Press `` to confirm and filter; leave input empty to cancel.
---
## Authentication
`reposcope.nvim` works out of the box โ **no authentication is required** for basic usage.
However, if you want to use the `gh` CLI as your request backend, you **must** set a valid `GITHUB_TOKEN` manually:
```sh
export GITHUB_TOKEN=ghp_your_token_here
```
โ ๏ธ **Important:** Logged-in `gh` sessions (via `gh auth login`) are **not** accessible to child processes started via `uv.spawn()` inside Neovim. Without an explicit `GITHUB_TOKEN`, `gh`-based requests will silently fail.
As an alternative, you can use `curl` or `wget` without authentication โ but youโll have lower API rate limits.
---
### Recommended: Set it explicitly in `setup({ ... })`
In some systems or plugin managers, Neovim **does not inherit** environment variables defined in `.zshenv`, `.profile`, or GUI launch contexts.
To avoid issues, we recommend passing the token directly during setup:
```lua
require("reposcope").setup({
github_token = os.getenv("GITHUB_TOKEN") or "gh__example_token", -- Explicitly forward the env variable
...
})
```
This ensures the token is correctly passed to internal request handlers, regardless of how Neovim was started.
If you do not set a token, `curl` or `wget` will still work โ but you may hit GitHub's anonymous rate limits.
---
## Architecture Overview
```
reposcope/
โ
โโโ init.lua โ Setup and UI lifecycle
โโโ config.lua โ User options and dynamic resolution
โโโ ui/ โ Modular UI: prompt, list, preview, background
โโโ providers/ โ GitHub (others coming soon)
โโโ cache/ โ In-memory and file-based caching
โโโ controllers/ โ Unified dispatch: readme, repositories, clone
โโโ state/ โ Buffers, windows, user input state
โโโ network/ โ HTTP clients and request tools (curl, gh, ...)
โโโ utils/ โ Debug, protection, encoding, os-tools
```
---
## Development & Debugging
* Use `:ReposcopePromptReload prefix topic` to dynamically reload prompt fields
* Use `require("reposcope.utils.debug").notify(...)` for developer output
* Toggle metrics in config: `metrics = true`
* Debug file paths and logs are stored in:
* `~/.local/share/nvim/reposcope/data/readme/`
* `~/.local/share/nvim/reposcope/logs/request_log.json`
---
## License
[MIT-License](./LICENSE)
---
## Contribution
Issues, suggestions and pull requests are welcome!
Clone, symlink into your Neovim config, and hack away.
```
git clone https://github.com/StefanBartl/reposcope.nvim ~/.config/nvim/reposcope.nvim
```
---