Skip to content

Commit

Permalink
refactor: soft deprecate Grapple.cycle for Grapple.cycle_tags (#148)
Browse files Browse the repository at this point in the history
* refactor: soft deprecate Grapple.cycle[_{forward|backward}] for Grapple.cycle_tags

* refactor: delete unused function

* refactor: improve naming + add luadocs

* fix: validate cycle direction + update completion values
  • Loading branch information
cbochs authored Mar 31, 2024
1 parent 8648afb commit b52a49d
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 34 deletions.
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ Note, these examples assume you are using the [lazy.nvim](https://github.com/fol
keys = {
{ "<leader>m", "<cmd>Grapple toggle<cr>", desc = "Grapple toggle tag" },
{ "<leader>M", "<cmd>Grapple toggle_tags<cr>", desc = "Grapple open tags window" },
{ "<leader>n", "<cmd>Grapple cycle_tags next<cr>", desc = "Grapple cycle next tag" },
{ "<leader>p", "<cmd>Grapple cycle_tags prev<cr>", desc = "Grapple cycle previous tag" },
},
},
```
Expand Down Expand Up @@ -150,8 +152,8 @@ Example configuration similar to [harpoon.nvim](https://github.com/ThePrimeagen/
{ "<c-n>", "<cmd>Grapple select index=3<cr>", desc = "Select third tag" },
{ "<c-s>", "<cmd>Grapple select index=4<cr>", desc = "Select fourth tag" },

{ "<c-s-p>", "<cmd>Grapple cycle backward<cr>", desc = "Go to previous tag" },
{ "<c-s-n>", "<cmd>Grapple cycle forward<cr>", desc = "Go to next tag" },
{ "<c-s-n>", "<cmd>Grapple cycle_tags next<cr>", desc = "Go to next tag" },
{ "<c-s-p>", "<cmd>Grapple cycle_tags prev<cr>", desc = "Go to previous tag" },
},
},
```
Expand All @@ -178,8 +180,8 @@ Example configuration similar to [arrow.nvim](https://github.com/otavioschwanck/
{ ";", "<cmd>Grapple toggle_tags<cr>", desc = "Toggle tags menu" },

{ "<c-s>", "<cmd>Grapple toggle<cr>", desc = "Toggle tag" },
{ "H", "<cmd>Grapple cycle forward<cr>", desc = "Go to next tag" },
{ "L", "<cmd>Grapple cycle backward<cr>", desc = "Go to previous tag" },
{ "H", "<cmd>Grapple cycle_tags next<cr>", desc = "Go to next tag" },
{ "L", "<cmd>Grapple cycle_tags prev<cr>", desc = "Go to previous tag" },
},
},
```
Expand Down Expand Up @@ -304,13 +306,13 @@ In general, the API is as follows:
Where `opts` in the user command is a list of `value` arguments and `key=value` keyword arguments. For example,

```vim
:Grapple cycle forward scope=cwd
:Grapple cycle_tags next scope=cwd
```

Has the equivalent form

```lua
require("grapple").cycle("forward", { scope = "cwd" })
require("grapple").cycle_tags("next", { scope = "cwd" })
```

### Grapple API
Expand Down Expand Up @@ -419,19 +421,15 @@ require("grapple").select({ index = 3 })

</details>

#### `Grapple.cycle`
#### `Grapple.cycle_tags`

Cycle through and select the next or previous available tag for a given scope.

**API**:

- `require("grapple").cycle(direction, opts)`
- `require("grapple").cycle_backward(opts)`
- `require("grapple").cycle_forward(opts)`
**API**: `require("grapple").cycle_tags(direction, opts)`

Where:

- **`direction`**: `"backward"` | `"forward"`
- **`direction`**: `"next"` | `"prev"`
- **`opts?`**: [`grapple.options`](#grappleoptions) (one of)

**Note**: Starting tag is searched based on one of (in order): `index`, `name`, `path`, `buffer`
Expand All @@ -441,10 +439,10 @@ Where:

```lua
-- Cycle to the previous tagged file
require("grapple").cycle_backward()
require("grapple").cycle_tags("next")

-- Cycle to the next tagged file
require("grapple").cycle_forward()
require("grapple").cycle_tags("prev")
```

</details>
Expand Down
76 changes: 57 additions & 19 deletions lua/grapple.lua
Original file line number Diff line number Diff line change
Expand Up @@ -196,28 +196,73 @@ function Grapple.quickfix(opts)
end
end

---@param current_index? integer
---@param direction "next" | "prev"
---@param length integer
---@return integer
local function next_index(current_index, direction, length)
-- Fancy maths to get the next index for a given direction
-- 1. Change to 0-based indexing
-- 2. Perform index % container length, being careful of negative values
-- 3. Change back to 1-based indexing
-- stylua: ignore
current_index = (
current_index
or direction == "next" and length
or direction == "prev" and 1
) - 1

local next_inc = direction == "next" and 1 or -1
local next_idx = math.fmod(current_index + next_inc + length, length) + 1

return next_idx
end

---Select the next available tag for a given scope
---By default, uses the current scope
---@deprecated Soft-deprecated in favour of Grapple.cycle_tags
---@param opts? grapple.options
function Grapple.cycle_forward(opts)
Grapple.cycle("forward", opts)
Grapple.cycle_tags("next", opts)
end

---Select the previous available tag for a given scope
---By default, uses the current scope
---@deprecated Soft-deprecated in favour of Grapple.cycle_tags
---@param opts? grapple.options
function Grapple.cycle_backward(opts)
Grapple.cycle("backward", opts)
Grapple.cycle_tags("prev", opts)
end

-- Cycle through and select the next or previous available tag for a given scope.
---By default, uses the current scope
---@deprecated Soft-deprecated in favour of Grapple.cycle_tags
---@param direction "forward" | "backward"
---@param opts? grapple.options
function Grapple.cycle(direction, opts)
Grapple.cycle_tags(direction, opts)
end

-- Cycle through and select the next or previous available tag for a given scope.
---By default, uses the current scope
---@param direction "next" | "prev" | "previous" | "forward" | "backward"
---@param opts? grapple.options
function Grapple.cycle_tags(direction, opts)
local App = require("grapple.app")
local app = App.get()

opts = opts or {}

local app = require("grapple.app").get()
-- stylua: ignore
direction = direction == "forward" and "next"
or direction == "backward" and "prev"
or direction == "previous" and "prev"
or direction

if not vim.tbl_contains({ "next", "prev" }, direction) then
return vim.notify(string.format("invalid direction: %s", direction), vim.log.levels.ERROR)
end

app:enter_without_save(opts.scope, function(container)
if container:is_empty() then
return
Expand All @@ -226,20 +271,10 @@ function Grapple.cycle(direction, opts)
local path, _ = extract_path(opts)
opts.path = path

-- Fancy maths to get the next index for a given direction
-- 1. Change to 0-based indexing
-- 2. Perform index % container length, being careful of negative values
-- 3. Change back to 1-based indexing
local index = (
container:find(opts)
or direction == "forward" and container:len()
or direction == "backward" and 1
) - 1
local next_direction = direction == "forward" and 1 or -1
local next_index = math.fmod(index + next_direction + container:len(), container:len()) + 1
local index = next_index(container:find(opts), direction, container:len())

---@diagnostic disable-next-line: redefined-local
local tag, err = container:get({ index = next_index })
local tag, err = container:get({ index = index })
if not tag then
return err
end
Expand Down Expand Up @@ -694,9 +729,7 @@ function Grapple.initialize()
-- Lookup table of API functions and their available arguments
local subcommand_lookup = {
clear_cache = { args = { "scope" }, kwargs = {} },
cycle = { args = { "direction" }, kwargs = use_kwargs },
cycle_backward = { args = {}, kwargs = use_kwargs },
cycle_forward = { args = {}, kwargs = use_kwargs },
cycle_tags = { args = { "direction" }, kwargs = use_kwargs },
open_loaded = { args = {}, kwargs = { "all" } },
open_scopes = { args = {}, kwargs = {} },
open_tags = { args = {}, kwargs = window_kwargs },
Expand All @@ -717,13 +750,18 @@ function Grapple.initialize()
-- Lookup table of arguments and their known values
local argument_lookup = {
all = { "true", "false" },
direction = { "forward", "backward" },
direction = { "next", "prev" },
scope = Util.sort(vim.tbl_keys(app.scope_manager.scopes), Util.as_lower),
style = Util.sort(vim.tbl_keys(app.settings.styles), Util.as_lower),
}

-- API methods which are not actionable
local excluded_subcmds = {
-- Deprecated
"cycle",
"cycle_backward",
"cycle_forward",

"define_scope",
"delete_scope",
"exists",
Expand Down

0 comments on commit b52a49d

Please sign in to comment.