Skip to content

Commit 1c281f8

Browse files
jfaz1vindarel
authored andcommitted
Add dashboard documentation
1 parent 53b405e commit 1c281f8

File tree

4 files changed

+134
-0
lines changed

4 files changed

+134
-0
lines changed

content/en/modes/dashboard.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
title: Dashboard
3+
---
4+
5+
Lem ships with a customizable dashboard, `lem-dashboard`, out of the box:
6+
7+
![Default dashboard](/default-dashboard.png)
8+
9+
Besides a more friendly greeting than a `*tmp*` buffer, it ships with useful shortcuts like starting a lisp scratch or seeing recent files/projects at a glance.
10+
11+
The dashboard is launched when you open lem without passing any file arguments. If you wish to open/reopen it, you can do so with `M-x open-dashboard`.
12+
13+
## Basic Customization
14+
15+
### Disable
16+
17+
To disable, simply set `*dashboard-enable*` to `nil` in your `init.lisp`:
18+
19+
```lisp
20+
(setf lem-dashboard:*dashboard-enable* nil)
21+
```
22+
23+
### Customizing default dashboard
24+
25+
If you want to make changes to the dashboard without defining a custom layout, there is a convenience function `set-default-dashboard` that you can use to make minor modifications:
26+
27+
```lisp
28+
(lem-dashboard:set-default-dashboard :project-count 1
29+
:file-count 6
30+
:hide-links t
31+
:splash '("hello" "hello again"))
32+
```
33+
34+
Which would look like:
35+
36+
![Customized default dashboard](/customized-default-dashboard.png)
37+
38+
Here are the currently available keywords:
39+
40+
- `hide-links`: Whether to hide the doc/GitHub links.
41+
- `project-count`: How many projects to list.
42+
- `file-count`: How many recent files to list.
43+
- `splash`: List of splash messages, will be randomly chosen.
44+
- `footer-messages`: List of footer messages, will be randomly chosen.
45+
46+
## Advanced Customization
47+
48+
`lem-dashboard` is designed to be customizable. If you wish to make more changes than `set-default-dashboard` allows, you can make your own dashboard layout.
49+
50+
A dashboard is simply a list of `dashboard-item` instances. Here's a list of available items:
51+
52+
- `dashboard-splash`: Randomly displays one of `SPLASH-TEXTS`.
53+
- `dashboard-url`: Creates link/button with `DISPLAY-TEXT` that opens `URL` externally.
54+
- `dashboard-working-dir`: Prints current working directory.
55+
- `dashboard-footer-message`: Randomly displays one of the passed-in `MESSAGES`.
56+
- `dashboard-command`: Creates a link/button with `DISPLAY-TEXT` that executes `ACTION-COMMAND` when clicked/activated.
57+
- `dashboard-recent-projects`: Displays a list of recent projects, limited to the last `PROJECT-COUNT`.
58+
- `dashboard-recent-files`: Displays a list of recent files, limited to the last `FILE-COUNT`.
59+
60+
All you need to do is call `set-dashboard` and pass it a list of `dashboard-item` instances:
61+
62+
```lisp
63+
(in-package :lem-dashboard)
64+
65+
(set-dashboard (list (make-instance 'dashboard-splash
66+
:item-attribute 'document-metadata-attribute
67+
:splash-texts '("Welcome!" "Second splash message!")
68+
:top-margin 4
69+
:bottom-margin 2)
70+
(make-instance 'dashboard-working-dir)
71+
(make-instance 'dashboard-recent-files
72+
:file-count 5
73+
:bottom-margin 1)
74+
(make-instance 'dashboard-command
75+
:display-text " New Lisp Scratch Buffer (l)"
76+
:action-command 'lem-lisp-mode/internal:lisp-scratch
77+
:item-attribute 'document-header2-attribute
78+
:bottom-margin 2)))
79+
```
80+
81+
The base class, `dashboard-item`, has the following slots:
82+
83+
- `item-attribute`: The attribute used when drawing the item
84+
- `top-margin`: The amount of vertical space (lines) to apply before the item.
85+
- `bottom-margin`: The amount of vertical space (lines) to apply after the item.
86+
- `action`: Function to execute when `RET` is pressed over this item. Most of the existing `dashboard-item` implementations have good default behavior here.
87+
88+
### Creating your own `dashboard-item`
89+
90+
Creating a custom `dashboard-item` is straightforward; just derive the class and implement the `draw-dashboard-item` method.
91+
92+
You are responsible for the actual insertion of text inside of `draw-dashboard-item`. There is a convenience function, `create-centered-string`, which you can use when inserting text.
93+
94+
As an example, let's make a `dashboard-item` that fetches a random fact from an HTTP API and prints it:
95+
96+
```lisp
97+
(defclass dashboard-random-fact (dashboard-item)
98+
((fact :initform nil :accessor fact)
99+
(fetching :initform nil :accessor fetching))
100+
(:documentation "Creates a dashboard item that displays a random fact."))
101+
102+
(defmethod draw-dashboard-item ((item dashboard-random-fact) point)
103+
;; Display fact if exists, or 'loading fact..' while fetching
104+
(insert-string point
105+
(create-centered-string (or (fact item) "Loading fact..."))
106+
:attribute (item-attribute item))
107+
108+
;; If we don't currently have a fact and are not fetching, start fetching fact
109+
(unless (or (fact item) (fetching item))
110+
(setf (fetching item) t)
111+
;; Start a background thread so we don't block
112+
(bt2:make-thread
113+
(lambda ()
114+
(handler-case
115+
(let* ((response (dexador:get "https://uselessfacts.jsph.pl/api/v2/facts/random"))
116+
(json-data (json:decode-json-from-string response))
117+
(fact-text (cdr (assoc :text json-data))))
118+
;; Once we receive the fact, we'll set it and redraw the dashboard
119+
(send-event (lambda ()
120+
(setf (fact item) fact-text)
121+
(redraw-dashboard))))
122+
(error (e)
123+
(send-event (lambda () (message (format nil "Error fetching fact: ~A" e))))))
124+
:name "random-fact-fetcher"))))
125+
```
126+
127+
Multithreading is overkill here, but it lets us fetch the fact without delaying the startup of the dashboard. Adding `dashboard-random-fact` to the last above, we get:
128+
129+
![New dashboard item](/dashboard-new-item.png)
130+
131+
### Current limitations
132+
133+
- Only vertical stacking is currently supported. If you want to stack multiple elements horizontally, you'll have to make a dashboard item that does so.
134+
- No image support.
14 KB
Loading

static/dashboard-new-item.png

11.7 KB
Loading

static/default-dashboard.png

17.1 KB
Loading

0 commit comments

Comments
 (0)