PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/lisp/errors.l

https://bitbucket.org/hokorobi/xyzzy.src
LEX | 244 lines | 224 code | 20 blank | 0 comment | 0 complexity | 323fbdcf35c51d783aeac4669ce7ee3e MD5 | raw file
  1. ;;; -*- Mode: Lisp; Package: EDITOR -*-
  2. ;;;
  3. ;;; This file is part of xyzzy.
  4. ;;;
  5. (provide "errors")
  6. (in-package "editor")
  7. (export '(first-error next-error *parse-errors-at-once* *highlight-error*
  8. *error-window-size* *error-regexp-list*
  9. *find-errors-find-buffers*))
  10. (defvar *parse-errors-at-once* nil)
  11. (defvar *highlight-error* t)
  12. (defvar *error-list* nil)
  13. (defvar *rerror-list* nil)
  14. (defvar *error-buffer* nil)
  15. (defvar *last-error* nil)
  16. (defvar *nerrors-found* nil)
  17. (defvar *error-window-size* 4)
  18. (defvar *find-errors-find-buffers* nil)
  19. (defvar-local *find-error-scanner* nil)
  20. (defun find-errors-get-buffer (name later)
  21. (setq name (string-trim " \t" name))
  22. (let ((file (substitute-string name "[/\\]+" "/"))
  23. buffer)
  24. (cond ((equal (car *last-error*) file)
  25. (cdr *last-error*))
  26. ((and later (null *parse-errors-at-once*))
  27. t)
  28. ((setq buffer (if (string-match "^<.+>$" name)
  29. (find-buffer (subseq name 1 (- (length name) 1)))
  30. (and (file-exist-p file)
  31. (or (get-file-buffer file)
  32. (save-excursion
  33. (find-file file nil t)
  34. (selected-buffer))))))
  35. (setq *last-error* (cons file buffer))
  36. buffer)
  37. ((and *find-errors-find-buffers*
  38. (setq buffer (find-buffer name)))
  39. (setq *last-error* (cons file buffer))
  40. buffer)
  41. (t nil))))
  42. (defvar *error-regexp-list*
  43. (list
  44. (list (compile-regexp "^\\(.+\\)[ \t]*(\\([0-9]+\\))") 1 2)
  45. (list (compile-regexp "^\\(.+\\)[::][ \t]*\\([0-9]+\\)\\([:: \t]\\|$\\)") 1 2)
  46. (list (compile-regexp "^[^ \n]+ \\(.+\\) \\([0-9]+\\):") 1 2)
  47. (list (compile-regexp "^[^ \n]+ [^ \n]+ \\(.+\\) \\([0-9]+\\):") 1 2)))
  48. (defun find-errors (later)
  49. (let ((opoint (point))
  50. buffer file line file-regnum line-regnum)
  51. (goto-bol)
  52. (loop
  53. (dolist (x *error-regexp-list*)
  54. (let ((regexp (pop x)))
  55. (when (looking-at regexp)
  56. (let ((file-regnum (pop x))
  57. (line-regnum (pop x)))
  58. (setq line (parse-integer (match-string line-regnum)))
  59. (setq file (match-string file-regnum))
  60. (setq buffer (find-errors-get-buffer file later))
  61. (while (and (not (bufferp buffer))
  62. (string-match regexp file))
  63. (setq line (parse-integer (subseq file
  64. (match-beginning line-regnum)
  65. (match-end line-regnum))))
  66. (setq file (subseq file (match-beginning file-regnum)
  67. (match-end file-regnum)))
  68. (setq buffer (find-errors-get-buffer file later))))
  69. (when buffer
  70. (unless (bufferp buffer)
  71. (return-from find-errors nil))
  72. (save-excursion
  73. (set-buffer buffer)
  74. (goto-line line)
  75. (let ((marker (make-marker)))
  76. (set-marker marker)
  77. (return-from find-errors marker)))))))
  78. (unless (forward-line 1)
  79. (goto-char opoint)
  80. (return)))))
  81. #|
  82. (defvar *error-regexp*
  83. (compile-regexp
  84. "^[ \t]*\\(.+\\)[::][ \t]*\\([0-9]+\\)\\([:: \t]\\|$\\)\\|^\\(.+\\)[ \t]*(\\([0-9]+\\))"))
  85. (defun error-regexp-regnum ()
  86. (if (match-beginning 1) (values 1 2) (values 4 5)))
  87. (defvar *error-regexp-regnum* #'error-regexp-regnum)
  88. (defun find-errors (later)
  89. (let (buffer file line file-regnum line-regnum)
  90. (goto-bol)
  91. (while (scan-buffer *error-regexp*)
  92. (multiple-value-setq (file-regnum line-regnum)
  93. (funcall *error-regexp-regnum*))
  94. (setq file (match-string file-regnum))
  95. (setq line (parse-integer (match-string line-regnum)))
  96. (setq buffer (find-errors-get-buffer
  97. (substitute-string file "[/\\]+" "/") later))
  98. (while (and (not (bufferp buffer))
  99. (string-match *error-regexp* file))
  100. (multiple-value-setq (file-regnum line-regnum)
  101. (funcall *error-regexp-regnum*))
  102. (setq line (parse-integer (subseq file
  103. (match-beginning line-regnum)
  104. (match-end line-regnum))))
  105. (setq file (subseq file (match-beginning file-regnum) (match-end file-regnum)))
  106. (setq buffer (find-errors-get-buffer file later)))
  107. (when buffer
  108. (unless (bufferp buffer)
  109. (return))
  110. (save-excursion
  111. (set-buffer buffer)
  112. (goto-line line)
  113. (let ((marker (make-marker)))
  114. (set-marker marker)
  115. (return marker))))
  116. (unless (forward-line 1)
  117. (return)))))
  118. |#
  119. (defun build-error-list-1 ()
  120. (long-operation
  121. (message "Parsing error messages...")
  122. (let (errors percent opercent)
  123. (loop
  124. (let ((marker (find-errors errors)))
  125. (or marker
  126. (return))
  127. (setq errors (cons (cons marker (current-line-number)) errors)))
  128. (setq *nerrors-found* (1+ *nerrors-found*))
  129. (setq percent (truncate (* 100 (point)) (point-max)))
  130. (unless (and opercent (eql percent opercent))
  131. (setq opercent percent)
  132. (message "Parsing error messages...~d (~d% of buffer)"
  133. *nerrors-found* percent))
  134. (or (forward-line 1)
  135. (return)))
  136. (setq *error-list* (reverse errors)))
  137. (message "Parsing error messages...done")))
  138. (defun build-error-list ()
  139. (setq *last-error* nil)
  140. (setq *nerrors-found* 0)
  141. (build-error-list-1)
  142. (setq *rerror-list* nil)
  143. (setq *error-buffer* (selected-buffer)))
  144. (defun rebuild-error-list ()
  145. (message "Parsing error messages...")
  146. (let (errors)
  147. (save-excursion
  148. (set-buffer *error-buffer*)
  149. (goto-line (cdr (car *rerror-list*)))
  150. (forward-line 1)
  151. (build-error-list-1))))
  152. (defun goto-error (next)
  153. (when (and next *error-list*)
  154. (setq *rerror-list* (cons (car *error-list*) *rerror-list*))
  155. (setq *error-list* (cdr *error-list*)))
  156. (when (and *rerror-list*
  157. (null *error-list*))
  158. (rebuild-error-list))
  159. (when *error-list*
  160. (let ((error (car *error-list*)))
  161. (if (= (count-windows 'arg) 1)
  162. (progn
  163. (split-window *error-window-size*)
  164. (set-buffer *error-buffer*))
  165. (pop-to-buffer *error-buffer*))
  166. (goto-line (cdr error))
  167. (reverse-region (progn
  168. (goto-eol)
  169. (point))
  170. (progn
  171. (goto-bol)
  172. (point)))
  173. (recenter)
  174. (let ((scanner (and *highlight-error* *find-error-scanner*)))
  175. (other-window)
  176. (set-buffer (marker-buffer (car error)))
  177. (goto-marker (car error))
  178. (and scanner
  179. (funcall scanner (save-excursion (goto-eol) (point)))
  180. (eq *highlight-error* t)
  181. (show-match)))
  182. (recenter)
  183. t)))
  184. (defun first-error (&optional arg wrap)
  185. (interactive "p")
  186. (if (or (and arg (eq *error-buffer* (selected-buffer)))
  187. wrap)
  188. (progn
  189. (dolist (x *rerror-list*)
  190. (setq *error-list* (cons x *error-list*)))
  191. (setq *rerror-list* nil)
  192. (or wrap
  193. (let ((l (current-line-number)))
  194. (while *error-list*
  195. (let ((x (car *error-list*)))
  196. (and (= (cdr x) l)
  197. (return))
  198. (setq *error-list* (cdr *error-list*))
  199. (setq *rerror-list* (cons x *rerror-list*)))))))
  200. (build-error-list))
  201. (if (goto-error nil)
  202. t
  203. (progn
  204. (message "エラーはありません")
  205. nil)))
  206. (defun next-error (&optional arg)
  207. (interactive "p")
  208. (if (or *error-list* arg)
  209. (if (if arg
  210. (progn
  211. (when *rerror-list*
  212. (setq *error-list* (cons (car *rerror-list*) *error-list*))
  213. (setq *rerror-list* (cdr *rerror-list*)))
  214. (goto-error nil))
  215. (goto-error t))
  216. t
  217. (progn
  218. (message "これ以上エラーはありません")
  219. nil))
  220. (if (first-error nil t)
  221. (message "これ以上エラーはないっつってんだろうがこのバカチンが!"))))
  222. (global-set-key #\F10 'first-error)
  223. (global-set-key #\F11 'next-error)
  224. (define-key ctl-x-map #\` 'next-error)