All files / diff/src/format tabs.ts

100% Statements 32/32
100% Branches 18/18
100% Functions 4/4
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38              15x 44x 44x 44x 44x 212x 212x 50x 50x 50x 50x   162x 8x 2x 2x 2x   154x 154x 15x 15x 139x   44x       15x 68632x  
/**
 * @param text The line, without its terminator.
 * @param size The tab stop; GNU's `--tabsize`, 8 by default.
 * @param flag Re-emitted after a carriage return that is not the last
 *     character. Omit it for a style that has no separate flag field.
 * @returns `text` itself when nothing in it needs expanding.
 */
export const expandLine = (text: string, size: number, flag?: string): string => {
  const length = text.length;
  let out = '';
  let column = 0;
  for (let i = 0; i < length; i++) {
    const code = text.charCodeAt(i);
    if (code === 0x09) {
      const width = size - (column % size);
      column += width;
      out += ' '.repeat(width);
      continue;
    }
    if (code === 0x08) {
      if (column === 0) continue;
      column--;
      out += text[i];
      continue;
    }
    out += text[i];
    if (code === 0x0d) {
      column = 0;
      if (flag !== undefined && i + 1 < length) out += flag;
    } else if (code >= 0x20 && code <= 0x7e) column++;
  }
  return out;
};
 
/** The expansion a writer applies, or the identity when `-t` was not asked for. */
export const expander = (tabs: number | undefined, flag?: string): ((text: string) => string) =>
  tabs ? (text: string): string => expandLine(text, tabs, flag) : (text: string): string => text;