summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llm-tools-hl-test.el10
-rw-r--r--llm-tools-hl.el35
2 files changed, 22 insertions, 23 deletions
diff --git a/llm-tools-hl-test.el b/llm-tools-hl-test.el
index e796ac8..5b50f14 100644
--- a/llm-tools-hl-test.el
+++ b/llm-tools-hl-test.el
@@ -234,15 +234,15 @@ export function greet(name) {
234 "Test formatting lines in hashline format." 234 "Test formatting lines in hashline format."
235 (let ((lines '("hello" "world"))) 235 (let ((lines '("hello" "world")))
236 ;; Without content 236 ;; Without content
237 (let ((no-content (llm-tools--hl-format-lines lines))) 237 (let ((no-content (llm-tools--hl-format-lines lines nil t)))
238 (should (= (length (string-lines no-content)) 2)) 238 (should (= (length (string-lines no-content)) 2))
239 (should (string-match-p "\\`1.." no-content))) 239 (should (string-match-p "\\`1.." no-content)))
240 ;; With content 240 ;; With content
241 (let ((with-content (llm-tools--hl-format-lines lines nil t))) 241 (let ((with-content (llm-tools--hl-format-lines lines)))
242 (should (string-match-p "\\`1..|hello" with-content)) 242 (should (string-match-p "\\`1..|hello" with-content))
243 (should (string-match-p "2..|world\\'" with-content))) 243 (should (string-match-p "2..|world\\'" with-content)))
244 ;; With custom start number 244 ;; With custom start number
245 (let ((custom-start (llm-tools--hl-format-lines lines 5))) 245 (let ((custom-start (llm-tools--hl-format-lines lines 5 t)))
246 (should (string-match-p "\\`5.." custom-start)) 246 (should (string-match-p "\\`5.." custom-start))
247 (should (string-match-p "6..\\'" custom-start))))) 247 (should (string-match-p "6..\\'" custom-start)))))
248 248
@@ -252,7 +252,7 @@ export function greet(name) {
252 (let* ((content "line1\nline2\nline3\nline4\n") 252 (let* ((content "line1\nline2\nline3\nline4\n")
253 (file (make-temp-file nil nil nil content))) 253 (file (make-temp-file nil nil nil content)))
254 (unwind-protect 254 (unwind-protect
255 (let ((result (llm-tools--hl-file-read-range file 2 3))) 255 (let ((result (llm-tools--hl-file-read file 2 3)))
256 (should (= (length (string-lines result)) 2)) 256 (should (= (length (string-lines result)) 2))
257 (should (string-match-p "\\`2.." result)) 257 (should (string-match-p "\\`2.." result))
258 (should (string-match-p "line2" result)) 258 (should (string-match-p "line2" result))
@@ -265,7 +265,7 @@ export function greet(name) {
265 (let* ((content "foo\nbar\n") 265 (let* ((content "foo\nbar\n")
266 (file (make-temp-file nil nil nil content))) 266 (file (make-temp-file nil nil nil content)))
267 (unwind-protect 267 (unwind-protect
268 (let ((hashes (llm-tools--hl-file-read-hashes file))) 268 (let ((hashes (llm-tools--hl-file-read file nil nil t t)))
269 (should (= (length hashes) 2)) 269 (should (= (length hashes) 2))
270 (should (string-match-p "\\`1.." (elt hashes 0))) 270 (should (string-match-p "\\`1.." (elt hashes 0)))
271 (should (string-match-p "\\`2.." (elt hashes 1))) 271 (should (string-match-p "\\`2.." (elt hashes 1)))
diff --git a/llm-tools-hl.el b/llm-tools-hl.el
index 9b2a9c2..49e67fb 100644
--- a/llm-tools-hl.el
+++ b/llm-tools-hl.el
@@ -68,31 +68,30 @@ With optional BEG and END (inclusive, 1-based), return the lines between that ra
68 (cl-subseq lines (1- beg) end) 68 (cl-subseq lines (1- beg) end)
69 lines)))) 69 lines))))
70 70
71(defun llm-tools--hl-format-lines (lines &optional start include-content?) 71(defun llm-tools--hl-format-lines (lines &optional start only-anchors?)
72 "Format LINES in hashline format. 72 "Format LINES in hashline format.
73START is 1-based (default 1). 73START is 1-based (default 1).
74If INCLUDE-CONTENT is non-nil, append `|LINE' after each hash." 74If ONLY-ANCHORS? is non-nil, do not append `|CONTENT' after each anchor."
75 (string-join 75 (string-join
76 (cl-mapcar (lambda (line i) 76 (cl-mapcar (lambda (line i)
77 (if include-content? 77 (if only-anchors?
78 (format "%d%2s|%s" i (llm-tools--hl-hash line) line) 78 (format "%d%2s" i (llm-tools--hl-hash line))
79 (format "%d%2s" i (llm-tools--hl-hash line)))) 79 (format "%d%2s|%s" i (llm-tools--hl-hash line) line)))
80 lines 80 lines
81 (number-sequence (or start 1) (+ (or start 1) (1- (length lines))))) 81 (number-sequence (or start 1) (+ (or start 1) (1- (length lines)))))
82 "\n")) 82 "\n"))
83 83
84(defun llm-tools--hl-file-read (file) 84(defun llm-tools--hl-file-read (file &optional beg end only-anchors? as-list?)
85 "Return FILE contents in hashline format." 85 "Return FILE contents in hashline format.
86 (llm-tools--hl-format-lines (llm-tools--hl-file-lines file) nil t)) 86With optional BEG and END (inclusive, 1-based), return lines BEG to END.
87 87If ONLY-ANCHORS? is non-nil, do not append `|CONTENT' after each anchor.
88(defun llm-tools--hl-file-read-range (file beg end) 88If AS-LIST? is non-nil, return a list of hashline strings instead of a
89 "Return FILE contents in hashline format from lines BEG to END." 89single string."
90 (llm-tools--hl-format-lines (llm-tools--hl-file-lines file beg end) beg t)) 90 (let* ((lines (llm-tools--hl-file-lines file beg end))
91 91 (formatted (llm-tools--hl-format-lines lines (or beg 1) only-anchors?)))
92(defun llm-tools--hl-file-read-hashes (file) 92 (if as-list?
93 "Return FILE contents as a list of hashline strings without line content. 93 (string-lines formatted)
94Each element is a line number and two-character hash, like `1vx'." 94 formatted)))
95 (string-lines (llm-tools--hl-format-lines (llm-tools--hl-file-lines file))))
96 95
97(defun llm-tools--hl-file-line-hash (file n) 96(defun llm-tools--hl-file-line-hash (file n)
98 "Return the hash of the Nth line in FILE." 97 "Return the hash of the Nth line in FILE."
@@ -310,7 +309,7 @@ line in the on-disk file."
310 (mapcar (lambda (section) 309 (mapcar (lambda (section)
311 (let* ((file (car section)) 310 (let* ((file (car section))
312 (anchors (delete "BOF" (delete "EOF" (cdr section)))) 311 (anchors (delete "BOF" (delete "EOF" (cdr section))))
313 (hl (llm-tools--hl-file-read-hashes file))) 312 (hl (llm-tools--hl-file-read file nil nil t t)))
314 ;; cl-subsetp uses eql by default which compares by identity and not content 313 ;; cl-subsetp uses eql by default which compares by identity and not content
315 (cons file (cl-subsetp anchors hl :test #'equal)))) 314 (cons file (cl-subsetp anchors hl :test #'equal))))
316 patch-anchors))) 315 patch-anchors)))