lampson 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/diff.syn ADDED
@@ -0,0 +1,142 @@
1
+ -- lib/diff.syn — diff de líneas para mostrar en la terminal qué cambió edit/write
2
+ -- diff(old, new, ctx, color) → {"added": n, "removed": m, "lines": [texto ya formateado…]}
3
+ -- Algoritmo: se recorta el prefijo y sufijo comunes (una edición es local) y se hace LCS solo sobre el
4
+ -- medio. Si el medio es enorme (> LIMIT² celdas) se muestra como bloque quitado + bloque agregado.
5
+
6
+ let ESC be decode(bytes("1b", "hex"))
7
+ let LIMIT be 600
8
+
9
+ task sgr(color, code, s)
10
+ when not color
11
+ give s
12
+ give ESC + "[" + code + "m" + s + ESC + "[0m"
13
+
14
+ task lpad(s, n)
15
+ let out be s
16
+ while length(out) < n
17
+ set out to " " + out
18
+ give out
19
+
20
+ -- LCS clásico: devuelve la lista de ops {"op": " "|"-"|"+", "a": idx_old, "b": idx_new}
21
+ task lcs_ops(a, b)
22
+ let n be length(a)
23
+ let m be length(b)
24
+ -- tabla (n+1)×(m+1) aplanada, fila por fila
25
+ let table be []
26
+ let size be (n + 1) * (m + 1)
27
+ while length(table) < size
28
+ set table to append(table, 0)
29
+ let i be n - 1
30
+ while i >= 0
31
+ let j be m - 1
32
+ while j >= 0
33
+ when a[i] == b[j]
34
+ set table[i * (m + 1) + j] to table[(i + 1) * (m + 1) + j + 1] + 1
35
+ otherwise
36
+ let down be table[(i + 1) * (m + 1) + j]
37
+ let right be table[i * (m + 1) + j + 1]
38
+ set table[i * (m + 1) + j] to (when down >= right then down otherwise right)
39
+ set j to j - 1
40
+ set i to i - 1
41
+ let ops be []
42
+ set i to 0
43
+ let j be 0
44
+ while i < n and j < m
45
+ when a[i] == b[j]
46
+ set ops to append(ops, {"op": " ", "a": i, "b": j})
47
+ set i to i + 1
48
+ set j to j + 1
49
+ otherwise when table[(i + 1) * (m + 1) + j] >= table[i * (m + 1) + j + 1]
50
+ set ops to append(ops, {"op": "-", "a": i, "b": j})
51
+ set i to i + 1
52
+ otherwise
53
+ set ops to append(ops, {"op": "+", "a": i, "b": j})
54
+ set j to j + 1
55
+ while i < n
56
+ set ops to append(ops, {"op": "-", "a": i, "b": j})
57
+ set i to i + 1
58
+ while j < m
59
+ set ops to append(ops, {"op": "+", "a": i, "b": j})
60
+ set j to j + 1
61
+ give ops
62
+
63
+ export task diff(old, new, ctx, color)
64
+ let a be when old == "" then [] otherwise split(old, "\n")
65
+ let b be when new == "" then [] otherwise split(new, "\n")
66
+ -- prefijo común
67
+ let pre be 0
68
+ while pre < length(a) and pre < length(b) and a[pre] == b[pre]
69
+ set pre to pre + 1
70
+ -- sufijo común (sin pisar el prefijo)
71
+ let suf be 0
72
+ while suf < length(a) - pre and suf < length(b) - pre and a[length(a) - 1 - suf] == b[length(b) - 1 - suf]
73
+ set suf to suf + 1
74
+ let mid_a be slice(a, pre, length(a) - suf)
75
+ let mid_b be slice(b, pre, length(b) - suf)
76
+ let ops be []
77
+ when length(mid_a) * length(mid_b) > LIMIT * LIMIT
78
+ each e in enumerate(mid_a)
79
+ set ops to append(ops, {"op": "-", "a": e["index"], "b": 0})
80
+ each e in enumerate(mid_b)
81
+ set ops to append(ops, {"op": "+", "a": length(mid_a), "b": e["index"]})
82
+ otherwise
83
+ set ops to lcs_ops(mid_a, mid_b)
84
+ let added be 0
85
+ let removed be 0
86
+ each o in ops
87
+ when o["op"] == "+"
88
+ set added to added + 1
89
+ otherwise when o["op"] == "-"
90
+ set removed to removed + 1
91
+ -- render: ctx líneas de contexto antes y después del bloque cambiado (números de línea del archivo NUEVO
92
+ -- para "+"/" ", del viejo para "-"), con "⋯" entre hunks
93
+ let width be length(text(length(b)))
94
+ let lines be []
95
+ -- contexto previo (del prefijo común)
96
+ let start be when pre - ctx > 0 then pre - ctx otherwise 0
97
+ when start > 0
98
+ set lines to append(lines, sgr(color, "2", lpad("", width) + " ⋯"))
99
+ let k be start
100
+ while k < pre
101
+ set lines to append(lines, sgr(color, "2", lpad(text(k + 1), width) + " │ " + a[k]))
102
+ set k to k + 1
103
+ -- medio: contexto interno acotado (ctx a cada lado de un cambio)
104
+ let last_change be -1
105
+ let idx be 0
106
+ each o in ops
107
+ when o["op"] != " "
108
+ set last_change to idx
109
+ set idx to idx + 1
110
+ set idx to 0
111
+ let skipping be false
112
+ each o in ops
113
+ let near be false
114
+ let w be idx - ctx
115
+ while w <= idx + ctx and not near
116
+ when w >= 0 and w < length(ops) and ops[w]["op"] != " "
117
+ set near to true
118
+ set w to w + 1
119
+ when o["op"] == " "
120
+ when near
121
+ set lines to append(lines, sgr(color, "2", lpad(text(pre + o["b"] + 1), width) + " │ " + mid_b[o["b"]]))
122
+ set skipping to false
123
+ otherwise when not skipping
124
+ set lines to append(lines, sgr(color, "2", lpad("", width) + " ⋯"))
125
+ set skipping to true
126
+ otherwise when o["op"] == "-"
127
+ set lines to append(lines, sgr(color, "2", lpad(text(pre + o["a"] + 1), width) + " │ ") + sgr(color, "31", "- " + mid_a[o["a"]]))
128
+ set skipping to false
129
+ otherwise
130
+ set lines to append(lines, sgr(color, "2", lpad(text(pre + o["b"] + 1), width) + " │ ") + sgr(color, "32", "+ " + mid_b[o["b"]]))
131
+ set skipping to false
132
+ set idx to idx + 1
133
+ -- contexto posterior (del sufijo común)
134
+ let after_start be length(b) - suf
135
+ let upto be when after_start + ctx < length(b) then after_start + ctx otherwise length(b)
136
+ set k to after_start
137
+ while k < upto
138
+ set lines to append(lines, sgr(color, "2", lpad(text(k + 1), width) + " │ " + b[k]))
139
+ set k to k + 1
140
+ when upto < length(b)
141
+ set lines to append(lines, sgr(color, "2", lpad("", width) + " ⋯"))
142
+ give {"added": added, "removed": removed, "lines": lines}