Last active
November 6, 2024 18:25
-
-
Save bluss/761455e123fbdbf481be9ec0b0bdce58 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This file configures basedpyright for nvim-lspconfig | |
-- This is not the complete lspconfig configuration - lazy.nvim | |
-- configuration merging gathers multiple files for the complete lspconfig configuration. | |
-- global function to silence this thing | |
function SilenceBasedpyright() | |
local function filter_diagnostics(diagnostic) | |
if diagnostic.source == 'basedpyright' then | |
return false | |
end | |
return true | |
end | |
vim.lsp.handlers['textDocument/publishDiagnostics'] = vim.lsp.with( | |
function(_, result, ctx, config) | |
result.diagnostics = vim.tbl_filter(filter_diagnostics, result.diagnostics) | |
vim.lsp.diagnostic.on_publish_diagnostics(_, result, ctx, config) | |
end, | |
{} | |
) | |
end | |
if vim.fn.executable('basedpyright') <= 0 then | |
return {} | |
end | |
local function get_root(fname) | |
local root_func = require("lspconfig.util").root_pattern({"pyproject.toml", ".git"}) | |
local ret = root_func(fname) or vim.fn.getcwd() | |
return ret | |
end | |
return { | |
{ | |
"neovim/nvim-lspconfig", | |
opts = { | |
servers = { | |
basedpyright = { | |
mason = false, | |
cmd = { "basedpyright-langserver", "--stdio" }, | |
filetypes = { 'python' }, | |
single_file_support = true, | |
root_dir = function(fname) return get_root(fname) end, | |
init_options = { | |
diagnostic = { | |
enable = true, | |
}, | |
}, | |
settings = { | |
python = { | |
}, | |
basedpyright = { | |
analysis = { typeCheckingMode = "standard" }, | |
}, | |
}, | |
on_init = function(client, _) | |
client.server_capabilities.semanticTokensProvider = nil; -- turn off semantic tokens | |
local root_func = require("lspconfig.util").root_pattern("pyproject.toml") | |
if root_func(vim.fn.getcwd()) then | |
-- nothing | |
else | |
print("No pyproject: basedpyright linter disabled") | |
SilenceBasedpyright() | |
end | |
end, | |
on_new_config = function(new_config, new_root_dir) | |
-- configure basedpyright's python.pythonPath to be the python executable path for the environment | |
-- vim.print("new root: " .. tostring(new_root_dir)) | |
local root_func = require("lspconfig.util").root_pattern("pyproject.toml") | |
if root_func(new_root_dir) then | |
-- | |
local success, py_path = pcall(function() | |
local pysupport = require("python_support") | |
return pysupport.get_local_python_location(new_root_dir) | |
end) | |
if success and py_path then | |
new_config.settings.python.pythonPath = py_path | |
-- note, one could set extraPaths instead, but those are counted as 'in' the project | |
end | |
if not success then | |
vim.notify("Error: " .. tostring(py_path), vim.log.levels.WARN) | |
end | |
else | |
-- pass | |
end | |
end, | |
}, | |
}, | |
}, | |
}, | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- helper functions for python | |
local M = {} | |
-- python-preference system causes it to find system python outside projects, | |
-- but inside a project it still picks the current project's venv python | |
local _uv_command = {"uv", "run", "-q", "--no-sync", "--python-preference=system", "python"} | |
local _uv_find = {"uv", "python", "find", "-q", "--python-preference=system"} | |
-- Get local python (python in virtualenv with preference, else system python) | |
---@return table: python command arguments | |
function M.get_local_python_cmd() | |
if vim.fn.executable('uv') > 0 then | |
return vim.list_slice(_uv_command) -- copy | |
else | |
return {"python3"} | |
end | |
end | |
local function get_python_finder_cmd() | |
return vim.list_extend(M.get_local_python_cmd(), {"-c", "import sys; import json; print(json.dumps(sys.executable))"}) | |
end | |
local function _system_get_output(cmd, cwd) | |
local proc = vim.system(cmd, {cwd=cwd, timeout=15000, text=false, env={UV_NO_ENV_FILE = "1"}}) | |
local ret = proc:wait() | |
if ret.stderr then | |
vim.notify(ret.stderr, vim.log.levels.WARN) | |
end | |
return ret.stdout | |
end | |
function M.get_local_python_location(cwd) | |
local cmd = get_python_finder_cmd() | |
if #cmd > 1 then | |
local out = _system_get_output(cmd, cwd) | |
local decoded = vim.json.decode(out) | |
return vim.fn.trim(decoded) | |
else | |
return cmd[1] | |
end | |
end | |
local function nonempty(elt) | |
if elt and #elt > 0 then return true else return false end | |
end | |
-- Get local python's sys.path | |
function M.get_py_path(cwd) | |
local cmd = vim.list_extend(M.get_local_python_cmd(), {"-c", "import json; import sys; print(json.dumps(sys.path))"}) | |
local out = _system_get_output(cmd, cwd) | |
local decoded_list = vim.json.decode(out) | |
local non_empty = vim.tbl_filter(nonempty, decoded_list or {}) | |
local ret = vim.tbl_filter(function(elt) return vim.fn.isdirectory(elt) > 0 end, non_empty) | |
return ret | |
end | |
return M |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local M = {} | |
-- live grep in the listed paths | |
---@param paths table: list of directories | |
---@param opts table? | |
function M.live_grep_paths(paths, opts) | |
opts = opts or {} | |
require("telescope.builtin").live_grep(vim.tbl_deep_extend("force", { | |
prompt_title = "Live Grep Paths", | |
search_dirs = paths, | |
}, opts)) | |
end | |
local shorten_path_opts = {path_display={ shorten = { len = 2, exclude = {-1, -2, -3 }}}} | |
---@param str string | |
---@param pfx string | |
---@return boolean | |
local function has_prefix(str, pfx) | |
local len = #pfx | |
return str:sub(1, len) == pfx | |
end | |
---@param str string | |
---@param pfx string | |
---@param sub string | |
---@return string | |
local function sub_prefix(str, pfx, sub) | |
local plen = #pfx | |
return sub .. str:sub(plen + 1) | |
end | |
local function table_is_empty(table_to_check) | |
return table_to_check == nil or next(table_to_check) == nil | |
end | |
---@param opt1 table? | |
---@param opt2 table? | |
---@return table | |
local function combine_opts(opt1, opt2) | |
if opt1 == nil or table_is_empty(opt1) then | |
return opt2 or {} | |
elseif opt2 == nil or table_is_empty(opt2) then | |
return opt1 or {} | |
end | |
return vim.tbl_deep_extend("force", opt1, opt2) | |
end | |
---@param opts table | |
function M.sub_homedir_path_display_func(opts) | |
local tutils = require("telescope.utils") | |
local homedir = vim.fn.expand("~") | |
---@param inner_opts table | |
---@param path string | |
return function(inner_opts, path) | |
if has_prefix(path, homedir) then | |
path = sub_prefix(path, homedir, "~") | |
end | |
local copts | |
if opts.path_display then | |
copts = combine_opts(inner_opts, opts) | |
else | |
copts = opts | |
end | |
return tutils.transform_path(copts, path) | |
end | |
end | |
function M.live_grep_pypath() | |
local py_paths = require("python_support").get_py_path() | |
M.live_grep_paths(py_paths, { | |
prompt_title = "Live Grep Python Env", | |
-- shorten home directory to ~ | |
path_display = M.sub_homedir_path_display_func(shorten_path_opts), | |
additional_args = { "-u" } }) | |
end | |
function M.find_files_pypath(opts) | |
local py_paths = require("python_support").get_py_path() | |
local og = (combine_opts({ | |
prompt_title = "Find Files in Python Env", | |
hidden = true, | |
search_dirs = py_paths, | |
-- shorten home directory to ~ | |
path_display = M.sub_homedir_path_display_func(shorten_path_opts), | |
find_command = {"rg", "--color=never", "--files", "-g*.py", "-u"} | |
}, opts)) | |
require("telescope.builtin").find_files(og) | |
end | |
return M |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment