Skip to content

Commit 80aab6b

Browse files
committed
displaying concepts: mark, attributes, text properties
1 parent 42db2cc commit 80aab6b

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

content/en/development/displaying.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,135 @@ Because, in frame-multiplexer, it is needed to store frames and to switch betwee
6767
One virtual frame store multiple frames in it, and modify `lem::*display-frame-map*` when like frame switching.
6868

6969
Source: `/lib/core/frame-multiplexer.lisp`
70+
71+
## Editing display concepts
72+
73+
These displaying mechanisms are used in text buffers.
74+
75+
### Visually selecting text - the mark
76+
77+
Setting the mark allows to start a visual selection of text.
78+
79+
It also allows to add a point to the *mark ring*, which further allows
80+
to circle back between marks.
81+
82+
It can be done with
83+
84+
```lisp
85+
(set-current-mark (current-point))
86+
```
87+
88+
`set-cursor-mark` is similar, and in addition it pushes the point to the mark ring.
89+
90+
For example, this is how the command `mark-set-whole-buffer` is implemented:
91+
92+
```lisp
93+
(define-command (mark-set-whole-buffer (:advice-classes jump-cursor-advice)) () ()
94+
"Select the whole buffer as a region."
95+
(buffer-end (current-point)) ;; move the current point
96+
(set-current-mark (current-point)) ;; set the mark to the current point, start visual selection.
97+
(buffer-start (current-point)) ;; move the point, effectively selecting all text.
98+
(message "Mark set whole buffer"))
99+
```
100+
101+
### Adding and showing meta data on top of content - overlays
102+
103+
Overlays allow to complement the buffer's text with all sort of
104+
metadata. It is visible, it appears "around" the text (in the left
105+
margin, in the emply line space on the right…), but it isn't part of
106+
the buffer's content. It can be temporary.
107+
108+
For example, when your compile a Lisp form, you see a fast visual
109+
effect around it: it was an overlay that was created, and quickly
110+
deleted. When you evaluate a Lisp form, its result is showed on its
111+
right: it is an overlay.
112+
113+
Overlays are defined in `src/overlays.lisp`. An overlay is defined by
114+
a class, with slots: `start, end, temporary, buffer, attribute, plist,
115+
alivep`.
116+
117+
The class `line-endings-overlay` extends a base overlay with slots: `text, offset`.
118+
119+
We also have `cursor-overlay`.
120+
121+
When an overlay is created (with `make-overlay` and the corresponding
122+
constructor functions), it is automatically pushed to the buffer's
123+
list of overlays, and is displayed.
124+
125+
```lisp
126+
;;; src/overlays.lisp
127+
(defun make-overlay (start end attribute
128+
&key (start-point-kind :right-inserting)
129+
(end-point-kind :left-inserting)
130+
temporary)
131+
(make-instance 'overlay
132+
:start (copy-point start start-point-kind)
133+
:end (copy-point end end-point-kind)
134+
:attribute attribute
135+
:buffer (point-buffer start)
136+
:temporary temporary))
137+
```
138+
139+
For example:
140+
141+
```lisp
142+
(make-line-endings-overlay (current-point) (current-point) 'lem-lisp-mode/eval::eval-error-attribute :text "hello")
143+
```
144+
This creates an overlay at the end of the line, showing "hello".
145+
146+
Delete all the current buffer overlays with `(clear-overlays)` (use
147+
`M-:` M-x `lisp-eval-string`).
148+
149+
The `attribute` argument of the constructor functions lead us to… attributes.
150+
151+
152+
### Text properties, attributes
153+
154+
Attributes allow to display rich text: bold, italic, with colors… but
155+
they also allow to store metadata in buffer strings. In that case,
156+
attributes are invisible.
157+
158+
For example, Legit's status buffer displays a line of text `Untracked
159+
Files` with the built-in attribute `:header-marker`, like this:
160+
161+
```lisp
162+
(put-text-property start point :header-marker t))
163+
;; ^^ attribute ^^^ attribute value
164+
```
165+
166+
Thanks to it, we can implement a keyboard shortcut to navigate from
167+
one heading to another.
168+
169+
Attributes are created with `define-attribute name (specs)`:
170+
171+
```lisp
172+
(define-attribute filename-attribute
173+
(t :foreground :base0D))
174+
```
175+
176+
Built-in attributes are defined in `src/attributes.lisp`, such as:
177+
178+
```lisp
179+
;; built-in attributes
180+
(define-attribute cursor
181+
(:light :background "black")
182+
(:dark :background "white"))
183+
184+
(define-attribute region
185+
(:light :foreground nil :background "#eedc82")
186+
(:dark :foreground nil :background "blue"))
187+
188+
(define-attribute syntax-warning-attribute
189+
(t :foreground "red"))
190+
191+
(define-attribute syntax-comment-attribute
192+
(:light :foreground "#cd0000")
193+
(:dark :foreground "chocolate1"))
194+
195+
196+
(define-attribute document-header1-attribute
197+
(:light :foreground "#000000" :bold t)
198+
(:dark :foreground "#FFFFFF" :bold t))
199+
```
200+
201+
and so on.

0 commit comments

Comments
 (0)