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

Feature Request (Project Scope for bookmarks) #7

Open
elge70 opened this issue May 2, 2023 · 6 comments · May be fixed by #15
Open

Feature Request (Project Scope for bookmarks) #7

elge70 opened this issue May 2, 2023 · 6 comments · May be fixed by #15

Comments

@elge70
Copy link

elge70 commented May 2, 2023

Is it possible to give an option to save booksmarks per project also instead of global scope.

@ttytm
Copy link
Contributor

ttytm commented May 21, 2023

If that's of any help: Harpoon is a nice plugin for project scope mark / anchor based navigation. They work well in conjunction.

@ten3roberts
Copy link

I've thought the same, scoped bookmarks would be amazing.

Harpoon is wonderful as well, but it is not tailored for marking a specific point in a file, but rather the file itself.

@ten3roberts ten3roberts linked a pull request Nov 8, 2023 that will close this issue
@Nullarity
Copy link

Nullarity commented May 27, 2024

If that's of any help: Harpoon is a nice plugin for project scope mark / anchor based navigation. They work well in conjunction.

I came to this plugin because I couldn't get Harpoon to work. The documentation for Harpoon is poor, lacking clear instructions on how to delete marks. Although it mentions how to integrate Telescope, it again provides no information on how to delete marked files. Despite having 6k stars, I found this plugin better. And yes, having project scope for bookmarks would be very appreciated.

@droopy4096
Copy link

droopy4096 commented Nov 20, 2024

looking at code:

require('bookmarks').setup {
  -- sign_priority = 8,  --set bookmark sign priority to cover other sign
  save_file = vim.fn.expand "$HOME/.bookmarks", -- bookmarks save file path

I'm wondering whether we can alter save_file to point to current project dir. I'm lacking knowledge of how to extract that information from nvim though (i.e. how to get current project path).

@droopy4096
Copy link

droopy4096 commented Nov 20, 2024

I've got as far as

      save_file = function()
        local project_dir = vim.fn.finddir(".git", ".;");
        local project_elements=vim.fn.split(project_dir, "/")
        local path_elements=table.unpack(project_elements, 0, vim.fn.len(project_elements) - 1 )
        return vim.fn.join(path_elements,"/")
      end,

but save_file expects string and not function so that's a dead end for now.

@ESSO0428
Copy link

ESSO0428 commented Dec 4, 2024

I've got as far as

      save_file = function()
        local project_dir = vim.fn.finddir(".git", ".;");
        local project_elements=vim.fn.split(project_dir, "/")
        local path_elements=table.unpack(project_elements, 0, vim.fn.len(project_elements) - 1 )
        return vim.fn.join(path_elements,"/")
      end,

but save_file expects string and not function so that's a dead end for now.

Hellow @droopy4096, have you solved this issue?

I noticed the discussion about implementing project-scoped bookmarks. I've created a configuration that solves this issue by dynamically saving bookmarks based on the current working directory. This approach ensures that each project has its own bookmark file stored in a dedicated directory.

Here’s my complete configuration:

-- Helper function to get the appropriate path separator for the OS
local function get_path_sep()
  if jit then
    if jit.os == "Windows" then
      return '\\'
    else
      return '/'
    end
  else
    return package.config:sub(1, 1)
  end
end

-- Ensure that the given directory exists, create it if necessary
local function ensure_directory_exists(dir_path)
  if vim.fn.exists(dir_path) == 0 or vim.fn.isdirectory(dir_path) == 0 then
    -- Create directory recursively, similar to `mkdir -p`
    vim.fn.mkdir(dir_path, "p")
  end
end

-- Generate the path for the bookmark file, scoped to the current project
local function get_bookmark_path()
  local path_sep = get_path_sep()
  local base_filename = vim.fn.getcwd()

  -- Handle Windows paths by replacing ':' with '_'
  if jit and jit.os == 'Windows' then
    base_filename = base_filename:gsub(':', '_')
  end

  -- Define the directory for storing bookmarks
  local bookmark_dir = vim.fn.stdpath('data') .. path_sep .. "nvim_bookmarks"
  -- Ensure the directory exists
  ensure_directory_exists(bookmark_dir)

  -- Return the full path to the bookmark file
  return bookmark_dir .. path_sep .. base_filename:gsub(path_sep, '_') .. '.json'
end

-- Define the path for the bookmark file
local bookmark_file_path = get_bookmark_path()

-- Bookmarks plugin setup
require("bookmarks").setup {
  save_file = bookmark_file_path, -- Save bookmarks in the project-scoped file
  keywords = {
    ["@t"] = "☑️ ", -- Mark annotation starts with @t, sign as `Todo`
    ["@w"] = "⚠️ ", -- Mark annotation starts with @w, sign as `Warn`
    ["@f"] = "🐞", -- Mark annotation starts with @f, sign as `Fix`
    ["@n"] = "󰍨 ", -- Mark annotation starts with @n, sign as `Note`
  },
  on_attach = function(bufnr)
    local bm = require "bookmarks"
    local map = vim.keymap.set
    map("n", "mm", bm.bookmark_toggle) -- Add or remove bookmark at the current line
    map("n", "ma", bm.bookmark_ann)    -- Add or edit mark annotation at the current line
    map("n", "mc", bm.bookmark_clean)  -- Clean all marks in the local buffer
    map("n", "mk", bm.bookmark_next)   -- Jump to the next mark in the local buffer
    map("n", "mi", bm.bookmark_prev)   -- Jump to the previous mark in the local buffer
    map("n", "ml", bm.bookmark_list)   -- Show marked file list in the quickfix window
  end,
  signs = {
    ann = { hl = "BookMarksAnn", text = "🔖", numhl = "BookMarksAnnNr", linehl = "BookMarksAnnLn" },
  }
}

Explanation:

Project-specific bookmarks

Each project's bookmarks are stored in a JSON file under nvim_bookmarks, with the filename based on the current working directory.
Cross-platform compatibility

Handles path separators and file naming differences for Windows and Unix-like systems.
Ease of use

Feel free to try it out, I hope this helps!

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

Successfully merging a pull request may close this issue.

6 participants