You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					102 lines
				
				3.0 KiB
			
		
		
			
		
	
	
					102 lines
				
				3.0 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var common = require('./common');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// get snippet for a single line, respecting maxLength
							 | 
						||
| 
								 | 
							
								function getLine(buffer, lineStart, lineEnd, position, maxLineLength) {
							 | 
						||
| 
								 | 
							
								  var head = '';
							 | 
						||
| 
								 | 
							
								  var tail = '';
							 | 
						||
| 
								 | 
							
								  var maxHalfLength = Math.floor(maxLineLength / 2) - 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (position - lineStart > maxHalfLength) {
							 | 
						||
| 
								 | 
							
								    head = ' ... ';
							 | 
						||
| 
								 | 
							
								    lineStart = position - maxHalfLength + head.length;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (lineEnd - position > maxHalfLength) {
							 | 
						||
| 
								 | 
							
								    tail = ' ...';
							 | 
						||
| 
								 | 
							
								    lineEnd = position + maxHalfLength - tail.length;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail,
							 | 
						||
| 
								 | 
							
								    pos: position - lineStart + head.length // relative position
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function padStart(string, max) {
							 | 
						||
| 
								 | 
							
								  return common.repeat(' ', max - string.length) + string;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function makeSnippet(mark, options) {
							 | 
						||
| 
								 | 
							
								  options = Object.create(options || null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!mark.buffer) return null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!options.maxLength) options.maxLength = 79;
							 | 
						||
| 
								 | 
							
								  if (typeof options.indent      !== 'number') options.indent      = 1;
							 | 
						||
| 
								 | 
							
								  if (typeof options.linesBefore !== 'number') options.linesBefore = 3;
							 | 
						||
| 
								 | 
							
								  if (typeof options.linesAfter  !== 'number') options.linesAfter  = 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var re = /\r?\n|\r|\0/g;
							 | 
						||
| 
								 | 
							
								  var lineStarts = [ 0 ];
							 | 
						||
| 
								 | 
							
								  var lineEnds = [];
							 | 
						||
| 
								 | 
							
								  var match;
							 | 
						||
| 
								 | 
							
								  var foundLineNo = -1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while ((match = re.exec(mark.buffer))) {
							 | 
						||
| 
								 | 
							
								    lineEnds.push(match.index);
							 | 
						||
| 
								 | 
							
								    lineStarts.push(match.index + match[0].length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (mark.position <= match.index && foundLineNo < 0) {
							 | 
						||
| 
								 | 
							
								      foundLineNo = lineStarts.length - 2;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var result = '', i, line;
							 | 
						||
| 
								 | 
							
								  var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;
							 | 
						||
| 
								 | 
							
								  var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i = 1; i <= options.linesBefore; i++) {
							 | 
						||
| 
								 | 
							
								    if (foundLineNo - i < 0) break;
							 | 
						||
| 
								 | 
							
								    line = getLine(
							 | 
						||
| 
								 | 
							
								      mark.buffer,
							 | 
						||
| 
								 | 
							
								      lineStarts[foundLineNo - i],
							 | 
						||
| 
								 | 
							
								      lineEnds[foundLineNo - i],
							 | 
						||
| 
								 | 
							
								      mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),
							 | 
						||
| 
								 | 
							
								      maxLineLength
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								    result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +
							 | 
						||
| 
								 | 
							
								      ' | ' + line.str + '\n' + result;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);
							 | 
						||
| 
								 | 
							
								  result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +
							 | 
						||
| 
								 | 
							
								    ' | ' + line.str + '\n';
							 | 
						||
| 
								 | 
							
								  result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i = 1; i <= options.linesAfter; i++) {
							 | 
						||
| 
								 | 
							
								    if (foundLineNo + i >= lineEnds.length) break;
							 | 
						||
| 
								 | 
							
								    line = getLine(
							 | 
						||
| 
								 | 
							
								      mark.buffer,
							 | 
						||
| 
								 | 
							
								      lineStarts[foundLineNo + i],
							 | 
						||
| 
								 | 
							
								      lineEnds[foundLineNo + i],
							 | 
						||
| 
								 | 
							
								      mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),
							 | 
						||
| 
								 | 
							
								      maxLineLength
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								    result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +
							 | 
						||
| 
								 | 
							
								      ' | ' + line.str + '\n';
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return result.replace(/\n$/, '');
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = makeSnippet;
							 |