Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
linkify filename/line-number entries in github issues in a couple different formats
// ==UserScript==
// @name Perl6-Github-Linkify
// @namespace http://tampermonkey.net/
// @version 0.3.3
// @description Turns paths to perl6 source (core setting, grammar, actions) and moarvm code to clickable links on github issue/PR pages as well as gists
// @author Timo 'timotimo' Paulssen
// @match https://github.com/*/*/issues/*
// @match https://github.com/*/*/pull/*
// @match https://gist.github.com/*
// @grant none
// ==/UserScript==
// 0.3.3 - linkify lines in spec test files
// 0.3.2 - remove debug output and fix src/Perl6/*nqp
// 0.3.1 - silly javascript using + for string concat and math
// 0.3 - linkify more function names in gdb backtraces, don't kill gist syntax highlighting
// 0.2 - gist support
// 0.1 - initial version
(function() {
'use strict';
let moarvm_filename_map = {
"ambiguous": {
"README.md": [ "src/README.md", "src/6model/README.md"],
"args.c": [ "src/spesh/args.c", "src/core/args.c" ],
"graph.h": [ "src/spesh/graph.h", "src/jit/graph.h" ],
"dump.h": [ "src/spesh/dump.h", "src/jit/dump.h" ],
"log.c": [ "src/spesh/log.c", "src/profiler/log.c" ],
"ops.h": [ "src/core/ops.h", "src/strings/ops.h" ],
"dump.c": [ "src/spesh/dump.c", "src/jit/dump.c" ],
"args.h": [ "src/spesh/args.h", "src/core/args.h" ],
"log.h": [ "src/spesh/log.h", "src/profiler/log.h" ],
"io.h": [ "src/io/io.h", "src/platform/io.h" ],
"graph.c": [ "src/spesh/graph.c", "src/jit/graph.c" ],
"ops.c": [ "src/core/ops.c", "src/strings/ops.c" ],
"threads.h": [ "src/core/threads.h", "src/platform/threads.h" ],
"debug.c": [ "src/spesh/debug.c", "src/gc/debug.c" ],
"debug.h": [ "src/spesh/debug.h", "src/gc/debug.h" ]
},
"unique": {
"frame.h": "src/core/frame.h",
"allocation.h": "src/gc/allocation.h",
"plugin.h": "src/spesh/plugin.h",
"filewatchers.c": "src/io/filewatchers.c",
"moar.c": "src/moar.c",
"threshold.c": "src/spesh/threshold.c",
"hll.c": "src/core/hll.c",
"main.c": "src/main.c",
"num.c": "src/math/num.c",
"interp.c": "src/core/interp.c",
"core_expr_tables.h": "src/jit/core_expr_tables.h",
"lookup.c": "src/spesh/lookup.c",
"ext.h": "src/core/ext.h",
"callsite.h": "src/core/callsite.h",
"stats.h": "src/spesh/stats.h",
"worker.c": "src/spesh/worker.c",
"collect.h": "src/gc/collect.h",
"eventloop.h": "src/io/eventloop.h",
"procops.h": "src/io/procops.h",
"nativecall_dyncall.h": "src/core/nativecall_dyncall.h",
"deopt.h": "src/spesh/deopt.h",
"line_coverage.c": "src/instrument/line_coverage.c",
"tile.c": "src/jit/tile.c",
"inline.c": "src/spesh/inline.c",
"stdint.h": "src/platform/stdint.h",
"uthash.h": "src/strings/uthash.h",
"random.h": "src/platform/random.h",
"debugserver.c": "src/debug/debugserver.c",
"core_templates.h": "src/jit/core_templates.h",
"configuration.c": "src/profiler/configuration.c",
"reprs.c": "src/6model/reprs.c",
"decode_stream.c": "src/strings/decode_stream.c",
"ascii.h": "src/strings/ascii.h",
"normalize.h": "src/strings/normalize.h",
"pea.c": "src/spesh/pea.c",
"parse_num.h": "src/strings/parse_num.h",
"validation.h": "src/core/validation.h",
"unicode_gen.h": "src/strings/unicode_gen.h",
"macro.expr": "src/jit/macro.expr",
"containers.h": "src/6model/containers.h",
"lookup.h": "src/spesh/lookup.h",
"exceptions.c": "src/core/exceptions.c",
"utf16.h": "src/strings/utf16.h",
"shiftjis_codeindex.h": "src/strings/shiftjis_codeindex.h",
"finalize.h": "src/gc/finalize.h",
"normalize.c": "src/strings/normalize.c",
"crossthreadwrite.h": "src/instrument/crossthreadwrite.h",
"orchestrate.c": "src/gc/orchestrate.c",
"vector.h": "src/core/vector.h",
"osr.h": "src/spesh/osr.h",
"memmem32.h": "src/platform/memmem32.h",
"linear_scan.c": "src/jit/linear_scan.c",
"dll.h": "src/core/dll.h",
"telemeh.c": "src/profiler/telemeh.c",
"worklist.c": "src/gc/worklist.c",
"sys.c": "src/platform/sys.c",
"crossthreadwrite.c": "src/instrument/crossthreadwrite.c",
"debugserver.h": "src/debug/debugserver.h",
"instrument.c": "src/profiler/instrument.c",
"config.h": "src/gen/config.h",
"configuration.h": "src/profiler/configuration.h",
"num.h": "src/math/num.h",
"signals.c": "src/io/signals.c",
"nativecall.c": "src/core/nativecall.c",
"continuation.h": "src/core/continuation.h",
"worker.h": "src/spesh/worker.h",
"fixedsizealloc.c": "src/core/fixedsizealloc.c",
"grisu.c": "src/math/grisu.c",
"utf16.c": "src/strings/utf16.c",
"memdebug.h": "src/memdebug.h",
"nfg.c": "src/strings/nfg.c",
"threadcontext.c": "src/core/threadcontext.c",
"nativecall_libffi.c": "src/core/nativecall_libffi.c",
"expr_ops.h": "src/jit/expr_ops.h",
"loadbytecode.h": "src/core/loadbytecode.h",
"validation.c": "src/core/validation.c",
"facts.h": "src/spesh/facts.h",
"inline.h": "src/spesh/inline.h",
"sc.h": "src/6model/sc.h",
"tile.h": "src/jit/tile.h",
"intcache.c": "src/core/intcache.c",
"syncsocket.c": "src/io/syncsocket.c",
"osr.c": "src/spesh/osr.c",
"unicode.h": "src/strings/unicode.h",
"6model.h": "src/6model/6model.h",
"dirops.c": "src/io/dirops.c",
"facts.c": "src/spesh/facts.c",
"bithacks.h": "src/bithacks.h",
"gen2.c": "src/gc/gen2.c",
"reprconv.c": "src/6model/reprconv.c",
"unicode_db.c": "src/strings/unicode_db.c",
"unicode.c": "src/strings/unicode.c",
"asyncsocket.h": "src/io/asyncsocket.h",
"latin1.c": "src/strings/latin1.c",
"iterator.c": "src/spesh/iterator.c",
"dead_ins_elimination.h": "src/spesh/dead_ins_elimination.h",
"codegen.h": "src/spesh/codegen.h",
"asyncsocketudp.h": "src/io/asyncsocketudp.h",
"asyncsocketudp.c": "src/io/asyncsocketudp.c",
"shiftjis.c": "src/strings/shiftjis.c",
"coerce.h": "src/core/coerce.h",
"bytecodedump.c": "src/core/bytecodedump.c",
"syncsocket.h": "src/io/syncsocket.h",
"unicode_prop_macros.h": "src/strings/unicode_prop_macros.h",
"reprconv.h": "src/6model/reprconv.h",
"bytecode.c": "src/core/bytecode.c",
"nativecall_libffi.h": "src/core/nativecall_libffi.h",
"utf8_c8.h": "src/strings/utf8_c8.h",
"gen2.h": "src/gc/gen2.h",
"continuation.c": "src/core/continuation.c",
"shiftjis.h": "src/strings/shiftjis.h",
"unsafe.expr": "src/jit/unsafe.expr",
"iterator.h": "src/spesh/iterator.h",
"procops.c": "src/io/procops.c",
"ext.c": "src/core/ext.c",
"oplist": "src/core/oplist",
"dll.c": "src/core/dll.c",
"dead_bb_elimination.h": "src/spesh/dead_bb_elimination.h",
"decode_stream.h": "src/strings/decode_stream.h",
"timers.c": "src/io/timers.c",
"finalize.c": "src/gc/finalize.c",
"nfg.h": "src/strings/nfg.h",
"unicode_ops.h": "src/strings/unicode_ops.h",
"hll.h": "src/core/hll.h",
"windows1252.c": "src/strings/windows1252.c",
"deopt.c": "src/spesh/deopt.c",
"instrument.h": "src/profiler/instrument.h",
"manipulate.h": "src/spesh/manipulate.h",
"codegen.c": "src/spesh/codegen.c",
"callsite.c": "src/core/callsite.c",
"sys.h": "src/platform/sys.h",
"heapsnapshot.c": "src/profiler/heapsnapshot.c",
"exceptions.h": "src/core/exceptions.h",
"roots.c": "src/gc/roots.c",
"collect.c": "src/gc/collect.c",
"instance.h": "src/core/instance.h",
"sc.c": "src/6model/sc.c",
"config.c": "src/gen/config.c",
"coerce.c": "src/core/coerce.c",
"utf8.c": "src/strings/utf8.c",
"serialization.c": "src/6model/serialization.c",
"stub.c": "src/jit/stub.c",
"usages.c": "src/spesh/usages.c",
"bigintops.h": "src/math/bigintops.h",
"regionalloc.h": "src/core/regionalloc.h",
"windows1252.h": "src/strings/windows1252.h",
"expr.c": "src/jit/expr.c",
"timers.h": "src/io/timers.h",
"callstack.c": "src/core/callstack.c",
"fileops.c": "src/io/fileops.c",
"worklist.h": "src/gc/worklist.h",
"interface.h": "src/jit/interface.h",
"arg_guard.c": "src/spesh/arg_guard.c",
"bytecode.h": "src/core/bytecode.h",
"dead_ins_elimination.c": "src/spesh/dead_ins_elimination.c",
"parametric.h": "src/6model/parametric.h",
"compunit.h": "src/core/compunit.h",
"types.h": "src/types.h",
"arg_guard.h": "src/spesh/arg_guard.h",
"pea.h": "src/spesh/pea.h",
"heapsnapshot.h": "src/profiler/heapsnapshot.h",
"loadbytecode.c": "src/core/loadbytecode.c",
"frame.c": "src/core/frame.c",
"time.h": "src/platform/time.h",
"io.c": "src/io/io.c",
"containers.c": "src/6model/containers.c",
"core_templates.expr": "src/jit/core_templates.expr",
"setjmp.h": "src/platform/setjmp.h",
"parse_num.c": "src/strings/parse_num.c",
"profile.h": "src/profiler/profile.h",
"candidate.h": "src/spesh/candidate.h",
"profile.c": "src/profiler/profile.c",
"uthash_types.h": "src/strings/uthash_types.h",
"bootstrap.c": "src/6model/bootstrap.c",
"asyncsocket.c": "src/io/asyncsocket.c",
"filewatchers.h": "src/io/filewatchers.h",
"label.c": "src/jit/label.c",
"wb.h": "src/gc/wb.h",
"roots.h": "src/gc/roots.h",
"plan.c": "src/spesh/plan.c",
"callstack.h": "src/core/callstack.h",
"internal.h": "src/jit/internal.h",
"dead_bb_elimination.c": "src/spesh/dead_bb_elimination.c",
"optimize.c": "src/spesh/optimize.c",
"grisu.h": "src/math/grisu.h",
"eventloop.c": "src/io/eventloop.c",
"fork.h": "src/platform/fork.h",
"threshold.h": "src/spesh/threshold.h",
"dirops.h": "src/io/dirops.h",
"usages.h": "src/spesh/usages.h",
"allocation.c": "src/gc/allocation.c",
"emit_posix_x64.c": "src/jit/emit_posix_x64.c",
"register.h": "src/jit/register.h",
"expr.h": "src/jit/expr.h",
"objectid.h": "src/gc/objectid.h",
"wb.c": "src/gc/wb.c",
"moar.h": "src/moar.h",
"fileops.h": "src/io/fileops.h",
"iter.h": "src/strings/iter.h",
"mmap.h": "src/platform/mmap.h",
"frame_walker.h": "src/spesh/frame_walker.h",
"candidate.c": "src/spesh/candidate.c",
"random.c": "src/platform/random.c",
"threads.c": "src/core/threads.c",
"interface.c": "src/jit/interface.c",
"inttypes.h": "src/platform/inttypes.h",
"oplabels.h": "src/core/oplabels.h",
"utf8.h": "src/strings/utf8.h",
"manipulate.c": "src/spesh/manipulate.c",
"syncfile.c": "src/io/syncfile.c",
"label.h": "src/jit/label.h",
"bigintops.c": "src/math/bigintops.c",
"fixedsizealloc.h": "src/core/fixedsizealloc.h",
"regionalloc.c": "src/core/regionalloc.c",
"orchestrate.h": "src/gc/orchestrate.h",
"gcc_diag.h": "src/gcc_diag.h",
"unicode_uca.c": "src/strings/unicode_uca.c",
"compile.c": "src/jit/compile.c",
"memmem32.c": "src/platform/memmem32.c",
"unicode_ops.c": "src/strings/unicode_ops.c",
"objectid.c": "src/gc/objectid.c",
"compile.h": "src/jit/compile.h",
"plan.h": "src/spesh/plan.h",
"bootstrap.h": "src/6model/bootstrap.h",
"intcache.h": "src/core/intcache.h",
"signals.h": "src/io/signals.h",
"telemeh.h": "src/profiler/telemeh.h",
"memmem.h": "src/platform/memmem.h",
"serialization.h": "src/6model/serialization.h",
"alloc.h": "src/core/alloc.h",
"syncfile.h": "src/io/syncfile.h",
"line_coverage.h": "src/instrument/line_coverage.h",
"shiftjis_codeindex.c": "src/strings/shiftjis_codeindex.c",
"plugin.c": "src/spesh/plugin.c",
"nativecall_dyncall.c": "src/core/nativecall_dyncall.c",
"stats.c": "src/spesh/stats.c",
"utf8_c8.c": "src/strings/utf8_c8.c",
"optimize.h": "src/spesh/optimize.h",
"reprs.h": "src/6model/reprs.h",
"nativecall.h": "src/core/nativecall.h",
"latin1.h": "src/strings/latin1.h",
"interp.h": "src/core/interp.h",
"threadcontext.h": "src/core/threadcontext.h",
"compunit.c": "src/core/compunit.c",
"parametric.c": "src/6model/parametric.c",
"frame_walker.c": "src/spesh/frame_walker.c",
"bytecodedump.h": "src/core/bytecodedump.h",
"ascii.c": "src/strings/ascii.c",
"6model.c": "src/6model/6model.c",
"bitmap.h": "src/core/bitmap.h"
}
}
function makeAlternatives(lis) {
return lis.map(el => el.replace(/\//g, "\\/").replace(/\:/g, "\\:")).join("|")
}
let validCStarters = "(?:" + makeAlternatives(["tc", "instance", "argc", "exitCode", "data", "executing", "idx"]) + ")";
let validMoarPaths = makeAlternatives(["6model", "core", "debug", "gc", "gen", "instrument", "io", "jit", "mast", "math", "platform", "profiler", "spesh", "strings", "moar\\.", "main\\."]);
let validPaths = makeAlternatives(["gen/moar", "src/Perl6/", "SETTING::src/core/", "t/spec/"]) + "|src\\/(?:" + validMoarPaths + ")";
let gdbPart = "("
+ "(?:\\S+\\s\\("
+ `${validCStarters}.*?\\)\\sat\\s`
+ ")?";
let valgrindPart = "" // used to match opening parenthesis here, but it's easier without.
+ "(\\S+?\\.[ch])"
+ "\\:(\\d+)"
+ "\\)";
let restPart = "((?:"
+ validPaths
+ `)\\S+?)\\:(\\d+))`;
let everything = `\\b(?:${valgrindPart}|${gdbPart}${restPart})`;
let matchRegex = new RegExp(everything);
function linkifyParts(element, rx) {
let parts = element.innerText.split(rx);
let target = element;
let originalHTML = element.innerHTML;
let anyChanges = 0;
element.innerText = "";
while (parts.length > 0) {
var written = false;
target.appendChild(document.createTextNode(parts.shift()));
let c_filename = parts.shift();
let c_lineno = parts.shift();
let whole_text = parts.shift();
let path = parts.shift();
let number = parts.shift();
console.log(c_filename, c_lineno, whole_text, path, number);
var extra_post_text = undefined;
var target_url = undefined;
if (typeof path !== "undefined") {
if (path.match(/Perl6-Actions.nqp/)) {
target_url = "https://github.com/rakudo/rakudo/blob/master/src/Perl6/Actions.nqp#L" + (number - 3);
}
else if (path.match(/Perl6-Grammar.nqp/)) {
target_url = "https://github.com/rakudo/rakudo/blob/master/src/Perl6/Grammar.nqp#L" + (number - 3);
}
else if (path.match(/SETTING\:\:src\/.*pm6?/)) {
target_url = "https://github.com/rakudo/rakudo/blob/master/" + path.substr(9) + "#L" + number;
}
else if (path.match(/src\/Perl6\/.*nqp/)) {
target_url = "https://github.com/rakudo/rakudo/blob/master/" + path + "#L" + number;
}
else if (path.match(/t\/spec\/S\d+/)) {
// undo the fudger if necessary
var thepath = path.replace(/\.rakudo.moar$/, ".t");
thepath = thepath.replace(/^t\/spec\//, "");
target_url = "https://github.com/perl6/roast/blob/master/" + thepath + "#L" + number;
}
else if (path.match(/^src\//)) {
target_url = "https://github.com/MoarVM/MoarVM/blob/master/" + path + "#L" + number;
// extra_post_text = whole_text.match(/\s\((?:tc|instance|argc|exitCode).*?\)\sat\s\S+/);
extra_post_text = whole_text.match(/\((?:tc|instance|argc|exitCode).*\)\sat\s\S+/);
if (extra_post_text) {
extra_post_text = extra_post_text[0];
whole_text = whole_text.substr(0, whole_text.length - extra_post_text.length);
}
else {
extra_post_text = undefined;
}
}
if (typeof target_url !== "undefined") {
let linkEl = document.createElement("a");
linkEl.href = target_url;
linkEl.innerText = whole_text;
target.appendChild(linkEl);
if (typeof extra_post_text !== "undefined") {
target.appendChild(document.createTextNode(extra_post_text));
}
written = true;
}
}
else if (typeof c_filename !== "undefined") {
whole_text = c_filename + ":" + c_lineno;
if (moarvm_filename_map.unique.hasOwnProperty(c_filename)) {
target_url = "https://github.com/MoarVM/MoarVM/blob/master/" + moarvm_filename_map.unique[c_filename] + "#L" + c_lineno;
if (typeof target_url !== "undefined") {
let linkEl = document.createElement("a");
linkEl.href = target_url;
linkEl.innerText = whole_text;
target.appendChild(linkEl);
target.appendChild(document.createTextNode(")"));
if (typeof extra_post_text !== "undefined") {
target.appendChild(document.createTextNode(extra_post_text));
}
written = true;
}
}
else if (moarvm_filename_map.ambiguous.hasOwnProperty(c_filename)) {
target.appendChild(document.createTextNode("Ambiguous Filename ["));
moarvm_filename_map.ambiguous[c_filename].forEach((el, idx) => {
target_url = "https://github.com/MoarVM/MoarVM/blob/master/" + el + "#L" + c_lineno;
if (idx != 0) {
target.appendChild(document.createTextNode(", "));
}
let linkEl = document.createElement("a");
linkEl.href = target_url;
linkEl.innerText = el + ":" + c_lineno;
target.appendChild(linkEl);
written = true;
});
if (written) {
target.appendChild(document.createTextNode("])"));
}
}
else {
whole_text = whole_text + ")";
}
}
if (!written && typeof whole_text !== "undefined") {
target.appendChild(document.createTextNode(whole_text));
}
else if (written) {
anyChanges++;
}
}
if (anyChanges == 0) {
target.innerHTML = originalHTML;
}
}
document.querySelectorAll(".comment-body pre").forEach(el => { linkifyParts(el, matchRegex); });
document.querySelectorAll(".js-file-line-container td.blob-code-inner").forEach(el => { linkifyParts(el, matchRegex); });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.