forked from idris-hackers/idris-mode
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathidris-warnings.el
136 lines (113 loc) · 5.32 KB
/
idris-warnings.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
;;; idris-warnings.el --- Mark warnings reported by idris in buffers -*- lexical-binding: t -*-
;; Copyright (C) 2013 Hannes Mehnert
;; Author: Hannes Mehnert <[email protected]>
;; License:
;; Inspiration is taken from SLIME/DIME (http://common-lisp.net/project/slime/) (https://github.com/dylan-lang/dylan-mode)
;; Therefore license is GPL
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
(require 'idris-core)
(require 'cl-lib)
(defface idris-warning-face
`((((class color) (background light))
(:underline "orange"))
(((class color) (background dark))
(:underline "coral"))
(t (:underline t)))
"Face for warnings from the compiler."
:group 'idris-faces)
(defvar idris-warnings-buffers '() "All buffers which have warnings")
(defvar-local idris-warnings '() "All warnings in the current buffer")
(defvar idris-raw-warnings '() "All warnings from Idris")
(defun idris-warning-event-hook-function (event)
(destructure-case event
((:warning output _target)
(idris-warning-overlay output)
t)
(t nil)))
(defun idris-warning-reset-all ()
(mapc #'idris-warning-reset-buffer idris-warnings-buffers)
(setq idris-raw-warnings '())
(setq idris-warnings-buffers '()))
(defun idris-warning-reset-buffer (buffer)
(when (buffer-live-p buffer)
(with-current-buffer buffer (idris-warning-reset))))
(defun idris-warning-reset ()
(mapc #'delete-overlay idris-warnings)
(setq idris-warnings '())
(delq (current-buffer) idris-warnings-buffers))
(defun get-region (line)
(goto-char (point-min))
(values
(line-beginning-position line)
(line-end-position line)))
(defun idris-warning-overlay-p (overlay)
(overlay-get overlay 'idris-warning))
(defun idris-warning-overlay-at-point ()
"Return the overlay for a note starting at point, otherwise nil."
(cl-find (point) (cl-remove-if-not 'idris-warning-overlay-p (overlays-at (point)))
:key 'overlay-start))
(defun idris-warning-overlay (warning)
"Add a compiler warning to the buffer as an overlay.
May merge overlays, if there's already one in the same location.
WARNING is of form (filename linenumber column message &optional highlighting-spans)
or the old format, used by Idris up to 0.9.10.1, which does not contain a column
Since March 10th 2014 (commit 7437ebe5052250630ca52117dd50dbf3187807d5) - Idris 0.9.11.2
WARNING is of form (filename (startline startcolumn) (endline endcolumn) message &optional highlighting-spans)
"
(case (safe-length warning)
(3 (destructuring-bind (filename lineno message) warning
(idris-real-warning-overlay filename lineno 0 message)))
(4 (destructuring-bind (filename lineno col message) warning
(idris-real-warning-overlay filename lineno col message)))
(5 (destructuring-bind (filename sl1 sl2 message highlighting) warning
(if (listp sl1)
(progn
(assert (listp sl2))
(assert (eq (safe-length sl1) 2))
(assert (eq (safe-length sl2) 2))
(idris-real-warning-overlay filename (nth 0 sl1) (nth 1 sl1) message highlighting))
(assert (integerp sl1))
(assert (integerp sl2))
(idris-real-warning-overlay filename sl1 sl2 message highlighting))))))
(defun idris-real-warning-overlay (filename lineno col message &optional spans)
"Add the compiler warning to the buffer for real!"
(push (list filename lineno col message spans) idris-raw-warnings)
(let ((buffer (get-file-buffer filename)))
(when (not (null buffer))
(with-current-buffer buffer
(multiple-value-bind (start end) (get-region lineno)
(goto-char start)
; this is a hack to have warnings reported which point to empty lines
(let ((rend (if (equal start end)
(progn (insert " ")
(1+ end))
end)))
(let ((overlay (idris-warning-overlay-at-point)))
(if overlay
(idris-warning-merge-overlays overlay message)
(idris-warning-create-overlay (+ start col) rend message)))))))))
(defun idris-warning-merge-overlays (overlay message)
(overlay-put overlay 'help-echo
(concat (overlay-get overlay 'help-echo) "\n" message)))
(defun idris-warning-create-overlay (start end message)
(let ((overlay (make-overlay start end)))
(overlay-put overlay 'idris-warning message)
(overlay-put overlay 'help-echo message)
(overlay-put overlay 'face 'idris-warning-face)
(overlay-put overlay 'mouse-face 'highlight)
(push overlay idris-warnings)
(unless (memq (current-buffer) idris-warnings-buffers)
(push (current-buffer) idris-warnings-buffers))
overlay))
(provide 'idris-warnings)