Skip to content
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

proposal: "frozen" file tags #118

Open
cbochs opened this issue Mar 15, 2024 · 7 comments
Open

proposal: "frozen" file tags #118

cbochs opened this issue Mar 15, 2024 · 7 comments

Comments

@cbochs
Copy link
Owner

cbochs commented Mar 15, 2024

Frozen Tags

Context

I have seen this suggestion/idea pop up many times across many different plugins which are attempting to make file/buffer navigation easier. It's even been requested here (#58 #65 #66). This seems to be some way to bridge the gap between harpoon-like file marking and :h mark-motions.

For those unfamiliar, Vim marks allow you to do two things:

  • Use 'a (lowercase) marks to mark a specific location in some file, globally
  • Use 'A (uppercase) to mark a specific location in a specific file, globally

Grapple compliments the above system by allowing users to "tag" a file, but not a specific location. Rather, the cursor is tracked and will be restored when the tag is selected. In addition, tags are scoped per-project instead of globally.

There is a gap, however. What if you want that tag to stop updating, temporarily? What if you want to tag a specific location, but keep it local to the project you're working on?

Proposal

I would like to propose the following: frozen tags. These would be similar to regular tags, but their cursor position would never update. In addition to never updating, there would be more than one allowed per file.

Although it would be recommended that a frozen tag be created with a name, it would not be required. Selection behaviour would still always prefer the non-frozen tag, if not specified.

NOTE: default behaviour would remain the same. Non-frozen (dynamic) tags would still be restricted to one-per-filepath and track the last known cursor location.

For example, creating a frozen tag would look something like this:

require("grapple").tag({ buffer = 0, name = "a", frozen = true })

And to select a frozen tag:

require("grapple").select({ name = "a", frozen = true })

You could convert a non-frozen tag into a frozen tag, creating a new file tag if it doesn't exist (this would likely be a simple wrapper around Grapple.tag):

require("grapple").freeze({ buffer = 0 })

You could convert a frozen tag into a non-frozen tag, overwriting (or not) an existing non-frozen tag if one does exist (again, this would likely be a simple wrapper around Grapple.tag):

require("grapple").unfreeze({ buffer = 0, overwrite = true })

Implementation

The implementation is a bit fuzzy right now, but grapple.tag would look a bit like this:

---@class grapple.tag
---@field path string absolute path
---@field name string | nil (optional) tag name
---@field cursor integer[] (1, 0)-indexed cursor position
---@field frozen boolean

And the grapple.tag_container would need to accommodate more than one file per tag. That would require some refactor work, but not be too difficult.

The UI would need some experimentation to ensure it doesn't distract too much, add more overhead, or feel out-of-place.

@ColinKennedy
Copy link

ColinKennedy commented Mar 16, 2024

To summarize this

  • Allow the option to jump to a specific line + file
    • (currently I believe the default is to go to the previous cursor position in the file). But I think grapple does allow you to save the current cursor position?
  • Allow "naming" a position, similar to marks
    • If naming is based on single letters, maybe text motions could be implemented for these frozen tags?
  • Allow multiple tags per file
  • The UI view of grapple would likely need an update, idk, maybe a tree view?
    • some/file.txt
      • [a] - line 10 - some frozen tag
      • [b] - line 15 - another frozen tag
      • [c] - line 21 - etc
      • ...

Like that?

@cbochs
Copy link
Owner Author

cbochs commented Mar 17, 2024

@ColinKennedy Thanks for taking the time to summarize. To clarify:

I think grapple does allow you to save the current cursor position?

Correct. A cursor position can be specified with cursor = { x, y }, but will be tracked and overridden to the previous cursor position by default. With the proposed changes, frozen = true will ensure a set cursor position is not tracked or overridden.

Allow "naming" a position, similar to marks

Correct. Grapple already allows names with (i.e. name = "a"). However, to push this point a bit, I am leaning towards having named tags remain local to the project, not buffer. That means, for example:

  • Allowed: frozen tag with name a on file A, frozen tag with name b on file A
  • Allowed: frozen tag with name a on file A, frozen tag with name b on file B
  • Disallowed: frozen tag with name a on file A, frozen tag with name a on file B

The UI view of grapple would likely need an update, idk, maybe a tree view?

A tree view would likely complicate things. It could likely remain a list view with a the cursor as an additional detail. For example (mockup),

image

@ColinKennedy
Copy link

A list view would work, though it would be nice if users can customize where each piece of info goes per-row. For example I would prefer to have it be mark | relative/project path | (row, column) whereas others might want (row, column) | mark | relative/project path as your mockup shows

@cbochs
Copy link
Owner Author

cbochs commented Mar 18, 2024

While I agree that providing formatting options would be useful, I think that might be better suited as a later feature. For now, there are already a couple options available in the settings (see style and name_pos).

@tkivela
Copy link

tkivela commented Jun 1, 2024

I find myself looking into this issue every couple of months because it'll be so nice when implemented!

@serranomorante
Copy link

I thought grapple.nvim already remembered cursor position (coming from reading this issue: #72).
Looking forward for this proposal! 👍

@KiLLeRRaT
Copy link

Heh PERFECT timing. I was at it yesterday to hack about in the grapple code to get exactly this feature going. I haven't yet been successful, and your implementation sounds great, because I was just toying with the autocmds.

in #72 there is a workaround to remove the autocmds and to hodge podge some things, but it's not ideal, because if you remove the auto commands, you never get a cursor location saved since it's ONLY saved via autocmd for me, never when I first create the tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants