Permalinks
One of the neat features about GitHub is the generation of permalinks urls that highlights a range of line numbers. This is particularly useful when you want to highlight a chunk of code or a line to show it to someone else.
To do so, just navigate to the file you want on github and click on one line, hit the Shift
key and click on the end line for the code block. This generates a URL with the highlighted block content that you can then use for sharing.
Edit: feedback based on comment
Clicking on the start line number will show the ellipses button ...
hold down shift and click on the end line number. Then click on the overflow button and select Copy permalink
Tip:
You can just add #L{start_line}-L{end_line}
to the URL as follows
https://github.com/{org_name}/{repo_name}/{path_to_file}#L{start_line}-L{end_line}
Note: You can perhaps do the same thing with other version control platforms like bitbucket or gitlabs but I have not checked.
Show me the API!
I was recently working on a project that dynamically generates code snippet from files hosted on github. Naturally, I referred to GitHub's APIs to query file content. Simple right? Well let's dig deeper into it.
Navigating through Github's APIs, I was disappointed to find out there is no API that query a specific line number(s) from a file. The Search API only allows to query the full content of the file. No problem, let's dig into coding logic for post processing.
Show me the code!
To bypass this limitation, I was able to fetch the content of the file using the SearchAPI as follows
async function fetchContent(orgName, repoName, file, ref) {
const baseURL = `https://api.github.com/repos/${orgName}/${repoName}/contents/${file}?ref=${ref}`
let res = await fetch(baseURL).catch(err => {
throw new Error(`Error fetching content from ${baseURL}. ${err}`)
})
if (!res.ok){
throw new Error(`Response status from ${baseURL}: ${res.status}`)
}
let body = await res.text()
// Content body from github is base64 encoded
return Base64.decode(JSON.parse(body).content)
}
let content = await fetchContent(orgName, repoName, file, ref)
This brings in the whole file as text with new line delimiters presented as \n
. You see where I'm going with this 👀
From here, you can split()
the text content using \n
as the separator and store it in an array
content = content.split('\n')
And then simply generate the snippet using a getSlice(content,range)
method
let snippet = getSlice(content,range)
Where getSlice is defined as follows
// Splits the content given the range a-b or just line number a
const getSlice = (content, range) => {
if (range.includes('-')){
var a = range.split("-")[0] - 1
var b = range.split("-")[1]
return content.slice(a,b).join('\r\n')
} else if (parseInt(range)) {
return content[parseInt(range)-1]
}
}
Note: range is passed as a string with a -
delimiter between the start_line and end_line
And thats it!
What about you?
Did you find this useful? I am curious to know if anyone has another approach for this since GitHub does not have an API to do so (yet!)
Top comments (2)
Nice tip! Although the description to get the permalink was not immediately clear until I looked at the gif animation. To clarify: you have to click on the start line number (which will show the overflow button
...
) then hold down shift and click on the end line number. Then click on the overflow button and select `Copy permalink".Initially I was clicking on the start and end of the text which does not show the overflow button.
Thanks for this feedback @myleftshoe ! I will update the content with this 👍