Skip to content

feat: permit "scope" for grapple tagging operations #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ require("grapple").setup({

Create a scoped tag on a file or buffer with an (optional) tag key.

**Command**: `:GrappleTag [key={index} or key={name}] [buffer={buffer}] [file_path={file_path}]`
**Command**: `:GrappleTag [key={index} or key={name}] [buffer={buffer}] [file_path={file_path}] [scope={scope}]`

**API**: `require("grapple").tag(opts)`

Expand All @@ -148,6 +148,7 @@ Create a scoped tag on a file or buffer with an (optional) tag key.
* **`buffer?`**: `integer` (default: `0`)
* **`file_path?`**: `string` (overrides `buffer`)
* **`key?`**: [`Grapple.TagKey`](#grappletagkey)
* **`scope?`**: [`Grapple.ScopeResolverLike`](#grapplescoperesolverlike) (default: `settings.scope`)

**Note**: only one tag can be created _per scope per file_. If a tag already exists for the given file or buffer, it will be overridden with the new tag.

Expand All @@ -160,16 +161,19 @@ require("grapple").tag()
-- Tag a file using its file path
require("grapple").tag({ file_path = "{file_path}" })

-- Tag the curent buffer using a specified key
-- Tag the current buffer using a specified key
require("grapple").tag({ key = 1 })
require("grapple").tag({ key = "{name}" })

-- Tag the current buffer in a specified scope
require("grapple").tag({ scope = "global" })
```

#### `grapple#untag`

Remove a scoped tag on a file or buffer.

**Command**: `:GrappleUntag [key={name} or key={index}] [buffer={buffer}] [file_path={file_path}]`
**Command**: `:GrappleUntag [key={name} or key={index}] [buffer={buffer}] [file_path={file_path}] [scope={scope}]`

**API**: `require("grapple").untag(opts)`

Expand All @@ -178,6 +182,7 @@ Remove a scoped tag on a file or buffer.
* **`buffer?`**: `integer` (default: `0`)
* **`file_path?`**: `string` (overrides `buffer`)
* **`key?`**: [`Grapple.TagKey`](#grappletagkey) (overrides `buffer` and `file_path`)
* **`scope?`**: [`Grapple.ScopeResolverLike`](#grapplescoperesolverlike) (default: `settings.scope`)

**Examples**

Expand All @@ -191,13 +196,16 @@ require("grapple").untag({ file_path = "{file_path}" })
-- Untag a file using its tag key
require("grapple").untag({ key = 1 })
require("grapple").untag({ key = "{name}" })

-- Untag a the current buffer from a scope
require("grapple").untag({ scope = "global" })
```

#### `grapple#toggle`

Toggle a tag or untag on a file or buffer.

**Command**: `:GrappleToggle [key={index} or key={name}] [buffer={buffer}] [file_path={file_path}]`
**Command**: `:GrappleToggle [key={index} or key={name}] [buffer={buffer}] [file_path={file_path}] [scope={scope}]`

**API**: `require("grapple").toggle(opts)`

Expand All @@ -206,6 +214,7 @@ Toggle a tag or untag on a file or buffer.
* **`buffer?`**: `integer` (default: `0`)
* **`file_path?`**: `string` (overrides `buffer`)
* **`key?`**: [`Grapple.TagKey`](#grappletagkey) (behaviour inherited from [grapple#tag](#grappletag) and [grapple#untag](#grappleuntag))
* **`scope?`**: [`Grapple.ScopeResolverLike`](#grapplescoperesolverlike)

**Examples**

Expand Down Expand Up @@ -291,12 +300,16 @@ require("grapple").key()
* **`buffer?`**: `integer` (default: `0`)
* **`file_path?`**: `string` (overrides `buffer`)
* **`key?`**: [`Grapple.TagKey`](#grappletagkey) (overrides `buffer` and `file_path`)
* **`scope?`**: [`Grapple.ScopeResolverLike`](#grapplescoperesolverlike) (default: `settings.scope`)

**Examples**

```lua
-- Check whether the current buffer is tagged or not
require("grapple").exists()

-- Check for a tag in a different scope
require("grapple").exists({ scope = "global" })
```

#### `grapple#cycle`
Expand Down Expand Up @@ -714,6 +727,7 @@ Options available for most top-level tagging actions (e.g. tag, untag, select, t
* **`buffer`**: `integer`
* **`file_path`**: `string`
* **`key`**: [`Grapple.TagKey`](#grappletagkey)
* **`scope`**: [`Grapple.Scope`](#grapplescope)

---

Expand Down
17 changes: 10 additions & 7 deletions lua/grapple.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ local initialized = false
--- @field buffer integer
--- @field file_path string
--- @field key Grapple.TagKey
--- @field scope Grapple.Scope

grapple.resolvers = require("grapple.scope_resolvers")

---@param overrides? Grapple.Settings
function grapple.initialize()
if initialized then
return
Expand All @@ -35,15 +35,15 @@ end
function grapple.tag(opts)
opts = vim.tbl_extend("force", { buffer = 0 }, opts or {})

local scope = require("grapple.state").ensure_loaded(settings.scope)
local scope = require("grapple.state").ensure_loaded(opts.scope or settings.scope)
require("grapple.tags").tag(scope, opts)
end

---@param opts? Grapple.Options
function grapple.untag(opts)
opts = vim.tbl_extend("force", { buffer = 0 }, opts or {})

local scope = require("grapple.state").ensure_loaded(settings.scope)
local scope = require("grapple.state").ensure_loaded(opts.scope or settings.scope)
require("grapple.tags").untag(scope, opts)
end

Expand All @@ -68,15 +68,15 @@ end
function grapple.find(opts)
opts = vim.tbl_extend("force", { buffer = 0 }, opts or {})

local scope = require("grapple.state").ensure_loaded(settings.scope)
local scope = require("grapple.state").ensure_loaded(opts.scope or settings.scope)
return require("grapple.tags").find(scope, opts)
end

---@param opts? Grapple.Options
function grapple.key(opts)
opts = vim.tbl_extend("force", { buffer = 0 }, opts or {})

local scope = require("grapple.state").ensure_loaded(settings.scope)
local scope = require("grapple.state").ensure_loaded(opts.scope or settings.scope)
return require("grapple.tags").key(scope, opts)
end

Expand All @@ -85,12 +85,15 @@ function grapple.exists(opts)
return grapple.key(opts) ~= nil
end

---@param opts? Grapple.Options
---@param direction Grapple.Direction
---@param opts? Grapple.Options
function grapple.cycle(opts, direction)
opts = opts or {}

local tag_key = grapple.key(opts)
local start_index = (type(tag_key) == "number") and tag_key or 0
local scope = require("grapple.state").ensure_loaded(settings.scope)
local scope = require("grapple.state").ensure_loaded(opts.scope or settings.scope)

local tag = require("grapple.tags").next(scope, start_index, direction)
if tag ~= nil then
require("grapple.tags").select(tag)
Expand Down
26 changes: 15 additions & 11 deletions tests/spec/grapple_spec.lua
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
describe("grapple", function()
before_each(function()
require("grapple").setup({ scope = "none" })
require("grapple").reset()
end)

describe("#tag", function()
it("creates a tag for the current buffer", function()
require("grapple").tag()
assert.is_true(require("grapple").exists(), "tag shoud exist")
require("grapple").tag({ scope = "none" })
assert.is_true(require("grapple").exists({ scope = "none" }), "tag should exist")
end)

it("does not create a tag in a different scope", function()
require("grapple").tag({ scope = "none" })
assert.is_false(require("grapple").exists({ scope = "git" }), "tag should not exist")
end)
end)

describe("#untag", function()
it("removes a tag on the current buffer", function()
require("grapple").tag()
require("grapple").untag()
assert.is_false(require("grapple").exists(), "tag should not exist")
require("grapple").tag({ scope = "none" })
require("grapple").untag({ scope = "none" })
assert.is_false(require("grapple").exists({ scope = "none" }), "tag should not exist")
end)
end)

describe("#toggle", function()
it("creates a tag on the current buffer when it does not exist", function()
require("grapple").toggle()
assert.is_true(require("grapple").exists(), "tag shoud exist")
require("grapple").toggle({ scope = "none" })
assert.is_true(require("grapple").exists({ scope = "none" }), "tag should exist")
end)

it("removes a tag on the current buffer when it does exist", function()
require("grapple").tag()
require("grapple").toggle()
assert.is_false(require("grapple").exists(), "tag not shoud exist")
require("grapple").tag({ scope = "none" })
require("grapple").toggle({ scope = "none" })
assert.is_false(require("grapple").exists({ scope = "none" }), "tag not should exist")
end)
end)

Expand Down