[WIP] broken, hacky attempt to get better diffs.

31332fc4de834fb03bb56cd214276d0209ed7bbd

Tucker McKnight <tmcknight@instructure.com> | Sun Mar 15 2026

[WIP] broken, hacky attempt to get better diffs.

Need to rethink this, just commiting it to remember what I changed.

Need to create newlines in one side of the diff if the other side is
exclusively adding lines. So maybe change the Diff to check lines
instead of words, and then do words (or characters?) per-line once
the line diff has been created.
js_templates/commit.ts:65
Before
64
65
66

67
68
            m('div', {class: "row"}, [
              m('div', {class: "col-auto border-end"},
                m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
⁣
                  return (lineNumber + hunk.lineNumber - 1).toString()
                }).join('\n'))
              ),
After
64
65
66
67
68
69
            m('div', {class: "row"}, [
              m('div', {class: "col-auto border-end"},
                m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
                  if (lineNumber === null) { return '' }
                  return (lineNumber + hunk.lineNumber - 1).toString()
                }).join('\n'))
              ),
js_templates/commit.ts:77
Before
76
77
78
79

80
81
            m('span', {class: 'font-monospace text-secondary'}, 'After'),
            m('div', {class: "row"},
              m('div', {class: "col-auto border-end"},
                m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
⁣
                  return (lineNumber + hunk.lineNumber - 1).toString()
                }).join('\n'))
              ),
After
76
77
78
79
80
81
82
            m('span', {class: 'font-monospace text-secondary'}, 'After'),
            m('div', {class: "row"},
              m('div', {class: "col-auto border-end"},
                m('pre', {class: "mb-0"}, lineNumbers(hunk.afterText).map((lineNumber) => {
                  if (lineNumber === null) { return '' }
                  return (lineNumber + hunk.lineNumber - 1).toString()
                }).join('\n'))
              ),
main.ts:136
Before
135
136
137
138

139
140
141

142
143
144
  })

  eleventyConfig.addFilter("lineNumbers", (code: string) => {
    code.split('')
⁣
    const numLines = code.split('\n').length
    const lineNumbers = []
    for (let i = 1; i <= numLines; i++) {
⁣
      lineNumbers.push(i)
    }

    return lineNumbers
After
135
136
137
138
139
140
141
142
143
144
145
146
  })

  eleventyConfig.addFilter("lineNumbers", (code: string) => {
    const lines = code.split('\n')
    console.log(lines)
    const numLines = lines.length
    const lineNumbers = []
    for (let i = 0; i < numLines - 1; i++) {
      const lineNum = lines[i].includes('\u{2063}') ? null : i
      lineNumbers.push(lineNum)
    }

    return lineNumbers
src/helpers.ts:35
Before
34
35
36





















37






38

39
40
41
42
43


44
45
46
47
48
49



50
51
52



53
54
        skipFourStartingAt = -1
      }
      const lastHunk = lines.slice(previousHunk, hunkEndIndex)
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
      let lastHunkBefore = lastHunk.filter(line => line.startsWith("-")).map(str => str.replace("-", "")).join("\n")
⁣
⁣
⁣
⁣
⁣
⁣
      let lastHunkAfter = lastHunk.filter(line => line.startsWith("+")).map(str => str.replace("+", "")).join("\n")
⁣
      const changeObject = Diff.diffWordsWithSpace(lastHunkBefore, lastHunkAfter)
      let beforeText = ""
      let afterText = ""

      changeObject.forEach((obj) => {
⁣
⁣
        if (!obj.added && !obj.removed) {
          beforeText = beforeText + escape(obj.value)
          afterText = afterText + escape(obj.value)
        }
        if (obj.added) {
          afterText = afterText + "<mark>" + escape(obj.value) + "</mark>"
⁣
⁣
⁣
        }
        if (obj.removed) {
          beforeText = beforeText + "<mark>" + escape(obj.value) + "</mark>"
⁣
⁣
⁣
        }
      })
After
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
        skipFourStartingAt = -1
      }
      const lastHunk = lines.slice(previousHunk, hunkEndIndex)

      // TODO: this change I've made doesn't quite work. Need to make it
      // skip lines in the other diff when adding lines to just one diff.

      lastHunk.forEach((line) => {
        if (line.startsWith(' ')) {
          line = line.replace(' ', '')
        }
        else if (line.startsWith('-')) {
          line = line.replace('-', '')
        }
        else if (line.startsWith('+')) {
          line = line.replace('+', '')
        }
      })

      let lastHunkBefore = lastHunk.filter((line) => {
        return line.startsWith("-") || line.startsWith(" ")
      }).map((str) => {
        if (str.startsWith('-')) { return str.replace("-", "") }
        if (str.startsWith(' ')) { return str.replace(" ", "") }
      }).join("\n")

      let lastHunkAfter = lastHunk.filter((line) => {
        return line.startsWith("+") || line.startsWith(" ")
      }).map((str) => {
        if (str.startsWith('+')) { return str.replace("+", "") }
        if (str.startsWith(' ')) { return str.replace(" ", "") }
      }).join("\n")

      const changeObject = Diff.diffLines(lastHunkBefore, lastHunkAfter)
      let beforeText = ""
      let afterText = ""

      changeObject.forEach((obj) => {
        const numNewLines = obj.value.split('').filter(char => char === '\n').length

        if (!obj.added && !obj.removed) {
          beforeText = beforeText + escape(obj.value)
          afterText = afterText + escape(obj.value)
        }
        if (obj.added) {
          afterText = afterText + "<mark>" + escape(obj.value) + "</mark>"
          if (numNewLines > 0) {
            beforeText = beforeText + (new Array(numNewLines).fill('\u{2063}', 0).join('\n'))
          }
        }
        if (obj.removed) {
          beforeText = beforeText + "<mark>" + escape(obj.value) + "</mark>"
          if (numNewLines > 0) {
            afterText = afterText + (new Array(numNewLines).fill('\u{2063}', 0).join('\n'))
          }
        }
      })