link2code crafts direct URLs to source on GitHub
For every file given, it compares local revisions to those upstream. The most recent, common revision is used for the direct link. Line numbers, and ranges, are supported by appending ":start[-end]" to the filepath.
Git submodules and worktrees are supported. Files in trees that are not git repositories are skipped.
> link2code --help
Usage:
link2code FILES... [flags]
Examples:
link2code Makefile
link2code Makefile:5-10
link2code repo1/Makefile repo2/cmd/my-tool.go repo3/README.md:25-30
rg 'search term' -n | link2code
Flags:
--colon-filenames use this if you have filenames or directories with ':' in them - otherwise parsing will fail
-h, --help help for link2code
> link2code README.md link2code/link2code.go:3-16 ../codesearch/cs/main.go
https://github.com/coxley/link2code/tree/e24d3cc/README.md
https://github.com/coxley/link2code/tree/e24d3cc/link2code/link2code.go#L3-L16
https://github.com/coxley/codesearch/tree/c0973ac/cs/main.go
go install github.com/coxley/link2code@latest
This is great for Vim.
Because of how simple it is, I haven't created an installable plugin (though perhaps that's exactly why I should). Feel free to copy or modify what I use:
<leader><leader>l: Copy the Github Permalink to the clipboard<leader><leader>b: Copy the Github Blame Permalink to the clipboard<leader>ol: Copy the Github Permalink and open in your browser<leader>ob: Copy the Github Blame Permalink and open in your browser
Works for both current line in normal mode and visually selected regions.
localfunctionlink2code(opts)
opts=optsor {}
localblame=opts.blameorfalselocalopen=opts.openorfalse-- If called from a user command with :range, opts has line1/line2localline1=opts.line1orvim.fn.line(".")
localline2=opts.line2orline1localline_rangeifline2>line1thenline_range=string.format("%d-%d", line1, line2)
elseline_range=string.format("%d", line1)
endlocalfile_path=vim.fn.expand("%:p")
localfile_pos=string.format("%s:%s", file_path, line_range)
localcmdifblamethencmd=string.format("link2code --blame %s 2> /dev/null", file_pos)
elsecmd=string.format("link2code %s 2> /dev/null", file_pos)
endlocallink=vim.fn.system(cmd)
link=link:gsub("%s*$", "")
vim.fn.setreg("+", link)
vim.cmd.redraw()
vim.api.nvim_echo({ { "Copied to clipboard: " ..link, "None" } }, false, {})
ifopenandlink~="" thenvim.ui.open(link)
endreturnlinkendvim.api.nvim_create_user_command("LinkToCode", function(opts)
localopen=falselocalblame=falsefor_, arginipairs(opts.fargs) doifarg=="open" thenopen=trueendifarg=="blame" thenblame=trueendendlink2code({
blame=blame,
open=open,
line1=opts.line1,
line2=opts.line2,
})
end, {
range=true,
nargs="*",
})
vim.keymap.set({ "n", "v" }, "<leader><leader>l", ":LinkToCode<CR>", options)
vim.keymap.set({ "n", "v" }, "<leader><leader>b", ":LinkToCode blame<CR>", options)
vim.keymap.set({ "n", "v" }, "<leader>ol", ":LinkToCode open<CR>", options)
vim.keymap.set({ "n", "v" }, "<leader>ob", ":LinkToCode open blame<CR>", options)