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

Find workspace root #247

Merged
merged 3 commits into from
Oct 11, 2024
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
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ in your default browser using the xdg-open command.
- `enterprise_mode`: enable enterprise mode
- `detect_proxy`: enable or disable proxy detection
- `enable_chat`: enable chat functionality
- `workspace_root`:
- `use_lsp`: Use Neovim's LSP support to find the workspace root, if possible.
- `paths`: paths to files that indicate a workspace root when not using the LSP support
- `find_root`: An optional function that the plugin will call to find the workspace root.
- `tools`: paths to binaries used by the plugin:

- `uname`: not needed on Windows, defaults given.
Expand Down Expand Up @@ -129,6 +133,48 @@ cmp.setup({
})
```

### Workspace Root Directory

The plugin uses a few techniques to find the workspace root directory, which helps to inform the autocomplete and chat context.

1. Call the optional `workspace_root.find_root` function, if provided. This is described below.
2. Query Neovim's built-in LSP support for the workspace root, if `workspace_root.use_lsp` is not set to `false`.
3. Search upward in the filesystem for a file or directory in `workspace_root.paths` that indicates a workspace root.

The default configuration is:

```lua
require('codeium').setup({
workspace_root = {
use_lsp = true,
find_root = nil,
paths = {
".bzr",
".git",
".hg",
".svn",
"_FOSSIL_",
"package.json",
}
}
})
```

The `find_root` function can help the plugin find the workspace root when you are not using Neovim's built-in LSP
provider. For example, this snippet calls into `coc.nvim` to find the workspace root.

```lua
require('codeium').setup({
workspace_root = {
find_root = function()
return vim.fn.CocAction("currentWorkspacePath")
end
}
})
```



## Troubleshooting

The plugin log is written to `~/.cache/nvim/codeium.log`.
Expand Down
9 changes: 4 additions & 5 deletions lua/codeium/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,8 @@ function Server:new()
cursor_offset = 0,
text = text,
line_ending = line_ending,
absolute_path = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ":p"),
relative_path = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ":"),
absolute_uri = util.get_uri(vim.api.nvim_buf_get_name(bufnr)),
workspace_uri = util.get_uri(util.get_project_root()),
}

request("RefreshContextForIdeAction", {
Expand All @@ -453,12 +453,11 @@ function Server:new()
notify.error("failed refresh context: " .. err.out)
return
end
end
)
end)
end

function m.add_workspace()
local project_root = vim.fn.getcwd()
local project_root = util.get_project_root()
-- workspace already tracked by server
if workspaces[project_root] then
return
Expand Down
12 changes: 12 additions & 0 deletions lua/codeium/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ function M.defaults()
enable_index_service = true,
search_max_workspace_file_count = 5000,
file_watch_max_dir_count = 50000,
workspace_root = {
use_lsp = true,
find_root = nil,
paths = {
".bzr",
".git",
".hg",
".svn",
"_FOSSIL_",
"package.json",
},
},
}
end

Expand Down
9 changes: 4 additions & 5 deletions lua/codeium/source.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ local function codeium_to_cmp(comp, offset, right)
local documentation = comp.completion.text

local label = documentation:sub(offset)
if label:sub(- #right) == right then
label = label:sub(1, - #right - 1)
if label:sub(-#right) == right then
label = label:sub(1, -#right - 1)
end

-- We get the completion part that has the largest offset
Expand Down Expand Up @@ -92,7 +92,7 @@ local function get_other_documents(bufnr)
local other_documents = {}

for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].filetype ~= '' and buf ~= bufnr then
if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].filetype ~= "" and buf ~= bufnr then
table.insert(other_documents, buf_to_codeium(buf))
end
end
Expand Down Expand Up @@ -187,7 +187,7 @@ function Source:complete(params, callback)
language = language,
cursor_position = { row = cursor.row - 1, col = cursor.col - 1 },
absolute_uri = util.get_uri(vim.api.nvim_buf_get_name(bufnr)),
workspace_uri = util.get_uri(util.get_relative_path(bufnr)),
workspace_uri = util.get_uri(util.get_project_root()),
line_ending = line_ending,
cursor_offset = cursor_offset,
},
Expand All @@ -205,7 +205,6 @@ function Source:complete(params, callback)
end
end
)

end

return Source
53 changes: 48 additions & 5 deletions lua/codeium/util.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local enums = require("codeium.enums")
local config = require("codeium.config")
local io = require("codeium.io")
local M = {}

Expand All @@ -19,13 +20,13 @@ function M.get_editor_options(bufnr)

return {
tab_size = M.fallback_call({
{ vim.api.nvim_get_option_value, "shiftwidth", { buf = bufnr, } },
{ vim.api.nvim_get_option_value, "tabstop", { buf = bufnr, } },
{ vim.api.nvim_get_option_value, "shiftwidth", { buf = bufnr } },
{ vim.api.nvim_get_option_value, "tabstop", { buf = bufnr } },
{ vim.api.nvim_get_option_value, "shiftwidth" },
{ vim.api.nvim_get_option_value, "tabstop" },
}, greater_than_zero, 4),
insert_spaces = M.fallback_call({
{ vim.api.nvim_get_option_value, "expandtab", { buf = bufnr, } },
{ vim.api.nvim_get_option_value, "expandtab", { buf = bufnr } },
{ vim.api.nvim_get_option_value, "expandtab" },
}, nil, true),
}
Expand All @@ -35,8 +36,50 @@ function M.get_newline(bufnr)
return enums.line_endings[vim.bo[bufnr].fileformat] or "\n"
end

function M.get_relative_path(bufnr)
return vim.fn.fnamemodify(vim.api.nvim_buf_get_name(bufnr), ":")
local cached_roots = {}
local function _get_project_root()
if config.options.workspace_root.find_root then
root = config.options.workspace_root.find_root()
if root then
return root
end
end

if config.options.workspace_root.use_lsp then
root = vim.lsp.buf.list_workspace_folders()[0]
if root then
return root
end
end

-- From the CWD, walk up the tree looking for a directory that contains one of the project root files
local candidates = config.options.workspace_root.paths
local result = vim.fs.find(candidates, {
path = cwd,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dimfeld where is this cwd variable coming from? I notice that this pr fixed things for mac, but on windows it fails. Seems the failure is because this cwd variable is nil. How does it get populated on mac?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, that was missed when I was moving around some code. M.get_project_root should pass its wd variable to _get_project_root for the value of cwd.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitted #248 as a fix

upward = true,
limit = 1,
})

local found = result[1]
local dir
if found then
dir = vim.fs.dirname(found)
else
dir = cwd
end

return dir
end

function M.get_project_root()
local wd = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(0), ":p:h") or vim.fn.getcwd()
if cached_roots[wd] then
return cached_roots[wd]
end

local root = _get_project_root()
cached_roots[wd] = root
return root
end

function M.get_uri(path)
Expand Down
Loading