Skip to content

Commit 25f4be5

Browse files
authored
Emacs/VSCode: Interactive mode (Deducteam#564)
- Electric mode for Emacs - Buttons for Proof Navigation in Emacs - Navigate by commands/tactics in Emacs and VScode - Evaluated region shrinks on edit in Emacs and VScode - Evaluated region changes colour after error in Emacs and VScode - LSP server sends logs only from last command/tactic - Few minor corrections in LSP server - Improve VSCode indentation - Fixes Deducteam#519 - Fixes Deducteam#515 - Fixes Deducteam#514 - Fixes Deducteam#513
1 parent 06ea327 commit 25f4be5

File tree

13 files changed

+867
-427
lines changed

13 files changed

+867
-427
lines changed

.dir-locals.el

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
((nil . ((sort-fold-case . t) ; Ignore case when sorting
2-
)))
2+
))
3+
(emacs-lisp-mode . ((indent-tabs-mode . nil))))

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ libraries/zenon_modulo
2020
*.png
2121
.DS_Store
2222
*.map
23+
TODO.*

docs/ui/emacs.rst

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,31 @@ Emacs
77
Lambdapi source code can be edited with the `emacs`_ editor with the major
88
mode ``lambdapi-mode``. It requires Emacs 26.1 or higher and provides:
99

10-
* Syntax highlighting for Lambdapi (``*.lp`` files) and Dedukti2 (``*.dk``
11-
files)
10+
* Syntax highlighting for Lambdapi (``*.lp`` files) and Dedukti (``*.dk`` files)
1211
* Auto indentation for Lambdapi
1312
* Easier unicode input
1413
* Completion for Lambdapi
1514
* Typing of symbol at point (in minibuffer)
1615
* Type checking declarations
1716

17+
List of short-cuts
18+
------------------
19+
20+
* ``C-c C-c``: jump to cursor position
21+
* ``C-c C-n`` or button "Next": next tactic or command
22+
* ``C-c C-p`` or button "Prev": previous tactic or command
23+
* ``C-c C-f``: next proof
24+
* ``C-c C-b``: previous proof
25+
* ``C-c C-e``: toggle electric mode
26+
* ``M-;`` : (un)comment region
27+
* ``C-x RET C-\``: enter unicode characters in minibuffer using LaTeX
28+
* ``M-x customize-group lambdapi``: customize window layout
29+
* ``C-c C-r``: refresh window layout
30+
* Click on a symbol to discover its type in the bottom line
31+
32+
As always with emacs, if you were to be dissatisfied with these
33+
keybindings, you can change them easily!
34+
1835
Installation
1936
------------
2037

@@ -99,8 +116,9 @@ Usage
99116
Commenting regions
100117
^^^^^^^^^^^^^^^^^^
101118

102-
Lambdapi handles only single-line comments with ``//``. To comment a
103-
region in Emacs, select it and use ``M-;``.
119+
Lambdapi handles single-line and multi-line comments with ``//`` and
120+
``/* ... */`` respectively. To comment a region in Emacs, select it and use
121+
``M-;``.
104122

105123
Entering unicode
106124
^^^^^^^^^^^^^^^^
@@ -156,45 +174,38 @@ LSP server
156174
Navigating goals
157175
''''''''''''''''
158176

159-
On lambdapi-mode startup, a window showing the goals at the current line
160-
is open.
161-
162-
You can toggle the interactive mode with ``C-c C-i``. If you were to do
163-
so, you still can navigate the proofs with ``C-c C-p`` and ``C-c C-n``,
164-
jump between proofs with ``C-c C-b`` and ``C-c C-f``, and show the goals
165-
at the current line with ``C-c C-c``. As always with emacs, if you were
166-
to be dissatisfied with these keybindings, you can change them easily!
177+
On lambdapi-mode startup, the window is split into three buffers:
167178

168-
Clicking on the ``i``-th goal of the ``*Goals*`` buffer puts the focus on it
169-
by inserting a ``focus i`` tactic in the proof script.
179+
* the top buffer contains the Lambdapi file,
180+
* the middle ``*Goals*`` buffer is where goals are displayed,
181+
* the bottom ``*lp-logs*`` buffer is where Lambdapi messages are displayed.
170182

171-
CPU usage and deactivation
172-
''''''''''''''''''''''''''
173-
174-
If for any reason the LSP server consumes too much power (e.g. if a
175-
non-terminating rewrite system is edited), it can be disabled with
176-
``M-x eglot-shutdown``.
183+
It is possible to print the goals to solve at some point in the file by
184+
using the following sort-cuts or the navigation buttons "Prev" and "Next":
177185

178-
Pseudo interactive proof mode
179-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
186+
* ``C-c C-c``: jump to cursor position
187+
* ``C-c C-n`` or button "Next": next tactic or command
188+
* ``C-c C-p`` or button "Prev": previous tactic or command
189+
* ``C-c C-f``: next proof
190+
* ``C-c C-b``: previous proof
180191

181-
One can use `quickrun`_ to call lambdapi while editing a buffer. It can be
182-
configured for lambdapi with
192+
The part of the file up to the current goal is displayed with a green
193+
background. In case of error, the background gets red. If an edition
194+
occurs in the green zone, the green zone is automatically shrinked and
195+
the goals buffer updated.
183196

184-
.. code:: emacs-lisp
197+
It is possible to make the green zone expand automatically each time a
198+
new command is typed by toggling the electric mode with ``C-c C-e``.
185199

186-
(quickrun-add-command "lambdapi"
187-
'((:command . "lambdapi check")
188-
(:exec . ("%c %s")))
189-
:mode 'lambdapi-mode)
190-
(add-hook 'lambdapi-mode-hook
191-
(lambda () (define-key lambdapi-mode-map (kbd "C-c r") #'quickrun)))
200+
Clicking on the ``i``-th goal of the ``*Goals*`` buffer puts the focus
201+
on it by inserting a ``focus i`` tactic in the proof script.
192202

193-
to run lambdapi on the edited buffer with ``C-c r``. It can be used to
194-
display goals while doing a proof. To display the result of ``compute``,
195-
``type``, and simlar commmand as well, write ``"%c --verbose 1 %s"``
196-
instead of ``"%c %s"``.
203+
Electric Terminator mode
204+
''''''''''''''''''''''''
197205

206+
You can toggle electric terminators either from the toolbar or
207+
using ``C-c C-e``. This will evaluate the region till the
208+
cursor whenever you type the ``;`` terminator or ``begin``.
198209

199210
Customize window layout
200211
'''''''''''''''''''''''
@@ -203,7 +214,12 @@ The window layout can be customized in the LambdaPi customization group
203214
(Do ``M-x customize-group lambdapi``).
204215
The layout can be refreshed with ``C-c C-r``.
205216

217+
CPU usage and deactivation
218+
''''''''''''''''''''''''''
206219

220+
If for any reason the LSP server consumes too much power (e.g. if a
221+
non-terminating rewrite system is edited), it can be disabled with
222+
``M-x eglot-shutdown``.
207223

208224
Other relevant packages
209225
-----------------------

editors/emacs/lambdapi-layout.el

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
(defconst lambdapi--temp-buffer-name "lp-asdf2io3jnc" ; any random name will work
2+
"Buffer name for used by `lambdapi-refresh-window-layout'. Must
3+
not match any buffer used by user")
4+
5+
(defun lambdapi--apply-window-layout (tree)
6+
"Applies the window configuration given by the argument tree,
7+
it is either a list (split-side ratio child1-tree child2-tree)
8+
or a leaf which is a buffer or a string with buffer's name.
9+
10+
It is meant to be called by `lambdapi-refresh-window-layout'
11+
which also replaces buffers with name `lambdapi--temp-buffer-name'
12+
with the current buffer.
13+
14+
Example:
15+
16+
(lambdapi--apply-window-layout
17+
'(h 0.6 \"proofs\" (v 0.3 \"goals\" \"logs\")))
18+
19+
will produce
20+
21+
+------------+--------+
22+
| | goals |
23+
| proofs +--------+
24+
| | logs |
25+
| | |
26+
+------------+--------+
27+
"
28+
(if (not (listp tree))
29+
(switch-to-buffer (eval tree) t t)
30+
(let* ((way (car tree))
31+
(ratio (eval (cadr tree)))
32+
(child1 (caddr tree))
33+
(child2 (cadddr tree))
34+
curwin sibling)
35+
(if (eq way 'h)
36+
(progn
37+
(split-window-horizontally
38+
(truncate (* ratio (window-width))))
39+
(setq curwin (selected-window))
40+
(setq sibling (next-window)))
41+
(progn
42+
(split-window-vertically
43+
(truncate (* ratio (window-height))))
44+
(setq curwin (selected-window))
45+
(setq sibling (next-window))))
46+
(with-selected-window curwin
47+
(lambdapi--apply-window-layout child1))
48+
(with-selected-window sibling
49+
(lambdapi--apply-window-layout child2)))))
50+
51+
(defun lambdapi-refresh-window-layout ()
52+
"Resets the window layout to default."
53+
(interactive)
54+
(let ((curbuf (current-buffer)))
55+
(delete-other-windows)
56+
(lambdapi--apply-window-layout lambdapi-window-layout)
57+
(dolist (win (get-buffer-window-list lambdapi--temp-buffer-name))
58+
(with-selected-window win
59+
(switch-to-buffer curbuf t t)))
60+
(kill-buffer lambdapi--temp-buffer-name)
61+
(select-window (get-buffer-window curbuf))))
62+
63+
(defcustom lambdapi-window-X-ratio 0.5
64+
"Ratio of height taken in horizontal split during window layout.
65+
(Not applicable to Layout 0)"
66+
:type '(float)
67+
:group 'lambdapi)
68+
69+
(defcustom lambdapi-window-Y-ratio 0.8
70+
"Ratio of width taken in vertical split during window layout
71+
(Not applicable to Layout 0)"
72+
:type '(float)
73+
:group 'lambdapi)
74+
75+
(defcustom lambdapi-window-layout '(v 0.75
76+
lambdapi--temp-buffer-name
77+
(v 0.75 "*Goals*" "*lp-logs*"))
78+
"Window layout of LambdaPi."
79+
:group 'lambdapi
80+
;; :set might change window layout at an unexpected time
81+
:set (lambda (option newval)
82+
(setq lambdapi-window-layout newval)
83+
(lambdapi-refresh-window-layout))
84+
:type '(radio (sexp :tag "Layout 0"
85+
:format "%t\n"
86+
:value
87+
(v 0.75
88+
lambdapi--temp-buffer-name
89+
(v 0.8 "*Goals*" "*lp-logs*")))
90+
(sexp :tag "Layout 1"
91+
:format "%t\n"
92+
:value
93+
(v lambdapi-window-Y-ratio
94+
lambdapi--temp-buffer-name
95+
(h lambdapi-window-X-ratio
96+
"*Goals*" "*lp-logs*")))
97+
(sexp :tag "Layout 2"
98+
:format "%t\n"
99+
:value
100+
(v lambdapi-window-Y-ratio
101+
(h lambdapi-window-X-ratio
102+
lambdapi--temp-buffer-name
103+
"*lp-logs*")
104+
"*Goals*"))
105+
(sexp :tag "Layout 3"
106+
:format "%t\n"
107+
:value
108+
(h lambdapi-window-X-ratio
109+
lambdapi--temp-buffer-name
110+
(v lambdapi-window-Y-ratio
111+
"*lp-logs*"
112+
"*Goals*")))
113+
(sexp :tag "Layout 4"
114+
:format "%t\n"
115+
:value
116+
(h lambdapi-window-X-ratio
117+
(v lambdapi-window-Y-ratio
118+
lambdapi--temp-buffer-name
119+
"*Goals*")
120+
"*lp-logs*"))
121+
(sexp :tag "Goal bottom"
122+
:format "%t\n"
123+
:value
124+
(v lambdapi-window-Y-ratio
125+
lambdapi--temp-buffer-name
126+
"*Goals*"))
127+
(sexp :tag "Goal right"
128+
:format "%t\n"
129+
:value
130+
(h lambdapi-window-X-ratio
131+
lambdapi--temp-buffer-name
132+
"*Goals*"))))
133+
134+
135+
(provide 'lambdapi-layout)

0 commit comments

Comments
 (0)