GitHub Code Guides

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

Verze ze dne 01. 02. 2017. Zobrazit nejnovější verzi.

// ==UserScript==
// @name         GitHub Code Guides
// @version      1.1.1
// @description  A userscript that allows you to add one or more vertical guidelines to the code
// @license      https://creativecommons.org/licenses/by-sa/4.0/
// @namespace    http://github.com/Mottie
// @include      https://github.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @run-at       document-idle
// @author       Rob Garrison
// ==/UserScript==
/* copy into textarea to check the guides
         1         2         3         4         5         6         7         8
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345
*/
/* global document, prompt, GM_getValue, GM_setValue, GM_registerMenuCommand */
/* jshint esnext:true, unused:true */
(() => {
	"use strict";
	const style = document.createElement("style");
	// eslint-disable-next-line one-var
	let guides = GM_getValue("ghcg-guides", [{
			chars: 80,
			color: "rgba(0, 0, 0, .3)",
			width: 0.2
		}]),
		font = GM_getValue("ghcg-font", "Menlo");

	function addGuides(vals) {
		let css = "";
		// to align the guides *after* the setting, we need to add 1, then add
		// another 0.1 to give the guide a tiny bit of white space to the left
		vals.forEach(guide => {
			let start = parseFloat(guide.chars) + 1.1;
			// eslint-disable-next-line one-var
			const size = parseFloat(guide.width) || 0.2,
				// each line needs to be at least 0.2ch in width to be visible
				end = (start + (size > 0.2 ? size : 0.2)).toFixed(1),
				color = guide.color || "rgba(0, 0, 0, .3)";
			start = start.toFixed(1);
			css += `transparent ${start}ch, ${color} ${start}ch, ${color} ${end}ch, transparent ${end}ch, `;
		});
		style.textContent = `
			span.blob-code-inner {
				display: block !important;
			}
			span.blob-code-inner, td.blob-code-inner:not(.blob-code-hunk) {
				font-family: "${font}", Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
				background: linear-gradient(to right, transparent 0%, ${css} transparent 100%) !important;
			}
		`;
	}

	function validateGuides(vals) {
		let last = 0;
		const valid = [];
		if (!Array.isArray(vals)) {
			console.log("Code-Guides Userscript: Invalid guidelines", vals);
			return;
		}
		// Object.keys() creates an array of string values
		const lines = vals.sort((a, b) => parseFloat(a.chars) - parseFloat(b.chars));
		lines.forEach(line => {
			const num = parseFloat(line.chars);
			// 0.2 is the width of the "ch" in CSS to make it visible
			if (num >= last + line.width) {
				valid.push(line);
				last = num;
			}
		});
		if (valid.length) {
			guides = valid;
			GM_setValue("ghcg-guides", valid);
			GM_setValue("ghcg-font", font);
			addGuides(valid);
		}
	}

	document.querySelector("head").appendChild(style);
	validateGuides(guides);

	// Add GM options
	GM_registerMenuCommand("Set code guideline position & color", () => {
		let val = prompt(`Enter valid JSON [{ "chars":80, "color":"#f00", "width":0.2 }, ...}`, JSON.stringify(guides));
		if (val !== null) {
			try {
				val = JSON.parse(val);
				validateGuides(val);
			} catch (err) {
				console.log(err);
			}
		}
	});

	GM_registerMenuCommand("Set code guideline default font", () => {
		const val = prompt("Enter code font (monospaced)", font);
		if (val !== null) {
			font = val;
			validateGuides(guides);
		}
	});
})();