Skip to content

Commit

Permalink
cscope: implement vim's pre-path feature (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhananjaylatkar authored Jul 6, 2024
1 parent 4086cbb commit 6c2b6b7
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 115 deletions.
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,28 @@ Heavily inspired by emacs' [xcscope.el](https://github.com/dkogan/xcscope.el).
- Tries to mimic vim's builtin cscope functionality.
- Provides user command, `:Cscope` which acts same as good old `:cscope`.
- Short commands are supported. e.g. `:Cs f g main`
- No need to add cscope database (`:cscope add <file>`), it is automatically picked from current directory or `db_file` option.
- Keymaps can be disabled using `disable_maps` option.
- Supports `cscope` and `gtags-cscope`. Use `cscope.exec` option to specify executable.
- `:Cstag <symbol>` does `tags` search if no results are found in `cscope`.
- `:Cscope build` builds cscope db
- `vim.g.cscope_maps_statusline_indicator` can be used in statusline to indicate ongoing db build.
- `:Cscope db add <space sepatated files>` add db file(s) to cscope search
- `:Cscope db rm <space sepatated files>` remove db file(s) from cscope search
- For `nvim < 0.9`, legacy cscope will be used. It will support keymaps. It won't have all the niceties of lua port.
- Opens results in quickfix, **telescope**, or **fzf-lua**.
- Has [which-key.nvim](https://github.com/folke/which-key.nvim) hints.
- See [this section](#vim-gutentags) for `vim-gutentags`.

### Cscope DB

- Statically provide table of db paths in config (`db_file`) OR add them at runtime using `:Cs db add ...`
- `:Cs db add <space sepatated files>` add db file(s) to cscope search.
- `:Cs db rm <space sepatated files>` remove db file(s) from cscope search.
- `:Cs db show` show all db connections.
- `:Cs db build` (re)builds db for primary db.
- `vim.g.cscope_maps_statusline_indicator` can be used in statusline to indicate ongoing db build.
- DB path grammar
- `db_file:db_pre_path` db_pre_path (prefix path) will be appended to cscope results.
- e.g. `:Cs db add ~/cscope.out:/home/code/proj2` => results from `~/cscope.out` will be prefixed with `/home/code/proj2/`
- `@` can be used to indicate that parent of `db_file` is `db_pre_path`.
- e.g. `:Cs db add ../proj2/cscope.out:@` => results from `../proj2/cscope.out` will be prefixed with `../proj2/`

### Stack View

- Visualize tree of caller functions and called functions.
Expand Down Expand Up @@ -82,8 +91,6 @@ _cscope_maps_ comes with following defaults:
-- when table of DBs is provided -
-- first DB is "primary" and others are "secondary"
-- primary DB is used for build and project_rooter
-- secondary DBs must be built with absolute paths
-- or paths relative to cwd. Otherwise JUMP will not work.
-- cscope executable
exec = "cscope", -- "cscope" or "gtags-cscope"
-- choose your fav picker
Expand Down
24 changes: 16 additions & 8 deletions doc/cscope_maps.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*cscope_maps.txt* For Neovim >= v0.10.0 Last change: 2024 June 01
*cscope_maps.txt* For Neovim >= v0.10.0 Last change: 2024 July 06

==============================================================================
Table of Contents *cscope_maps-table-of-contents*
Expand Down Expand Up @@ -31,20 +31,30 @@ CSCOPE ~
- Tries to mimic vim’s builtin cscope functionality.
- Provides user command, `:Cscope` which acts same as good old `:cscope`.
- Short commands are supported. e.g. `:Cs f g main`
- No need to add cscope database (`:cscope add <file>`), it is automatically picked from current directory or `db_file` option.
- Keymaps can be disabled using `disable_maps` option.
- Supports `cscope` and `gtags-cscope`. Use `cscope.exec` option to specify executable.
- `:Cstag <symbol>` does `tags` search if no results are found in `cscope`.
- `:Cscope build` builds cscope db
- `vim.g.cscope_maps_statusline_indicator` can be used in statusline to indicate ongoing db build.
- `:Cscope db add <space sepatated files>` add db file(s) to cscope search
- `:Cscope db rm <space sepatated files>` remove db file(s) from cscope search
- For `nvim < 0.9`, legacy cscope will be used. It will support keymaps. It won’t have all the niceties of lua port.
- Opens results in quickfix, **telescope**, or **fzf-lua**.
- Has which-key.nvim <https://github.com/folke/which-key.nvim> hints.
- See |cscope_maps-this-section| for `vim-gutentags`.


CSCOPE DB ~

- Statically provide table of db paths in config (`db_file`) OR add them at runtime using `:Cs db add ...`
- `:Cs db add <space sepatated files>` add db file(s) to cscope search.
- `:Cs db rm <space sepatated files>` remove db file(s) from cscope search.
- `:Cs db show` show all db connections.
- `:Cs db build` (re)builds db for primary db.
- `vim.g.cscope_maps_statusline_indicator` can be used in statusline to indicate ongoing db build.
- DB path grammar
- `db_file:db_pre_path` db_pre_path (prefix path) will be appended to cscope results.
- e.g. `:Cs db add ~/cscope.out:/home/code/proj2` => results from `~/cscope.out` will be prefixed with `/home/code/proj2/`
- `@` can be used to indicate that parent of `db_file` is `db_pre_path`.
- e.g. `:Cs db add ../proj2/cscope.out:@` => results from `../proj2/cscope.out` will be prefixed with `../proj2/`


STACK VIEW ~

- Visualize tree of caller functions and called functions.
Expand Down Expand Up @@ -102,8 +112,6 @@ _cscope_maps_ comes with following defaults:
-- when table of DBs is provided -
-- first DB is "primary" and others are "secondary"
-- primary DB is used for build and project_rooter
-- secondary DBs must be built with absolute paths
-- or paths relative to cwd. Otherwise JUMP will not work.
-- cscope executable
exec = "cscope", -- "cscope" or "gtags-cscope"
-- choose your fav picker
Expand Down
121 changes: 121 additions & 0 deletions lua/cscope/db.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
local utils = require("cscope_maps.utils")
local log = require("cscope_maps.utils.log")

local M = {}

--- conns = { {file = db_file, pre_path = db_pre_path}, ... }
M.conns = {}
M.global_conn = nil

---Get all db connections
---If global connection is declared then use that
---@return table
M.all_conns = function()
M.update_global_conn()
return M.global_conn or M.conns
end

---Get primary db connection
---If global connection is declared then use that
---@return table
M.primary_conn = function()
M.update_global_conn()
if M.global_conn then
return M.global_conn[1]
end
return M.conns[1]
end

---Update primary db connection
---@param file string
---@param pre_path string
M.update_primary_conn = function(file, pre_path)
M.conns[1].file = vim.fs.normalize(file)
M.conns[1].pre_path = vim.fs.normalize(pre_path)
end

---Update global db connection
M.update_global_conn = function()
if vim.g.cscope_maps_db_file then
local file, pre_path = M.sp_file_pre_path(vim.g.cscope_maps_db_file)
M.global_conn = { { file = file, pre_path = pre_path } }
else
M.global_conn = nil
end
end

---Split input to ":Cs db add" into file and pre_path
---@param path string
---@return string
---@return string|nil
M.sp_file_pre_path = function(path)
local sp = vim.split(path, ":")
local file = vim.fs.normalize(sp[1])

---@type string|nil
local pre_path = sp[2]

-- use parent as pre_path if its "@"
if pre_path and pre_path == "@" then
pre_path = utils.get_path_parent(file)
end

-- make it nil if its empty
if pre_path and pre_path == "" then
pre_path = nil
end

-- if pre_path exists, normalize it
if pre_path then
pre_path = vim.fs.normalize(pre_path)
end

return file, pre_path
end

---Find index of db in all connections
---@param file string
---@param pre_path string|nil
---@return integer
M.find = function(file, pre_path)
for i, cons in ipairs(M.conns) do
if cons.file == file and ((pre_path and cons.pre_path == pre_path) or cons.pre_path == nil) then
return i
end
end

return -1
end

---Add db in db connections
---@param path string
M.add = function(path)
local file, pre_path = M.sp_file_pre_path(path)
if M.find(file, pre_path) == -1 then
table.insert(M.conns, { file = file, pre_path = pre_path })
end
end

---Remove db from db connections
---Primary db connection will not be removed
---@param path string
M.remove = function(path)
local file, pre_path = M.sp_file_pre_path(path)
local loc = M.find(file, pre_path)
-- do not remove first entry
if loc > 1 then
table.remove(M.conns, loc)
end
end

M.print_conns = function()
if not M.conns then
log.warn("No connections")
end

for _, conn in ipairs(M.conns) do
log.warn(string.format("db=%s pre_path=%s", conn.file, conn.pre_path))
end
end

return M
Loading

0 comments on commit 6c2b6b7

Please sign in to comment.