Skip to content

Commit

Permalink
cscope: pre-path
Browse files Browse the repository at this point in the history
Implement vim's pre-path feature.
  • Loading branch information
dhananjaylatkar committed Jul 6, 2024
1 parent 5b82eaa commit 942991f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 39 deletions.
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,27 @@ 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

- No need to add cscope database, it is automatically picked from current directory or `db_file` option.
- `: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.
- `:Cscope db build` builds cscope db of 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.
- `@` can be used to indicate that parent of `db_file` is `db_pre_path`.
- e.g. `Cscope db add ../proj2/cscope.out:@` => results from `../proj2/cscope.out` will be prefixed with `../proj2/`
- e.g. `Cscope db add ~/cscope.out:/home/code/proj2` => results from `~/cscope.out` will be prefixed with `/home/code/proj2/`

### Stack View

- Visualize tree of caller functions and called functions.
Expand Down
54 changes: 27 additions & 27 deletions lua/cscope/db.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ local log = require("cscope_maps.utils.log")

local M = {}

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

Expand All @@ -28,58 +28,58 @@ end

---Update primary db connection
---@param file string
---@param rel string
M.update_primary_conn = function(file, rel)
---@param pre_path string
M.update_primary_conn = function(file, pre_path)
M.conns[1].file = vim.fs.normalize(file)
M.conns[1].rel = vim.fs.normalize(rel)
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, rel = M.sp_file_rel(vim.g.cscope_maps_db_file)
M.global_conn = { { file = file, rel = rel } }
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 rel
---Split input to ":Cs db add" into file and pre_path
---@param path string
---@return string
---@return string|nil
M.sp_file_rel = function(path)
M.sp_file_pre_path = function(path)
local sp = vim.split(path, ":")
local file = vim.fs.normalize(sp[1])

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

-- use parent as rel if its "@"
if rel and rel == "@" then
rel = utils.get_path_parent(file)
-- 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 rel and rel == "" then
rel = nil
if pre_path and pre_path == "" then
pre_path = nil
end

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

return file, rel
return file, pre_path
end

---Find index of db in all connections
---@param file string
---@param rel string|nil
---@param pre_path string|nil
---@return integer
M.find = function(file, rel)
M.find = function(file, pre_path)
for i, cons in ipairs(M.conns) do
if cons.file == file and ((rel and cons.rel == rel) or cons.rel == nil) then
if cons.file == file and ((pre_path and cons.pre_path == pre_path) or cons.pre_path == nil) then
return i
end
end
Expand All @@ -90,18 +90,18 @@ end
---Add db in db connections
---@param path string
M.add = function(path)
local file, rel = M.sp_file_rel(path)
if M.find(file, rel) == -1 then
table.insert(M.conns, { file = file, rel = rel })
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, rel = M.sp_file_rel(path)
local loc = M.find(file, rel)
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)
Expand All @@ -114,7 +114,7 @@ M.print_conns = function()
end

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

Expand Down
14 changes: 7 additions & 7 deletions lua/cscope/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ M.push_tagstack = function()
vim.fn.settagstack(vim.fn.win_getid(), { items = items }, "t")
end

M.parse_line = function(line, db_rel)
M.parse_line = function(line, db_pre_path)
local t = {}

-- Populate t with filename, context and linenumber
local sp = vim.split(line, "%s+")

t.filename = sp[1]
if db_rel then
t.filename = vim.fs.joinpath(db_rel, t.filename)
if db_pre_path then
t.filename = vim.fs.joinpath(db_pre_path, t.filename)
end
t.filename = utils.get_rel_path(vim.fn.getcwd(), t.filename)

Expand All @@ -131,14 +131,14 @@ M.parse_line = function(line, db_rel)
return t
end

M.parse_output = function(cs_out, db_rel)
M.parse_output = function(cs_out, db_pre_path)
-- Parse cscope output to be populated in QuickFix List
-- setqflist() takes list of dicts to be shown in QF List. See :h setqflist()

local res = {}

for line in string.gmatch(cs_out, "([^\n]+)") do
local parsed_line = M.parse_line(line, db_rel)
local parsed_line = M.parse_line(line, db_pre_path)
table.insert(res, parsed_line)
end

Expand Down Expand Up @@ -186,14 +186,14 @@ M.get_result = function(op_n, op_s, symbol, hide_log)

if M.opts.exec == "cscope" then
for _, db_con in ipairs(db_conns) do
local db_file, db_rel = db_con.file, db_con.rel
local db_file, db_pre_path = db_con.file, db_con.pre_path
if vim.loop.fs_stat(db_file) ~= nil then
local _cmd = string.format("%s -f %s", cmd, db_file)
print(_cmd)
out = M.cmd_exec(_cmd)
if out ~= "" then
any_res = true
res = vim.tbl_deep_extend("keep", res, M.parse_output(out, db_rel))
res = vim.tbl_deep_extend("keep", res, M.parse_output(out, db_pre_path))
end
end
end
Expand Down

0 comments on commit 942991f

Please sign in to comment.