GitHub Code Guides

A userscript that allows you to add one or more vertical guidelines to the code

As of 2017-03-25. See the latest version.

  1. // ==UserScript==
  2. // @name GitHub Code Guides
  3. // @version 1.1.2
  4. // @description A userscript that allows you to add one or more vertical guidelines to the code
  5. // @license https://creativecommons.org/licenses/by-sa/4.0/
  6. // @namespace https://github.com/Mottie
  7. // @include https://github.com/*
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @grant GM_registerMenuCommand
  11. // @run-at document-idle
  12. // @author Rob Garrison
  13. // ==/UserScript==
  14. /* copy into textarea to check the guides
  15. 1 2 3 4 5 6 7 8
  16. 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345
  17. */
  18. (() => {
  19. "use strict";
  20. const style = document.createElement("style");
  21. // eslint-disable-next-line one-var
  22. let guides = GM_getValue("ghcg-guides", [{
  23. chars: 80,
  24. color: "rgba(0, 0, 0, .3)",
  25. width: 0.2
  26. }]),
  27. font = GM_getValue("ghcg-font", "Menlo");
  28.  
  29. function addGuides(vals) {
  30. let css = "";
  31. // to align the guides *after* the setting, we need to add 1, then add
  32. // another 0.1 to give the guide a tiny bit of white space to the left
  33. vals.forEach(guide => {
  34. let start = parseFloat(guide.chars) + 1.1;
  35. // eslint-disable-next-line one-var
  36. const size = parseFloat(guide.width) || 0.2,
  37. // each line needs to be at least 0.2ch in width to be visible
  38. end = (start + (size > 0.2 ? size : 0.2)).toFixed(1),
  39. color = guide.color || "rgba(0, 0, 0, .3)";
  40. start = start.toFixed(1);
  41. css += `transparent ${start}ch, ${color} ${start}ch, ${color} ${end}ch, transparent ${end}ch, `;
  42. });
  43. style.textContent = `
  44. span.blob-code-inner {
  45. display: block !important;
  46. }
  47. span.blob-code-inner, td.blob-code-inner:not(.blob-code-hunk) {
  48. font-family: "${font}", Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
  49. background: linear-gradient(to right, transparent 0%, ${css} transparent 100%) !important;
  50. }
  51. `;
  52. }
  53.  
  54. function validateGuides(vals) {
  55. let last = 0;
  56. const valid = [];
  57. if (!Array.isArray(vals)) {
  58. console.log("Code-Guides Userscript: Invalid guidelines", vals);
  59. return;
  60. }
  61. // Object.keys() creates an array of string values
  62. const lines = vals.sort((a, b) => parseFloat(a.chars) - parseFloat(b.chars));
  63. lines.forEach(line => {
  64. const num = parseFloat(line.chars);
  65. // 0.2 is the width of the "ch" in CSS to make it visible
  66. if (num >= last + line.width) {
  67. valid.push(line);
  68. last = num;
  69. }
  70. });
  71. if (valid.length) {
  72. guides = valid;
  73. GM_setValue("ghcg-guides", valid);
  74. GM_setValue("ghcg-font", font);
  75. addGuides(valid);
  76. }
  77. }
  78.  
  79. document.querySelector("head").appendChild(style);
  80. validateGuides(guides);
  81.  
  82. // Add GM options
  83. GM_registerMenuCommand("Set code guideline position & color", () => {
  84. let val = prompt(
  85. `Enter valid JSON [{ "chars":80, "color":"#f00", "width":0.2 }, ...}]`,
  86. JSON.stringify(guides)
  87. );
  88. if (val !== null) {
  89. try {
  90. val = JSON.parse(val);
  91. validateGuides(val);
  92. } catch (err) {
  93. console.log(err);
  94. }
  95. }
  96. });
  97.  
  98. GM_registerMenuCommand("Set code guideline default font", () => {
  99. const val = prompt("Enter code font (monospaced)", font);
  100. if (val !== null) {
  101. font = val;
  102. validateGuides(guides);
  103. }
  104. });
  105. })();