+
+![tafuta logo](logo.svg)
+
# tafuta.nvim
-A tiny 🤏🏾, wrapper around ripgrep, for making search 🔍 blazingly fast ⚡ and easy to use 👌🏾 in your favorite editor 🥰.
+
+![Lua](https://img.shields.io/badge/Made%20with%20Lua-blueviolet.svg?style=for-the-badge&logo=lua)
+[![GitHub release (latest by date)](https://img.shields.io/github/v/release/mistweaverco/tafuta.nvim?style=for-the-badge)](https://github.com/mistweaverco/tafuta.nvim/releases/latest)
+
+[Install](#install) • [Usage](#usage)
+
+
+
+A tiny 🤏 wrapper around ripgrep for
+making search 🔍 blazingly fast ⚡ and
+easy to use 👌 in your favorite editor 🥰.
+
+Tafuta is swahili for "search".
+
+It allows you to search for text in your project.
+
+
+
+
+
+## Install
+
+> [!WARNING]
+> Requires Neovim 0.10.0+
+
+Via [lazy.nvim](https://github.com/folke/lazy.nvim):
+
+### Configuration
+
+```lua
+require('lazy').setup({
+ -- blazingly fast ⚡ search 🔍
+ {
+ 'mistweaverco/tafuta.nvim',
+ cmd = { "Tf" },
+ config = function()
+ -- Setup is required, even if you don't pass any options
+ require('tafuta').setup({
+ -- The user command to run the search e.g. `:Tf `
+ user_command = "Tf",
+ -- rg options, a lua table of options to pass to rg
+ rg_options = nil,
+ })
+ end,
+ },
+})
+```
+
+## Usage
+
+```
+:Tf
+```
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000..d42016b
Binary files /dev/null and b/logo.png differ
diff --git a/logo.svg b/logo.svg
new file mode 100644
index 0000000..926581c
--- /dev/null
+++ b/logo.svg
@@ -0,0 +1,208 @@
+
+
diff --git a/lua/tafuta/config/init.lua b/lua/tafuta/config/init.lua
new file mode 100644
index 0000000..6d32fff
--- /dev/null
+++ b/lua/tafuta/config/init.lua
@@ -0,0 +1,18 @@
+local M = {}
+
+M.defaults = {
+ -- The user command to run the search e.g. `:Tf `
+ user_command = "Tf",
+}
+
+M.options = {}
+
+M.setup = function(config)
+ M.options = vim.tbl_deep_extend("force", M.defaults, config or {})
+end
+
+M.get = function()
+ return M.options
+end
+
+return M
diff --git a/lua/tafuta/globals/init.lua b/lua/tafuta/globals/init.lua
new file mode 100644
index 0000000..43d4a18
--- /dev/null
+++ b/lua/tafuta/globals/init.lua
@@ -0,0 +1,5 @@
+local M = {}
+
+M.VERSION = "1.0.0"
+
+return M
diff --git a/lua/tafuta/init.lua b/lua/tafuta/init.lua
new file mode 100644
index 0000000..9461473
--- /dev/null
+++ b/lua/tafuta/init.lua
@@ -0,0 +1,76 @@
+local GLOBALS = require("tafuta.globals")
+local CONFIG = require("tafuta.config")
+local M = {}
+
+local rg_installed = vim.fn.executable("rg") == 1
+
+local async_run = vim.schedule_wrap(function(res)
+ local code = res.code
+ if code == 0 then
+ local matches = vim.split(res.stdout, "\n", { trimempty = true })
+ if vim.tbl_isempty(matches) then
+ vim.notify("❌ no match", vim.log.levels.INFO, { title = "Tafuta" })
+ return
+ end
+ vim.fn.setqflist({}, "r", {
+ title = "Tafuta results (" .. #matches .. ")",
+ lines = matches,
+ })
+ vim.cmd("copen")
+ elseif code == 1 then
+ vim.notify("❌ no match", vim.log.levels.INFO, { title = "Tafuta" })
+ else
+ vim.notify("💀 error occurred", vim.log.levels.ERROR, { title = "Tafuta" })
+ end
+end)
+
+local search = function(search_query)
+ local search_command = { "rg", "--vimgrep" }
+ local rg_options = CONFIG.get().rg_options
+ if rg_options ~= nil then
+ for _, option in ipairs(rg_options) do
+ table.insert(search_command, option)
+ end
+ end
+ table.insert(search_command, search_query)
+ vim.system(search_command, { text = true }, async_run)
+end
+
+M.setup = function(config)
+ CONFIG.setup(config)
+ local user_command = CONFIG.get().user_command
+ if user_command ~= nil then
+ vim.api.nvim_create_user_command(user_command, function(a)
+ if a.args == "" then
+ vim.notify("❌ No search query provided", vim.log.levels.INFO, { title = "Tafuta" })
+ return
+ end
+ M.run(a.args)
+ end, {
+ nargs = "?",
+ desc = "Tf, blazingly fast ⚡ search 🔍 using ripgrep 🦀",
+ })
+ end
+end
+
+M.run = function(search_query)
+ if not rg_installed then
+ vim.notify("❌ ripgrep not found on the system", vim.log.levels.WARN, { title = "Tafuta" })
+ return
+ end
+ if search_query == nil then
+ search_query = vim.fn.input("Search: ")
+ end
+ search(search_query)
+end
+
+M.version = function()
+ local neovim_version = vim.fn.execute("version")
+ vim.notify(
+ "Tafuta version: " .. GLOBALS.VERSION .. "\n\n" .. "Neovim version: " .. neovim_version,
+ "info",
+ { title = "Tafuta" }
+ )
+end
+
+return M
diff --git a/scripts/release.sh b/scripts/release.sh
new file mode 100755
index 0000000..fe3f2c9
--- /dev/null
+++ b/scripts/release.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+GH_TAG="v$VERSION"
+
+set_version() {
+ ./scripts/set-version.sh
+}
+
+check_git_dirty() {
+ if [[ -n $(git status -s) ]]; then
+ echo "Working directory is dirty. Please commit or stash your changes before releasing."
+ exit 1
+ fi
+}
+
+do_gh_release() {
+ echo "Creating new release $GH_TAG"
+ gh release create --generate-notes "$GH_TAG"
+}
+
+boot() {
+ set_version
+ check_git_dirty
+ do_gh_release
+}
+
+boot
diff --git a/scripts/set-version.sh b/scripts/set-version.sh
new file mode 100755
index 0000000..23be5e5
--- /dev/null
+++ b/scripts/set-version.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+update_lua_globals_version() {
+ local tmp
+ tmp=$(mktemp)
+ sed -e "s/VERSION = \".*\"/VERSION = \"$VERSION\"/" ./lua/tafuta/globals/init.lua > "$tmp" && mv "$tmp" ./lua/tafuta/globals/init.lua
+}
+
+update_lua_globals_version