diff --git a/lua/sg/rpc.lua b/lua/sg/rpc.lua index bcc113dc..33ea7389 100644 --- a/lua/sg/rpc.lua +++ b/lua/sg/rpc.lua @@ -82,8 +82,15 @@ function rpc.get_info(callback) end --- Get info about current sourcegraph info -function rpc.get_link(path, line, col, callback) - req("sourcegraph/link", { path = path, line = line, col = col }, callback) +---@param path string +---@param position { start_line: number, start_col: number, end_line: number, end_col: number } +---@param callback any +function rpc.get_link(path, position, callback) + ---@type table + local args = vim.deepcopy(position) + args.path = path + + req("sourcegraph/link", args, callback) end function rpc.get_remote_url(path, callback) diff --git a/plugin/sg.lua b/plugin/sg.lua index fc0279f5..fab5233f 100644 --- a/plugin/sg.lua +++ b/plugin/sg.lua @@ -137,11 +137,39 @@ end, { --- Get a sourcegraph link to the current repo + file + line. --- Automatically adds it to your '+' register ---@command ]] -vim.api.nvim_create_user_command("SourcegraphLink", function() - local cursor = vim.api.nvim_win_get_cursor(0) +vim.api.nvim_create_user_command("SourcegraphLink", function(args) print "requesting link..." - require("sg.rpc").get_link(vim.api.nvim_buf_get_name(0), cursor[1], cursor[2] + 1, function(err, link) + local region = vim.region(0, "'<", "'>", "v", true) + local keys = vim.tbl_keys(region) + table.sort(keys) + + local row1 = args.line1 - 1 + local row2 = args.line2 - 1 + + local first = keys[1] + local last = keys[#keys] + + local range + if first == row1 and last == row2 then + -- We have a visual selection + range = { + start_line = first + 1, + start_col = region[first][1], + end_line = last + 1, + end_col = region[last][2], + } + else + -- Just some range passed, or no range at all + range = { + start_line = args.line1, + start_col = 0, + end_line = args.line2, + end_col = 0, + } + end + + require("sg.rpc").get_link(vim.api.nvim_buf_get_name(0), range, function(err, link) if err or not link then print("[sourcegraph] Failed to get link:", link) return @@ -152,6 +180,7 @@ vim.api.nvim_create_user_command("SourcegraphLink", function() end) end, { desc = "Get a sourcegraph link to the current location", + range = 2, }) ---@command SourcegraphSearch [[ diff --git a/scratch/server.lua b/scratch/server.lua deleted file mode 100644 index 8aa22355..00000000 --- a/scratch/server.lua +++ /dev/null @@ -1,44 +0,0 @@ -local uv = vim.loop - -local redirect_server = function(callback) - print "starting server..." - - local contents = "" - - local server = uv.new_tcp() - server:bind("127.0.0.1", 8080) - server:listen(1024 * 1000, function(err) - assert(not err, err) - - local client = uv.new_tcp() - server:accept(client) - client:read_start(function(client_err, chunk) - assert(not client_err, client_err) - if chunk then - contents = contents .. chunk - - client:write [[ -HTTP/1.1 200 OK -Content-Type: html - - -
Success - Navigate back to Neovim
-]] - - client:shutdown() - client:close() - - callback(contents) - end - - server:shutdown() - server:close() - end) - end) - - print "server started..." -end - -redirect_server(function(contents) - print("server stopping...", contents) -end) diff --git a/src/bin/sg-lsp.rs b/src/bin/sg-lsp.rs index 98256373..44768013 100644 --- a/src/bin/sg-lsp.rs +++ b/src/bin/sg-lsp.rs @@ -42,31 +42,6 @@ mod sg_read { #[tokio::main] async fn main() -> Result<()> { - let file_path = "/home/tjdevries/.cache/nvim/sg-lsp.log"; - - // TODO: Make logging work for everyone and configurable, - // but for now I don't want to write to other people's systems - if Path::new(file_path).exists() { - let logfile = FileAppender::builder() - // Pattern: https://docs.rs/log4rs/*/log4rs/encode/pattern/index.html - .encoder(Box::new(PatternEncoder::new("{l} - {m}\n"))) - .build(file_path)?; - - let config = Config::builder() - .appender(Appender::builder().build("logfile", Box::new(logfile))) - .build( - Root::builder() - .appender("logfile") - .build(LevelFilter::Trace), - )?; - - // Use this to change log levels at runtime. - // This means you can change the default log level to trace - // if you are trying to debug an issue and need more logs on then turn it off - // once you are done. - let _handle = log4rs::init_config(config)?; - } - // Note that we must have our logging only write out to stderr. info!("starting generic LSP server"); diff --git a/src/nvim.rs b/src/nvim.rs index 259ad61e..c340768b 100644 --- a/src/nvim.rs +++ b/src/nvim.rs @@ -184,8 +184,10 @@ pub enum RequestData { #[serde(rename = "sourcegraph/link")] SourcegraphLink { path: String, - line: usize, - col: usize, + start_line: usize, + start_col: usize, + end_line: usize, + end_col: usize, }, #[serde(rename = "sourcegraph/get_remote_url")] @@ -320,14 +322,29 @@ impl Request { Ok(Response::new(id, ResponseData::SourcegraphInfo(value))) } - RequestData::SourcegraphLink { path, line, col } => { + RequestData::SourcegraphLink { + path, + start_line, + start_col, + end_line, + end_col, + } => { let link = match Entry::new(&path).await? { Entry::File(file) => { let endpoint = get_endpoint(); let remote = file.remote.0; let path = file.path; - format!("{endpoint}/{remote}/-/blob/{path}?L{line}:{col}") + let prefix = format!("{endpoint}/{remote}/-/blob/{path}"); + if start_line == end_line && start_col == end_col { + if start_col == 0 { + format!("{prefix}?L{start_line}") + } else { + format!("{prefix}?L{start_line}:{start_col}") + } + } else { + format!("{prefix}?L{start_line}:{start_col}-{end_line}:{end_col}") + } } Entry::Directory(dir) => { let endpoint = get_endpoint();