{"id":13598683,"url":"https://github.com/yassinebridi/serpl","last_synced_at":"2026-02-18T20:32:45.228Z","repository":{"id":245258244,"uuid":"818001992","full_name":"yassinebridi/serpl","owner":"yassinebridi","description":"A simple terminal UI for search and replace, ala VS Code.","archived":false,"fork":false,"pushed_at":"2025-07-11T09:18:48.000Z","size":378,"stargazers_count":762,"open_issues_count":20,"forks_count":10,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-10-21T04:06:27.576Z","etag":null,"topics":["ast-grep","replace","rust","search","terminal","tui","vscode"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yassinebridi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-20T22:27:13.000Z","updated_at":"2025-10-17T07:16:36.000Z","dependencies_parsed_at":"2024-06-21T00:12:42.155Z","dependency_job_id":"7f362315-dbd8-4992-8ad1-c69d13f96449","html_url":"https://github.com/yassinebridi/serpl","commit_stats":null,"previous_names":["yassinebridi/serpl"],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/yassinebridi/serpl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yassinebridi%2Fserpl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yassinebridi%2Fserpl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yassinebridi%2Fserpl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yassinebridi%2Fserpl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yassinebridi","download_url":"https://codeload.github.com/yassinebridi/serpl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yassinebridi%2Fserpl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29594259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T18:54:29.675Z","status":"ssl_error","status_checked_at":"2026-02-18T18:50:50.517Z","response_time":162,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast-grep","replace","rust","search","terminal","tui","vscode"],"created_at":"2024-08-01T17:00:55.008Z","updated_at":"2026-02-18T20:32:45.201Z","avatar_url":"https://github.com/yassinebridi.png","language":"Rust","funding_links":[],"categories":["Rust","💻 Apps"],"sub_categories":["⌨️ Development Tools"],"readme":"\u003e [!WARNING]\n\u003e This project needs maintainers, if you are interested please contact me at `github@yasbr.com`\n\n# Serpl\n\n`serpl` is a terminal user interface (TUI) application that allows users to search and replace keywords in an entire folder, similar to the functionality available in VS Code.\n\nhttps://github.com/yassinebridi/serpl/assets/18403595/348506704-73336074-bfaf-4a9a-849c-bd4aa4e24afc\n\n## Table of Contents\n\n1. [Features](#features)\n2. [Installation](#installation-and-update)\n   - [Prerequisites](#prerequisites)\n   - [Steps](#steps)\n   - [Binaries](#binaries)\n   - [OS Specific Installation](#os-specific-installation)\n3. [Usage](#usage)\n   - [Basic Commands](#basic-commands)\n   - [Key Bindings](#key-bindings)\n   - [Configuration](#configuration)\n4. [Panes](#panes)\n   - [Search Input](#search-input)\n   - [Replace Input](#replace-input)\n   - [Search Results Pane](#search-results-pane)\n   - [Preview Pane](#preview-pane)\n5. [Quick Hints](#quick-hints)\n6. [Neovim Integration using toggleterm](#neovim-integration-using-toggleterm)\n7. [Helix Integration](#helix-integration)\n8. [License](#license)\n9. [Contributing](#contributing)\n10. [Acknowledgements](#acknowledgements)\n11. [Similar Projects](#similar-projects)\n\n## Features\n\n- Search for keywords across an entire project folder, with options for case sensitivity, AST Grep and more.\n- Replace keywords with options for preserving case, AST Grep and more.\n- Interactive preview of search results.\n- Keyboard navigation for efficient workflow.\n- Configurable key bindings and search modes.\n\n## Installation and Update\n\n### Prerequisites\n\n- [ripgrep](https://github.com/BurntSushi/ripgrep?tab=readme-ov-file#installation) installed on your system.\n- (Optional) [ast-grep](https://ast-grep.github.io) installed on your system, if you want to use the AST Grep functionality.\n\n### Steps\n\n1. Install the application using Cargo:\n  ```bash\n  cargo install serpl\n  ```\n  - If you want to install the application with the AST Grep functionality, you can use the following command:\n    ```bash\n    cargo install serpl --features ast_grep\n    ```\n2. Run the application:\n  ```bash\n  serpl\n  ```\n   \n### Binaries\nCheck the [releases](https://github.com/yassinebridi/serpl/releases) page for the latest binaries.\n\n### OS Specific Installation\n \n#### Brew\n\n`serpl` can be installed using [Homebrew](https://brew.sh/):\n\n```bash\nbrew install serpl\n```\n\n#### Arch Linux\n\n`serpl` can be installed from the [official repositories](https://archlinux.org/packages/extra/x86_64/serpl/) using [`pacman`](https://wiki.archlinux.org/title/Pacman):\n\n```bash\npacman -S serpl\n```\n\n#### Nix/NixOS\n\n`serpl` is included in [nixpkgs](https://github.com/nixos/nixpkgs) since 24.11, and can be installed via Nix in different ways:\n\n**On standalone Nix setups**:\n\n```bash\nnix profile install nixpkgs#serpl\n```\n\n**On NixOS** (via `configuration.nix` or similar):\n\n```nix\n{pkgs, ...}: {\n  environment.systemPackages = [pkgs.serpl];\n}\n```\n\n**On Home-Manager**:\n\n```nix\n{pkgs, ...}: {\n  home.packages = [pkgs.serpl];\n}\n```\n\n## Usage\n\n### Basic Commands\n\n- Start the application in the current directory:\n  ```bash\n  serpl\n  ```\n- Start the application and provide the project root path:\n  ```bash\n  serpl --project-root /path/to/project\n  ```\n\n### Key Bindings\n\nDefault key bindings can be customized through the `config.json` file.\n\n#### Default Key Bindings\n\n| Key Combination              | Action                                    |\n| ---------------------------- | ----------------------------------------- |\n| `Ctrl + c`                   | Quit                                      |\n| `Ctrl + d`                   | Quit                                      |\n| `Ctrl + b`                   | Help                                      |\n| `Tab`                        | Switch between tabs                       |\n| `Backtab`                    | Switch to previous tabs                   |\n| `Ctrl + o`                   | Process replace for all files             |\n| `r`                          | Process replace for selected file or line |\n| `Ctrl + n`                   | Toggle search and replace modes           |\n| `Enter`                      | Execute search (for large folders)        |\n| `g` / `Left` / `h`           | Go to top of the list                     |\n| `G` / `Right` / `l`          | Go to bottom of the list                  |\n| `j` / `Down`                 | Move to the next item                     |\n| `k` / `Up`                   | Move to the previous item                 |\n| `/`                          | Search results list                       |\n| `d`                          | Delete selected file or line              |\n| `Esc`                        | Exit the current pane or dialog           |\n| `Enter` (in dialogs) / `y`   | Confirm action                            |\n| `Esc` (in dialogs) / `n`     | Cancel action                             |\n| `h`, `l`, `Tab` (in dialogs) | Navigate dialog options                   |\n\n### Configuration\n\n`serpl` uses a configuration file to manage key bindings and other settings. By default, the path to the configuration file can be found by running `serpl --version`. You can use various file formats for the configuration, such as JSON, JSON5, YAML, TOML, or INI.\n\n#### Example Configurations\n\n\u003cdetails\u003e\n\u003csummary\u003eJSON\u003c/summary\u003e\n \n```json\n{\n  \"keybindings\": {\n    \"\u003cCtrl-d\u003e\": \"Quit\",\n    \"\u003cCtrl-c\u003e\": \"Quit\",\n    \"\u003cTab\u003e\": \"LoopOverTabs\",\n    \"\u003cBacktab\u003e\": \"BackLoopOverTabs\",\n    \"\u003cCtrl-o\u003e\": \"ProcessReplace\",\n    \"\u003cCtrl-b\u003e\": \"ShowHelp\"\n  }\n}\n```\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eJSON5\u003c/summary\u003e\n \n```json5\n{\n  keybindings: {\n    \"\u003cCtrl-d\u003e\": \"Quit\",\n    \"\u003cCtrl-c\u003e\": \"Quit\",\n    \"\u003cTab\u003e\": \"LoopOverTabs\",\n    \"\u003cBacktab\u003e\": \"BackLoopOverTabs\",\n    \"\u003cCtrl-o\u003e\": \"ProcessReplace\",\n    \"\u003cCtrl-b\u003e\": \"ShowHelp\",\n  },\n}\n```\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eYAML\u003c/summary\u003e\n \n```yaml\nkeybindings:\n  \"\u003cCtrl-d\u003e\": \"Quit\"\n  \"\u003cCtrl-c\u003e\": \"Quit\"\n  \"\u003cTab\u003e\": \"LoopOverTabs\"\n  \"\u003cBacktab\u003e\": \"BackLoopOverTabs\"\n  \"\u003cCtrl-o\u003e\": \"ProcessReplace\"\n  \"\u003cCtrl-b\u003e\": \"ShowHelp\"\n```\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eTOML\u003c/summary\u003e\n \n```toml\n[keybindings]\n\"\u003cCtrl-d\u003e\" = \"Quit\"\n\"\u003cCtrl-c\u003e\" = \"Quit\"\n\"\u003cTab\u003e\" = \"LoopOverTabs\"\n\"\u003cBacktab\u003e\" = \"BackLoopOverTabs\"\n\"\u003cCtrl-o\u003e\" = \"ProcessReplace\"\n\"\u003cCtrl-b\u003e\" = \"ShowHelp\"\n```\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eINI\u003c/summary\u003e\n \n```ini\n[keybindings]\n\u003cCtrl-d\u003e = Quit\n\u003cCtrl-c\u003e = Quit\n\u003cTab\u003e = LoopOverTabs\n\u003cBacktab\u003e = BackLoopOverTabs\n\u003cCtrl-o\u003e = ProcessReplace\n\u003cCtrl-b\u003e = ShowHelp\n```\n\u003c/details\u003e\n\nYou can customize the key bindings by modifying the configuration file in the format of your choice.\n\n## Panes\n\n### Search Input\n\n- Input field for entering search keywords.\n- Toggle search modes (Simple, Match Case, Match Whole Word, Match Case Whole Word, Regex, AST Grep).\n  - Simple: Search all occurrences of the keyword.\n  - Match Case: Search occurrences with the same case as the keyword.\n  - Match Whole Word: Search occurrences that match the keyword exactly.\n  - Match Case Whole Word: Search occurrences that match the keyword exactly with the same case.\n  - Regex: Search occurrences using a regular expression.\n  - AST Grep: Search occurrences using AST Grep.\n \n\u003e [!TIP] \n\u003e If current directory is considerebly large, you have to click `Enter` to start the search.\n\n### Replace Input\n\n- Input field for entering replacement text.\n- Toggle replace modes (Simple, Preserve Case, AST Grep).\n  - Simple: Replace all occurrences of the keyword.\n  - Preserve Case: Replace occurrences while preserving the case of the keyword.\n  - AST Grep: Replace occurrences using AST Grep.\n\n### Search Results Pane\n\n- List of files with search results.\n- Navigation to select and view files.\n- Option to delete files from the search results.\n- Search results count and current file count.\n- Ability to search the list using the `/` key.\n\n### Preview Pane\n\n- Display of the selected file with highlighted search results, and context.\n- Navigation to view different matches within the file.\n- Option to delete individual lines containing matches.\n\n## Quick Hints\n- Use the `Ctrl + b` key combination to display the help dialog.\n- Use the `Ctrl + o` key combination to process the replace for all files.\n- Use the `r` key to process the replace for the selected file or line.\n- Use the `Ctrl + n` key combination to toggle between search and replace modes.\n- Use the `g`, `G`, `j`, and `k` keys to navigate through the search results.\n- Use the `d` key to delete the selected file or line.\n \n## Neovim Integration using toggleterm\n\nCheck out the [toggleterm.nvim](https://github.com/akinsho/toggleterm.nvim) plugin for Neovim, which provides a terminal that can be toggled with a key binding.\nOr you can use the following configuration, if you are using [AstroNvim](https://astronvim.com/):\n\n```lua\nreturn {\n  \"akinsho/toggleterm.nvim\",\n  cmd = { \"ToggleTerm\", \"TermExec\" },\n  dependencies = {\n    {\n      \"AstroNvim/astrocore\",\n      opts = function(_, opts)\n        local maps = opts.mappings\n        local astro = require \"astrocore\"\n        maps.n[\"\u003cLeader\u003et\"] = vim.tbl_get(opts, \"_map_sections\", \"t\")\n\n        local serpl = {\n          callback = function()\n            astro.toggle_term_cmd \"serpl\"\n          end,\n          desc = \"ToggleTerm serpl\",\n        }\n        maps.n[\"\u003cLeader\u003esr\"] = { serpl.callback, desc = serpl.desc }\n\n        maps.n[\"\u003cLeader\u003etf\"] = { \"\u003cCmd\u003eToggleTerm direction=float\u003cCR\u003e\", desc = \"ToggleTerm float\" }\n        maps.n[\"\u003cLeader\u003eth\"] = { \"\u003cCmd\u003eToggleTerm size=10 direction=horizontal\u003cCR\u003e\", desc = \"ToggleTerm horizontal split\" }\n        maps.n[\"\u003cLeader\u003etv\"] = { \"\u003cCmd\u003eToggleTerm size=80 direction=vertical\u003cCR\u003e\", desc = \"ToggleTerm vertical split\" }\n        maps.n[\"\u003cF7\u003e\"] = { '\u003cCmd\u003eexecute v:count . \"ToggleTerm\"\u003cCR\u003e', desc = \"Toggle terminal\" }\n        maps.t[\"\u003cF7\u003e\"] = { \"\u003cCmd\u003eToggleTerm\u003cCR\u003e\", desc = \"Toggle terminal\" }\n        maps.i[\"\u003cF7\u003e\"] = { \"\u003cEsc\u003e\u003cCmd\u003eToggleTerm\u003cCR\u003e\", desc = \"Toggle terminal\" }\n        maps.n[\"\u003cC-'\u003e\"] = { '\u003cCmd\u003eexecute v:count . \"ToggleTerm\"\u003cCR\u003e', desc = \"Toggle terminal\" }\n        maps.t[\"\u003cC-'\u003e\"] = { \"\u003cCmd\u003eToggleTerm\u003cCR\u003e\", desc = \"Toggle terminal\" }\n        maps.i[\"\u003cC-'\u003e\"] = { \"\u003cEsc\u003e\u003cCmd\u003eToggleTerm\u003cCR\u003e\", desc = \"Toggle terminal\" }\n      end,\n    },\n  },\n  opts = {\n    highlights = {\n      Normal = { link = \"Normal\" },\n      NormalNC = { link = \"NormalNC\" },\n      NormalFloat = { link = \"NormalFloat\" },\n      FloatBorder = { link = \"FloatBorder\" },\n      StatusLine = { link = \"StatusLine\" },\n      StatusLineNC = { link = \"StatusLineNC\" },\n      WinBar = { link = \"WinBar\" },\n      WinBarNC = { link = \"WinBarNC\" },\n    },\n    size = 10,\n    ---@param t Terminal\n    on_create = function(t)\n      vim.opt_local.foldcolumn = \"0\"\n      vim.opt_local.signcolumn = \"no\"\n      if t.hidden then\n        local toggle = function() t:toggle() end\n        vim.keymap.set({ \"n\", \"t\", \"i\" }, \"\u003cC-'\u003e\", toggle, { desc = \"Toggle terminal\", buffer = t.bufnr })\n        vim.keymap.set({ \"n\", \"t\", \"i\" }, \"\u003cF7\u003e\", toggle, { desc = \"Toggle terminal\", buffer = t.bufnr })\n      end\n    end,\n    shading_factor = 2,\n    direction = \"float\",\n    float_opts = { border = \"rounded\" },\n  },\n}\n```\n\n## Helix integration\n\nYou can add a keybinding like the following to open Serpl inside Helix:\n\n```toml\n[keys.normal.ret]\nt = [\":write-all\", \":insert-output serpl \u003e/dev/tty\", \":redraw\", \":reload-all\"]\n```\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## Contributing\n(WIP)\n\n## Acknowledgements\n- This project was inspired by the [VS Code](https://code.visualstudio.com/) search and replace functionality.\n- This project is built using the awesome [ratatui.rs](https://ratatui.rs) library, and build on top of their [Component Template](https://ratatui.rs/templates/component).\n- Thanks to the [ripgrep](https://github.com/BurntSushi/ripgrep) project for providing the search functionality.\n- Thanks to the [ast-grep](https://ast-grep.github.io) project for providing the AST Grep functionality.\n\n## Similar Projects\n- [repgrep](https://github.com/acheronfail/repgrep): An interactive replacer for ripgrep that makes it easy to find and replace across files on the command line.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyassinebridi%2Fserpl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyassinebridi%2Fserpl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyassinebridi%2Fserpl/lists"}