diff options
| -rw-r--r-- | llm-tools-hl.el | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/llm-tools-hl.el b/llm-tools-hl.el index fe45c58..0e6d3c8 100644 --- a/llm-tools-hl.el +++ b/llm-tools-hl.el | |||
| @@ -177,30 +177,39 @@ Each element is a line number and two-character hash, like `1vx'." | |||
| 177 | (push "Delete operation (-) must not have payload lines" errors))) | 177 | (push "Delete operation (-) must not have payload lines" errors))) |
| 178 | errors)) | 178 | errors)) |
| 179 | 179 | ||
| 180 | (defun llm-tools--hl-validate-insert-anchor (anchor) | ||
| 181 | "Return error string if ANCHOR is malformed for insert, else nil." | ||
| 182 | (when (and anchor | ||
| 183 | (not (string= anchor "EOF")) | ||
| 184 | (not (string= anchor "BOF"))) | ||
| 185 | (pcase anchor | ||
| 186 | ((pred (lambda (a) | ||
| 187 | (or (< (length a) 3) | ||
| 188 | (not (string-match-p "^[0-9]" a))))) | ||
| 189 | (format "Invalid anchor %S (expected LINEHASH like '5ff' or EOF/BOF)" anchor)) | ||
| 190 | (_ nil)))) | ||
| 191 | |||
| 192 | (defun llm-tools--hl-validate-range-anchor (anchor) | ||
| 193 | "Return error string if ANCHOR (like \"3gv..6be\") is malformed, else nil." | ||
| 194 | (pcase (split-string anchor "\\.\\.") | ||
| 195 | (`(,a ,b) | ||
| 196 | (when (or (< (length a) 3) (not (string-match-p "^[0-9]" a)) | ||
| 197 | (< (length b) 3) (not (string-match-p "^[0-9]" b))) | ||
| 198 | (format "Invalid anchor %S in range (expected numeric line anchor like '5ff')" anchor))) | ||
| 199 | (_ | ||
| 200 | (format "Invalid range %S (expected A..B)" anchor)))) | ||
| 201 | |||
| 180 | (defun llm-tools--hl-validate-anchors (ops) | 202 | (defun llm-tools--hl-validate-anchors (ops) |
| 181 | "Check that all anchors are well-formed." | 203 | "Check that all anchors are well-formed." |
| 182 | (let (errors) | 204 | (let (errors) |
| 183 | (dolist (op ops) | 205 | (dolist (op ops) |
| 184 | (let ((anchor (hl-verify-op-anchor op))) | 206 | (pcase (hl-verify-op-type op) |
| 185 | (pcase (hl-verify-op-type op) | 207 | ((or 'insert-after 'insert-before) |
| 186 | ((or 'insert-after 'insert-before) | 208 | (let ((err (llm-tools--hl-validate-insert-anchor (hl-verify-op-anchor op)))) |
| 187 | (when (and anchor | 209 | (when err (push err errors)))) |
| 188 | (not (string= anchor "EOF")) | 210 | ((or 'delete 'replace) |
| 189 | (not (string= anchor "BOF"))) | 211 | (let ((err (llm-tools--hl-validate-range-anchor (hl-verify-op-anchor op)))) |
| 190 | (if (or (< (length anchor) 3) | 212 | (when err (push err errors)))))) |
| 191 | (not (string-match-p "^[0-9]" anchor))) | ||
| 192 | (push (format "Invalid anchor %S (expected LINEHASH like '5ff' or EOF/BOF)" anchor) | ||
| 193 | errors)))) | ||
| 194 | ((or 'delete 'replace) | ||
| 195 | (let ((parts (split-string anchor "\\.\\."))) | ||
| 196 | (if (not (= (length parts) 2)) | ||
| 197 | (push (format "Invalid range %S (expected A..B)" anchor) errors) | ||
| 198 | (dolist (part parts) | ||
| 199 | (when (or (< (length part) 3) | ||
| 200 | (not (string-match-p "^[0-9]" part))) | ||
| 201 | (push (format "Invalid anchor %S in range (expected numeric line anchor like '5ff')" part) | ||
| 202 | errors)))))))) | ||
| 203 | errors) | ||
| 204 | (nreverse errors))) | 213 | (nreverse errors))) |
| 205 | 214 | ||
| 206 | (defun llm-tools--hl-verify-section (section) | 215 | (defun llm-tools--hl-verify-section (section) |
