├── .gitignore ├── README.md ├── index.js ├── modhelp1.gif └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # modhelp 2 | 3 | 4 | 5 | Uses `marked-terminal` to render a README.md for any `npm` module in the terminal. 6 | 7 | Now with built-in pager! Page up/down, arrow keys to scroll line-by-line, q to quit. I added this because piping to `less`, even with -r, doesn't work right with ANSI escape codes. 8 | 9 | ## Install 10 | 11 | ```sh 12 | npm install -g modhelp 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```sh 18 | modhelp themodule 19 | ``` 20 | 21 | [Tiny Villages: Horizontally Scaling Society](http://runvnc.github.io/tinyvillage) 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | function dt() { process.stdout.write('.'); } 3 | 4 | dt(); 5 | 6 | get = require('http-get-shim'); 7 | dt(); 8 | 9 | var marked = require('marked'); 10 | dt(); 11 | 12 | term = require('terminal-kit').terminal; 13 | dt(); 14 | 15 | TerminalRenderer = require('marked-terminal'); 16 | dt(); 17 | 18 | marked.setOptions({ 19 | renderer: new TerminalRenderer() 20 | }); 21 | dt(); 22 | 23 | var mod = process.argv[2]; 24 | 25 | var lines = []; 26 | var line = 0; 27 | 28 | var rows = term.height - 1; 29 | var pageNum = 1; 30 | var lastShown = 0; 31 | 32 | var nextStatus = ''; 33 | 34 | function statusLine(str) { 35 | term.moveTo(1,term.height); 36 | if (!str) str = "q: quit, n/p/pgup/pgdown, up/down arrow|j/k: scroll, /: search" + 37 | " Line " + (line+1) + " of " + lines.length; 38 | term.eraseLine(); 39 | term.dim.bgBlack.white(str); 40 | term.column(1); 41 | } 42 | 43 | var searched = ''; 44 | function search(text) { 45 | searched = text; 46 | statusLine('Searching for "'+text+'"'); 47 | setTimeout(function() { 48 | var found = false; 49 | var l = line; 50 | do { 51 | l++; 52 | found = l=0; 53 | } while (!found && l < lines.length); 54 | if (found) { 55 | line = l; 56 | nextStatus = 'Found ' + text; 57 | showPage(l); 58 | } else { 59 | statusLine('Not found.'); 60 | } 61 | }, 1); 62 | } 63 | 64 | function showPage(startLine) { 65 | term.clear(); 66 | var endLine = startLine + rows; 67 | var i = startLine; 68 | 69 | function inner() { 70 | if (i < lines.length -1) { 71 | console.log(lines[i]); 72 | } 73 | if (i-startLine < (rows-3)) { 74 | i+=1; 75 | inner(); 76 | } else { 77 | term.getCursorLocation(function(err, x, y) { 78 | if (y < rows-1 && i < endLine && i 0) { 133 | line -= 1; 134 | term.moveTo(1,1); 135 | term.insertLine(1); 136 | term.moveTo(1,1); 137 | console.log(lines[line]); 138 | statusLine(); 139 | } 140 | break; 141 | case 'p': 142 | case 'PAGE_UP': 143 | if (line > 0) line -= Math.round(rows/2); 144 | if (line < 0) line = 0; 145 | showPage(line); 146 | break; 147 | case 'n': 148 | case 'PAGE_DOWN': 149 | if (line < lines.length-1) line += Math.round(rows/2); 150 | if (line > lines.length-1) line = lines.length-rows-1; 151 | if (lastShown+1