Skip to content

Commit 41bc22e

Browse files
committed
Initial commit
1 parent eabd61e commit 41bc22e

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.luarc.json

Diff for: README.md

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Neovim Sourcegraph Integration
2+
3+
This repository contains a Lua script (`sourcegraph.lua`) that integrates
4+
[Sourcegraph](https://sourcegraph.com/) search into Neovim. This tool helps
5+
developers search for code snippets directly from their Neovim environment.
6+
7+
## Features
8+
9+
- Fetch selected code within Neovim
10+
- URL encode the fetched code for search
11+
- Construct a Sourcegraph URL including the selected code
12+
- Open the URL in the default browser to show search results on Sourcegraph
13+
- Contextual search based on the file type of the current buffer
14+
15+
## Usage
16+
17+
After you've installed the script (see Installation section below), you can use
18+
it by simply selecting text in visual mode in Neovim and pressing `<leader>S`.
19+
This will construct a Sourcegraph search URL with the selected text and open it
20+
in your default web browser.
21+
22+
## Installation
23+
24+
To install the script, follow these steps:
25+
26+
1. Clone the repository or download the `sourcegraph.lua` file.
27+
2. Move the `sourcegraph.lua` file to your Neovim configuration directory (usually `~/.config/nvim/lua`).
28+
3. Add the following line to your Neovim configuration file (`init.vim` or `init.lua`): `require'sourcegraph'`.
29+
4. Change the mapping to the location of your path
30+
31+
E.g.
32+
33+
```sh
34+
vnoremap <leader>S :lua require'philiplinell.sourcegraph'.search_sourcegraph()<CR>
35+
36+
```
37+
38+
My path is `config/nvim/lua/philiplinell/sourcegraph.lua`.
39+
40+
## Contributing
41+
42+
Contributions are welcome! Please submit a pull request or open an issue if you have any improvements or suggestions.
43+
44+
## Disclaimer
45+
46+
I am not used to the neovim API, lua or sourcegraph!
47+
48+
The majority of `sourcegraph.lua` was written with the help of ChatGPT, as well
49+
as the majority of this README.
50+
51+
These are some of the prompts that I used
52+
53+
```
54+
I would like to create a neovim plugin, in lua, that takes the text I have selected in visual mode and open that in a browser.
55+
56+
The text selected should be used instead of QUERY in the following string:
57+
58+
https://sourcegraph.com/search?q=context:global+QUERY&patternType=standard&sm=1
59+
```
60+
61+
```
62+
I'll create a repository that has the sourcegraph.lua file. Can you suggest a readme for the repository?
63+
```

Diff for: sourcegraph.lua

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
--[[
2+
This script allows you to quickly search for a selected piece of code
3+
in Sourcegraph directly from Neovim. When you highlight text in visual
4+
mode and press <leader>S, the script fetches the selected text, URL encodes
5+
it, and constructs a Sourcegraph search URL. The search is also tailored
6+
to the file type you're currently working with in Neovim. The script then
7+
opens the constructed URL in your default web browser, taking you straight
8+
to the search results on Sourcegraph. This helps you swiftly find usage
9+
examples, definitions, and other relevant information about the selected
10+
piece of code on Sourcegraph.
11+
]]
12+
13+
-- Disclaimer: Written with the help of ChatGPT 4
14+
15+
-- Create a module M.
16+
local M = {}
17+
18+
-- Function to convert a character to its hexadecimal value.
19+
local function char_to_hex(c)
20+
return string.format("%%%02X", string.byte(c))
21+
end
22+
23+
-- Function to URL encode a string.
24+
-- From https://gist.github.com/liukun/f9ce7d6d14fa45fe9b924a3eed5c3d99
25+
local function url_encode(url)
26+
-- If url is nil, return nil.
27+
if url == nil then
28+
return
29+
end
30+
31+
-- Replace newline characters with carriage return + newline.
32+
url = url:gsub("\n", "\r\n")
33+
34+
-- URL encode non-alphanumeric characters.
35+
url = url:gsub("([^%w ])", char_to_hex)
36+
37+
-- Replace spaces with '+'.
38+
url = url:gsub(" ", "+")
39+
return url
40+
end
41+
42+
-- Main function for searching Sourcegraph with the selected text.
43+
function M.search_sourcegraph()
44+
-- Get the start and end position of the selected text.
45+
local _, vs_line, vs_col, _ = unpack(vim.fn.getpos("'<"))
46+
local _, ve_line, ve_col, _ = unpack(vim.fn.getpos("'>"))
47+
48+
-- Get the selected text.
49+
local selected_text = vim.fn.getline(vs_line, ve_line)
50+
51+
-- If the selected text is only one line, just get the selected part.
52+
-- If it's multiple lines, concatenate them with newline characters.
53+
if #selected_text == 1 then
54+
selected_text = selected_text[1]:sub(vs_col, ve_col)
55+
else
56+
selected_text[1] = selected_text[1]:sub(vs_col)
57+
selected_text[#selected_text] = selected_text[#selected_text]:sub(1, ve_col)
58+
selected_text = table.concat(selected_text, '\n')
59+
end
60+
61+
-- If no text was selected, print an error message and return.
62+
if not selected_text then
63+
print("Error: No text selected.")
64+
return
65+
end
66+
67+
-- URL encode the selected text.
68+
local encoded_text = url_encode(selected_text)
69+
70+
-- Get the filetype of the current buffer.
71+
local filetype = vim.bo.filetype
72+
local lang_query = ""
73+
74+
-- Lookup table for matching Neovim filetypes to Sourcegraph language names.
75+
local filetype_to_sourcegraph_lang = {
76+
go = "Go",
77+
python = "Python",
78+
javascript = "JavaScript",
79+
cpp = "C++",
80+
markdown = "Markdown",
81+
lua = "Lua",
82+
html = "HTML"
83+
-- Add more file types as needed
84+
}
85+
86+
-- If the filetype is found in the lookup table, append it to the Sourcegraph query.
87+
if filetype_to_sourcegraph_lang[filetype] then
88+
lang_query = "+lang:" .. filetype_to_sourcegraph_lang[filetype]
89+
else
90+
-- If not, print a warning message.
91+
print("Warning: Filetype " .. filetype .. " not found in Sourcegraph language dictionary.")
92+
end
93+
94+
-- Construct the Sourcegraph URL.
95+
local url = "https://sourcegraph.com/search?q=context:global+" .. encoded_text .. lang_query .. "&patternType=standard&sm=1"
96+
97+
-- Determine the operating system and use the appropriate command to open the URL in the default browser.
98+
local OS = string.lower(jit.os)
99+
if OS == "osx" then
100+
os.execute('open ' .. url .. ' &')
101+
elseif OS == "linux" then
102+
os.execute('xdg-open ' .. url .. ' &')
103+
elseif OS == "windows" then
104+
os.execute('start ' .. url)
105+
else
106+
print("Error: Unrecognized OS.")
107+
end
108+
end
109+
110+
-- Map the function to the <leader>S key in visual mode.
111+
vim.api.nvim_exec([[
112+
vnoremap <leader>S :lua require'philiplinell.sourcegraph'.search_sourcegraph()<CR>
113+
]], false)
114+
115+
return M

0 commit comments

Comments
 (0)