-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsweep.texi
3614 lines (3019 loc) · 143 KB
/
sweep.texi
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\input texinfo @c -*- texinfo -*-
@c %**start of header
@setfilename sweep.info
@settitle Sweep: SWI-Prolog Embedded in Emacs
@documentencoding UTF-8
@documentlanguage en
@set MAINTAINERSITE @uref{https://eshelyaron.com,maintainer webpage}
@set MAINTAINER Eshel Yaron
@set MAINTAINEREMAIL @email{[email protected]}
@set MAINTAINERCONTACT @uref{mailto:[email protected],contact the maintainer}
@c %**end of header
@copying
This manual is for Sweep (version 0.27.6), an Emacs package providing
an embedded SWI-Prolog runtime inside of Emacs along with an advanced
SWI-Prolog development environment.
Copyright @copyright{} 2022-2024 Eshel Yaron.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
@end quotation
@end copying
@dircategory Emacs
@direntry
* Sweep: (sweep). SWI-Prolog Embedded in Emacs.
@end direntry
@finalout
@titlepage
@title Sweep: SWI-Prolog Embedded in Emacs
@author Eshel Yaron (@email{me@@eshelyaron.com})
@end titlepage
@contents
@ifnottex
@node Top
@top Sweep: SWI-Prolog Embedded in Emacs
This manual is for Sweep (version 0.27.6), an Emacs package providing
an embedded SWI-Prolog runtime inside of Emacs along with an advanced
SWI-Prolog development environment.
@end ifnottex
@menu
* Overview:: High level look at Sweep
* Installation:: Instructions for installing Sweep
* Getting Started:: First steps with Sweep
* Discovering Sweep:: Tips for finding out about Sweep features
* Initialization:: Functions for starting and stopping the embedded Prolog runtime
* Querying Prolog:: Functions for invoking Prolog predicates and consuming their results
* Editing Prolog Code:: Major mode for reading and writing Prolog
* Prolog Help:: Commands for displaying detailed Prolog documentation
* The Prolog Top-level:: Executing Prolog queries in a REPL-like interface
* Async Queries:: Running goals in seperate threads, redirecting their output to Emacs buffers
* Finding Prolog Code:: Commands for locating and opening Prolog files
* Quick Access Keymap:: Keymap for useful commands that can be invoked from any buffer
* Prolog Messages:: Messages emitted in the embedded Prolog runtime and how to display them
* Prolog Flags:: Commands for modifying the configuration of the embedded Prolog runtime by setting Prolog flags
* Prolog Packages:: Commands for installing SWI-Prolog add-ons
* Contributing:: Information for users and hackers looking to get involved in the development of this project
* Things To Do:: Breakdown of topics that deserve more attention
* Indices::
@detailmenu
--- The Detailed Node Listing ---
Overview
* Main Features:: Most important features that Sweep provides
* Architecture:: Overall structure of this project
* Alternatives:: Comparing Sweep with other Prolog Emacs packages
Querying Prolog
* Elisp to Prolog:: How sweep translates Emacs Lisp to Prolog
* Prolog to Elisp:: How sweep translates Prolog to Emacs Lisp
* Example Query:: Counting solutions for a Prolog predicate in Elisp
* Call Back to Elisp:: Special predicates for calling back to Emacs from Prolog
Editing Prolog Code
* Indentation:: How sweep indents Prolog code
* Highlighting:: Rich fontification for Prolog code
* Hover for Help:: Display description of Prolog tokens by hovering with the mouse
* Code Layout:: Commands for aligning Prolog code without having to count spaces
* Term-based Editing:: Commands that recognize and operate on Prolog terms
* Holes:: Commands for finding and filling holes for interactive term insertion
* Cross References:: Commands for finding cross-references for Prolog predicates
* Predicate Boundaries:: Commands operating on a Prolog predicate definition as a single unit
* File Specifications:: Commands for jumping to files that appear in Prolog code
* Loading Buffers:: Commands for loading Prolog predicates from the current buffer
* Setting Breakpoints:: Commands for setting breakpoints in Prolog buffers
* Creating New Modules:: Commands for populating new Prolog modules with predefined contents
* Documenting Code:: Commands for adding documentation to Prolog predicate definitions
* Usage Comments:: Commands for inserting comments that show example usage of your code
* Showing Prolog Docs:: Commands for showing documentation for Prolog predicates
* Showing Errors:: Commands for finding errors in Prolog code
* Exporting Predicates:: Commands for adding Prolog predicates to their module's export list
* Code Completion:: Auto-completion commands for Prolog code
* Insert Term DWIM:: Commands for smart insertion of Prolog terms based on the surrounding context
* Writing Tests:: Commands that facilitate writing Prolog unit tests
* Code Dependencies:: Commands for managing dependencies of Prolog source files on each other
* Term Search:: Search for Prolog terms matching a given structure
* Term Replace:: Consistently replace a set of terms in Prolog buffers
* Context Menu:: Right-click on Prolog code to open contextual menus
* Renaming Variables:: Replacing occurrences of one Prolog variable with another
* Numbered Variables:: Commands for managing numbers in names of related variables
* Macro Expansion:: Commands for expanding SWI-Prolog macros
* Extract Goal:: Commands for extracting part of a Prolog clause body to a separate predicate
Indentation
* Indentation Rules:: The intented indentation scenaria
Highlighting
* PceEmacs Theme:: Custom theme that mimics PceEmacs, the SWI-Prolog built-in editor
* Highlight Variables:: Commands for emphasizing all occurrences of a Prolog variable
* Quasi-Quotation:: Delegating fontification of quasi-quoted contents to other Emacs major modes
Code Layout
* Aligning Spaces:: Commands for adjusting whitespace according to Prolog conventions
* Electric Layout mode:: Minor mode for automatically adjusting whitespace
Holes
* Terms with Holes:: Write Prolog one term at a time, not one character at a time
* Jumping to Holes:: Commands for going to the next hole in the buffer
* Filling Holes:: Filling holes in Prolog terms
* Highlighting Holes:: Options for highlighting holes
Setting Breakpoints
* Breakpoint Menu:: Special mode for managing breakpoints
The Prolog Top-level
* Top-level Interaction:: The basics of working with a top-level
* Multiple Top-levels:: Creating and handling multiple top-level buffers
* Top-level Menu:: A special buffer for operating on active top-levels
* Top-level Signaling:: Commands for interrupting running top-levels
* Top-level History:: Accessing previous queries posted to the Prolog top-level
* Follow Messages:: Minor mode for visiting source locations in printed messages
* Send to Top-level:: Commands for sending goals to the be executed in the Top-level
Finding Prolog Code
* File Spec Expansion:: Integration with standard Emacs file-finding commands
* Native Predicates:: Finding and jumping to definitions of built-in SWI-Prolog predicates defined in C
Contributing
* Developing Sweep:: Instructions for preparing a local development environment for working on sweep
* Bug Reports:: Commands for contacting the maintainers of this project
Things To Do
* Editing Improvements:: List of potential enhancements for reading and writing Prolog
* General Improvements:: List of potentially useful new features
Indices
* Function Index::
* Variable Index::
* Keystroke Index::
* Concept Index::
@end detailmenu
@end menu
@node Overview
@chapter Overview
@cindex Sweep
Sweep is an embedding of SWI-Prolog in Emacs. It provides an
interface for executing Prolog queries and consuming their results
from Emacs Lisp (@pxref{Querying Prolog}). Sweep further builds on
top of this interface and on top of the standard Emacs facilities to
provide advanced features for developing SWI-Prolog programs in Emacs.
@menu
* Main Features:: Most important features that Sweep provides
* Architecture:: Overall structure of this project
* Alternatives:: Comparing Sweep with other Prolog Emacs packages
@end menu
@node Main Features
@section Main Features
Some of the main benefits that Sweep brings to working with Prolog
code in Emacs are:
@itemize
@item
Semantic highlighting, @pxref{Highlighting}.
@item
Automatic indentation, @ref{Indentation}
@item
Structural editing and navigation, @pxref{Term-based Editing}
@item
Jumping to predicate definitions and references, @pxref{Cross
References}
@item
On-the-fly diagnostics, @pxref{Showing Errors}
@item
Intelligent code completion, @pxref{Code Completion}
@item
Refactoring, @pxref{Renaming Variables} and @ref{Extract Goal}
@item
Integrated SWI-Prolog top-level, @pxref{The Prolog Top-level}
@item
Ability to run Prolog queries directly from Emacs Lisp, @ref{Querying
Prolog}
@end itemize
These features and others are documented in the rest of this manual,
along with many options that Sweep provides for you to customize its
behavior.
@node Architecture
@section High-level Architecture
@cindex architecture, of Sweep
@cindex design, of Sweep
@cindex Sweep architecture
@cindex Sweep design
Sweep uses the C interfaces of both SWI-Prolog and Emacs Lisp to
create a dynamically loaded Emacs module that contains the SWI-Prolog
runtime. As such, Sweep has parts written in C, in Prolog and in
Emacs Lisp.
The different parts of Sweep are structured as follows:
@cindex sweep-module
@cindex sweep.c
@itemize
@item
@file{sweep.c} defines a dynamic Emacs module which is referred to
from Elisp as @code{sweep-module}. This module is linked against the
SWI-Prolog runtime library (@file{libswipl}) and exposes a subset of
the SWI-Prolog C interface to Emacs in the form of Elisp functions
(@pxref{Querying Prolog}). Notably, @code{sweep-module} is
responsible for translating Elisp objects to Prolog terms and vice
versa.
@end itemize
@cindex sweeprolog.el
@itemize
@item
@file{sweeprolog.el} defines an Elisp library which builds on top of
@code{sweep-module} to provide user-facing commands and functionality.
It is also responsible for loading @code{sweep-module} the first time
you do something that involves interacting with Prolog.
@end itemize
@cindex sweep.pl
@itemize
@item
@file{sweep.pl} defines a Prolog module (named, unsurprisingly,
@code{sweep}) which is by default arranged by @file{sweeprolog.el} to
be loaded when the embedded Prolog runtime is initialized. It
contains predicates that @file{sweeprolog.el} invokes through
@code{sweep-module} to facilitate its different commands.
@end itemize
@node Alternatives
@section Comparison with Emacs's built-in Prolog mode
Emacs has a built-in mode for Prolog code, defined in the library
@file{prolog.el} that comes bundled with Emacs. @file{prolog.el} aims
to work with a wide variety of Prolog systems and dialects, unlike
Sweep that is very tightly integrated with SWI-Prolog specifically.
@strong{If you are working with SWI-Prolog, you'll find Sweep to be
far more powerful} than the built-in @file{prolog.el}. This is
because Sweep leverages the Prolog parser and other analysis tools
that SWI-Prolog itself uses, which give it access to highly accurate
and rich information about SWI-Prolog code. If you're using another
Prolog implementation, you should stick to @file{prolog.el} as Sweep
only supports SWI-Prolog.
@node Installation
@chapter Installation
@cindex requirements
Installing Sweep requires:
@itemize
@item
Emacs 27 or later, and
@item
SWI-Prolog 8.5.18 or later.
@end itemize
@cindex install
Sweep is available from NonGNU ELPA, to install it simply type in
Emacs @kbd{M-x package-install @key{RET} sweeprolog @key{RET}}.
Note that in Emacs prior to version 28, you need to explicitly enable
NonGNU ELPA by adding something like the following to your Emacs
configuration:
@lisp
(with-eval-after-load 'package
(add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/")))
@end lisp
@cindex update
@cindex upgrade
To upgrade Sweep to a newer version, do @kbd{M-x package-upgrade
@key{RET} sweeprolog @key{RET}}.
For @file{straight.el} users, use the following form to install Sweep:
@lisp
(straight-use-package '(sweeprolog :files (:defaults "*.pl")))
@end lisp
@node Getting Started
@chapter Getting Started
@cindex configuration
After installing the @code{sweeprolog} Elisp library, load it into
Emacs:
@lisp
(require 'sweeprolog)
@end lisp
@vindex sweeprolog-swipl-path
Sweep tries to find SWI-Prolog by looking for the @command{swipl}
executable in the directories listed in the Emacs variable
@code{exec-path}. When Emacs is started from a shell, it initializes
@code{exec-path} from the shell's @env{PATH} environment variable
which normally includes the location of @command{swipl} in common
SWI-Prolog installations. If Emacs doesn't find the @command{swipl}
executable via @code{exec-path}, you can tell Sweep where to find it
by setting the variable @code{sweeprolog-swipl-path} to point to it:
@lisp
(setq sweeprolog-swipl-path "/path/to/swipl")
@end lisp
All set! You can now use Sweep for Prolog development (@pxref{Editing
Prolog Code, , Editing Prolog code}) and for integrating Prolog into
your Emacs Lisp code (@pxref{Querying Prolog}). In the next section
(@pxref{Discovering Sweep}) you'll find some useful tips for learning
to work with Sweep.
@emph{Important note for Linux users:} prior to version 29, Emacs
would load dynamic modules in a way that is not fully compatible with
the way the SWI-Prolog native library, @file{libswipl}, loads its own
native extensions. This may lead to Sweep failing after loading
@code{sweep-module} (@pxref{Architecture}).
If you're running Emacs 28 or earlier on Linux, you can workaround
this issue by starting Emacs with @file{libswipl} loaded upfront via
@env{LD_PRELOAD}, for example:
@example shell
LD_PRELOAD=/usr/local/lib/libswipl.so emacs
@end example
@node Discovering Sweep
@chapter Discovering Sweep
Sweep comes with many useful commands and features for working with
SWI-Prolog. This section lists suggested ways for you to get to know
the provided commands and make the most out of Sweep.
The main documentation resource for Sweep is this very manual. It
describes almost every command and customization option that Sweep
provides. Since Sweep includes many features, describing all them
makes this manual longer then you'd probably want to read upfront.
Instead it's recommended that you skim this manual to get an idea of
the available features, and then return to it as a reference during
your work with Sweep.
To open this manual from within Emacs, type @kbd{C-h i} (@code{info})
to open the Info reader, followed by @kbd{d m sweep @key{RET}} to go
to the top Info directory and select the Sweep manual. Sweep also
provides a convenient command for opening the manual:
@findex sweeprolog-info-manual
@deffn Command sweeprolog-info-manual
Display the Sweep manual in Info.
@end deffn
To open the relevant part of the manual for a specific command that
you want to learn more about, type @kbd{C-h F} followed by the name of
that command. For example, typing @kbd{C-h F sweeprolog-info-manual
@key{RET}} brings up this manual section in Info. If the command
you're interested in is bound to a key sequence, you can go to its
Info node by typing @kbd{C-h K} followed by the key sequence that
invokes it.
Other than the text in this manual, Sweep commands and user options
have Elisp documentation strings that describe them individually. The
various Emacs Help commands (@kbd{C-h k}, @kbd{C-h f}, @kbd{C-h v},
etc.) display these documentation strings in a dedicated Help buffer
(@pxref{Help,,,emacs,}). From the Help buffer, you can jump to the
relevant Info node typing @kbd{i} (@code{help-goto-info}) to read more
about related commands and customization options.
You can also view an HTML version of this manual online at
@uref{https://eshelyaron.com/sweep.html}.
To learn about recent changes and new features in Sweep, check out the
NEWS file that comes with Sweep. You can open it with the command
@code{sweeprolog-view-news}:
@findex sweeprolog-view-news
@deffn Command sweeprolog-view-news
View the Sweep NEWS file.
@end deffn
@node Initialization
@chapter Prolog Initialization and Cleanup
The embedded SWI-Prolog runtime must be initialized before it can
start executing queries. Normally, Sweep takes care of initializing
Prolog for you the first time you use a command that requires running
some Prolog code. This section elaborates about Prolog initialization
and its customization options in Sweep:
@defopt sweeprolog-init-args
List of strings used as initialization arguments for Prolog. Sweep
uses these as the @var{args} argument of @code{sweeprolog-initialize}
when it initializes Prolog on-demand.
@end defopt
Sweep loads and initializes Prolog on-demand at the first invocation
of a command that requires the embedded Prolog. The user option
@code{sweeprolog-init-args} says which arguments to pass to Prolog
initialization. Its value is a list of strings that you can extend if
you want to pass specific command line flags SWI-Prolog. For example,
to limit the embedded Prolog stack to 512 MB, add the following to
your Emacs configuration:
@lisp
(with-eval-after-load 'sweeprolog
(push "--stack-limit=512m" sweeprolog-init-args))
@end lisp
Sweep initializes Prolog from Elisp by calling function
@code{sweeprolog-initialize}.
@defun sweeprolog-initialize prog @r{@b{&rest}} args
Initialize the embedded Prolog runtime. @var{prog} should be the path
to the @command{swipl} executable, and @var{args} should be a list of
command line arguments for @command{swipl}. Sweep initializes Prolog
as if it was started from the command line as @code{@var{prog}
@var{args}}.
@end defun
The function @code{sweeprolog-initialize} takes one or more string
arguments and initializes the embedded Prolog as if it were invoked
externally in a command line with the given strings as command line
arguments, where the first argument to @code{sweeprolog-initialize}
corresponds to @code{argv[0]}. This function is implemented in C in
@code{sweep-module} (@pxref{Architecture}).
@cindex sweep Prolog flag
The default value of @code{sweeprolog-init-args} is set to load the
Prolog helper library @file{sweep.pl} and to create a boolean Prolog
flag called @code{sweep} with value @code{true}. You can check for
this flag in Prolog code to detect at runtime that you're running
under Sweep.
@cindex command line arguments
It is also possible to specify initialization arguments to SWI-Prolog
by passing them as command line arguments to Emacs, which can be
convenient when using Emacs and Sweep as an alternative for the common
shell-based interaction with SWI-Prolog. This is achieved by adding
the flag @option{--swipl-args} followed by any number of arguments
intended for SWI-Prolog, with a single semicolon (@code{;}) argument
marking the end of the SWI-Prolog arguments, after which further
arguments are processed by Emacs as usual (see @ref{Emacs
Invocation,,,emacs,} for more information about Emacs's command line
options), for example:
@example shell
emacs --some-emacs-option --swipl-args -l foobar.pl \; --more-emacs-options
@end example
In order for Sweep to be able to handle Emacs's command line
arguments, you must call @code{sweeprolog-handle-command-line-args}
before Emacs processes the @option{--swipl-args} argument.
@defun sweeprolog-handle-command-line-args
Enable support for the Sweep-specific @option{--swipl-args} Emacs
command line flag. This flag can be used to specify additional Prolog
initialization arguments for Sweep to use when initializing Prolog
on-demand, directly from Emacs's command line invocation.
@end defun
This function makes Emacs recognize the @option{--swipl-args} command
line flag by adding a dedicated handler function to
@code{command-line-functions} (@pxref{Command-Line
Arguments,,,elisp,}). If you want to use @option{--swipl-args}, you
should arrange for @code{command-line-functions} to run before Emacs
processes @option{--swipl-args}. To do that, either place a call
@code{sweeprolog-handle-command-line-args} in your Emacs
configuration, or call it from the command line right before
@option{--swipl-args}:
@example
emacs -f sweeprolog-handle-command-line-args --swipl-args -l foobar.pl \;
@end example
@cindex restart Prolog
@cindex shutdown Prolog
@cindex cleanup Prolog
You can shut down or restart the embedded Prolog runtime using the
following commands:
@findex sweeprolog-shutdown
@deffn Command sweeprolog-shutdown
Shut down the embedded Prolog runtime.
@end deffn
@deffn Command sweeprolog-restart
Restart the embedded Prolog runtime.
@end deffn
The command @code{sweeprolog-shutdown} shuts down the Prolog runtime
and frees up resources Prolog allocated. You cannot shut down Prolog
with running top-levels (@pxref{The Prolog Top-level})---if you invoke
@code{sweeprolog-shutdown} while you have running top-levels, this
command suggests killing them, and if you refuse it complains and
keeps Prolog running. The command @code{sweeprolog-restart} is
similar to @code{sweeprolog-shutdown}, expect it starts the embedded
Prolog runtime anew after shutting it down. When you invoke
@code{sweeprolog-restart} with a prefix argument (@kbd{C-u M-x
sweeprolog-restart @key{RET}}), this command prompts for additional
initialization arguments to pass to the embedded Prolog runtime when
restarting it.
@node Querying Prolog
@chapter Querying Prolog
This section describes a set of Elisp functions that let you invoke
Prolog queries and interact with the embedded Prolog runtime:
@defun sweeprolog-open-query cxt mod functor input reverse
@anchor{Definition of sweeprolog-open-query}
Query the Prolog predicate @code{@var{mod}:@var{functor}/2} in the
context of the module @var{cxt}. Convert @var{input} to a Prolog
term and use it as the first argument, unless @var{reverse} is
non-@code{nil}, in which can use @var{input} as the second argument.
The other argument is called the @dfn{output argument} of the query,
it is expected to be unified with some output that the query wants to
return to Elisp. The output argument can be retrieved with
@code{sweeprolog-next-solution}. This function always returns
@code{t} when its arguments are valid, otherwise it returns
@code{nil}.
@end defun
@defun sweeprolog-next-solution
@anchor{Definition of sweeprolog-next-solution}
Return the next solution of the last Prolog query. Return a cons cell
@code{(@var{det} . @var{output})} if the query succeeded, where
@var{det} is the symbol @code{!} if no choice points remain and
@code{t} otherwise, and @var{output} is the output argument of the
query converted to an Elisp S-expression. If there are no more
solutions, return @code{nil} instead. If a Prolog exception was
thrown, return a cons cell @code{(exception . @var{exp})} where
@var{exp} is the exception term converted to Elisp.
@end defun
@defun sweeprolog-cut-query
Cut the last Prolog query. This releases any resources reserved for
it and makes further calls to @code{sweeprolog-next-solution} invalid
until you open a new query.
@end defun
@defun sweeprolog-close-query
Close the last Prolog query. Similar to @code{sweeprolog-cut-query}
expect that any unifications created by the last query are dropped.
@end defun
Sweep provides the Elisp function @code{sweeprolog-open-query} for
invoking Prolog predicates. The predicate you invoke via this
function must be of arity two, and it will be called in mode
@code{p(+In, -Out)}---the predicate should treat the first argument as
input and expect a variable as the second argument, which it should
unify with some output. This restriction is placed in order to
facilitate a natural calling convention between Elisp, a functional
language, and Prolog, a logical one.
The @code{sweeprolog-open-query} function takes five arguments, the
first three are strings which denote:
@itemize
@item
The name of the Prolog context module from which to execute the query,
@item
The name of the module in which the invoked predicate is defined, and
@item
The name of the predicate to call.
@end itemize
The fourth argument to @code{sweeprolog-open-query} is converted into
a Prolog term and used as the first argument of the predicate
(@pxref{Elisp to Prolog}). The fifth argument is an optional
@dfn{reverse flag}---when this flag is set to non-@code{nil}, the
order of the arguments is reversed such that the predicate is called
in mode @code{p(-Out, +In)} rather than @code{p(+In, -Out)}.
To examine th results of a Prolog query, use the function
@code{sweeprolog-next-solution}. If the query succeeded,
@code{sweeprolog-next-solution} returns a cons cell whose @code{car}
is either the symbol @code{!} when the success was deterministic or
@code{t} otherwise, and the @code{cdr} is the current value of the
second (output) Prolog argument converted to an Elisp object
(@pxref{Prolog to Elisp}). If the query failed,
@code{sweeprolog-next-solution} returns nil.
Sweep only executes one Prolog query at a given time, so you need to
close close queries that you open with @code{sweeprolog-open-query}
before opening new ones. When no more solutions are available for the
current query (@code{sweeprolog-next-solution} returns @code{nil}), or
when you're otherwise not interested in more solutions, you must close
the query with either @code{sweeprolog-cut-query} or
@code{sweeprolog-close-query}. Both of these functions close the
current query, but @code{sweeprolog-close-query} also destroys any
Prolog bindings that it created.
@menu
* Elisp to Prolog:: How sweep translates Emacs Lisp to Prolog
* Prolog to Elisp:: How sweep translates Prolog to Emacs Lisp
* Example Query:: Counting solutions for a Prolog predicate in Elisp
* Call Back to Elisp:: Special predicates for calling back to Emacs from Prolog
@end menu
@node Elisp to Prolog
@section Conversion of Elisp objects to Prolog terms
Sweep converts Elisp objects into Prolog terms to allow the Elisp
programmers to specify arguments for Prolog predicates invocations
(@pxref{Definition of sweeprolog-open-query}). Seeing as some Elisp
objects, like Elisp compiled functions, wouldn't be as useful for
passing to Prolog as others, Sweep only converts Elisp objects of
certain types to Prolog, namely Sweep currently converts @emph{trees
of strings and numbers}:
@itemize
@item
Elisp strings are converted to equivalent Prolog strings.
@item
Elisp integers are converted to equivalent Prolog integers.
@item
Elisp floats are converted to equivalent Prolog floats.
@item
The Elisp nil object is converted to the Prolog empty list @code{[]}.
@item
Elisp cons cells are converted to Prolog lists whose head and tail
are the Prolog representations of the @code{car} and the @code{cdr} of the cons.
@end itemize
@node Prolog to Elisp
@section Conversion of Prolog terms to Elisp objects
Sweep converts Prolog terms into Elisp object to allow efficient
processing of Prolog query results in Elisp (@pxref{Definition of
sweeprolog-next-solution}).
@itemize
@item
Prolog strings are converted to equivalent Elisp strings.
@item
Prolog integers are converted to equivalent Elisp integers.
@item
Prolog floats are converted to equivalent Elisp floats.
@item
A Prolog atom @code{foo} is converted to a cons cell @code{(atom . "foo")}.
@item
The Prolog empty list @code{[]} is converted to the Elisp @code{nil} object.
@item
Prolog lists are converted to Elisp cons cells whose @code{car} and @code{cdr} are
the representations of the head and the tail of the list.
@item
Prolog compounds are converted to list whose first element is the
symbol @code{compound}. The second element is a string denoting the
functor name of the compound, and the rest of the elements are the
arguments of the compound in their Elisp representation.
@item
All other Prolog terms (variables, blobs and dicts) are currently
represented in Elisp only by their type:
@itemize
@item
Prolog variables are converted to the symbol @code{variable},
@item
Prolog blobs are converted to the symbol @code{blob}, and
@item
Prolog dicts are converted to the symbol @code{dict}.
@end itemize
@end itemize
@node Example Query
@section Counting solutions for a Prolog predicate in Elisp
Below is an example usage of the Sweep interface for calling Prolog.
It shows an invocation of the non-deterministic predicate
@code{lists:permutation/2} directly from an function Elisp that counts
the number of different permutations of the list @code{(1 2 3 4 5)}:
@lisp
(sweeprolog-open-query "user" "lists" "permutation" '(1 2 3 4 5))
(let ((num 0)
(sol (sweeprolog-next-solution)))
(while sol
(setq num (1+ num))
(setq sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
num)
@end lisp
@node Call Back to Elisp
@section Calling Elisp function inside Prolog queries
Sweep defines the foreign Prolog predicates @code{sweep_funcall/2} and
@code{sweep_funcall/3}, that you can use for calling Elisp functions
from Prolog code. You can only call these predicates in the context
of a Prolog query initiated by @code{sweeprolog-open-query}, meaning
that they only work in the main Prolog thread (which is also Emacs's
main thread). The first argument to these predicates is a Prolog
string holding the name of the Elisp function to call. The last
argument to these predicates is unified with the return value of the
Elisp function, represented as a Prolog term (@pxref{Elisp to
Prolog}). @code{sweep_funcall/3} converts its second argument to an
Elisp object (@pxref{Prolog to Elisp}) and passes it as a sole
argument to the Elisp function it invokes. The @code{sweep_funcall/2}
variant invokes the Elisp function without any arguments.
@node Editing Prolog Code
@chapter Editing Prolog code
@cindex Sweep Prolog mode
@cindex sweeprolog-mode
@cindex major mode for Prolog, sweeprolog-mode
@cindex Prolog major mode, sweeprolog-mode
Sweep includes a dedicated major mode for reading and editing Prolog
code---Sweep Prolog mode, or simply @code{sweeprolog-mode}.
@findex sweeprolog-mode
@deffn Command sweeprolog-mode
Enable the Sweep Prolog major mode for reading and editing SWI-Prolog
code in the current buffer.
@end deffn
@defvar sweeprolog-mode-hook
Hook run after entering Sweep Prolog mode. @xref{Hooks,,,emacs,}, for
more information about major mode hooks in Emacs.
@end defvar
To activate this mode in a buffer, type @kbd{M-x sweeprolog-mode
@key{RET}}. To instruct Emacs to always open Prolog files in Sweep
Prolog mode, modify the Emacs variable @code{auto-mode-alist}
accordingly:
@lisp
(add-to-list 'auto-mode-alist '("\\.plt?\\'" . sweeprolog-mode))
@end lisp
@xref{Choosing Modes,,,emacs,}, for more information about how Emacs
chooses a major mode to use when you visit a file.
To list all of the commands available in a Sweep Prolog mode buffer,
type @kbd{C-h m} (@code{describe-mode}). When Menu Bar mode is
enabled, you can run many of these commands via the Sweep menu. For
more information about Menu Bar mode, @pxref{Menu Bars,,,emacs,}.
@menu
* Indentation:: How sweep indents Prolog code
* Highlighting:: Rich fontification for Prolog code
* Hover for Help:: Display description of Prolog tokens by hovering with the mouse
* Code Layout:: Commands for aligning Prolog code without having to count spaces
* Term-based Editing:: Commands that recognize and operate on Prolog terms
* Holes:: Commands for finding and filling holes for interactive term insertion
* Cross References:: Commands for finding cross-references for Prolog predicates
* Predicate Boundaries:: Commands operating on a Prolog predicate definition as a single unit
* File Specifications:: Commands for jumping to files that appear in Prolog code
* Loading Buffers:: Commands for loading Prolog predicates from the current buffer
* Setting Breakpoints:: Commands for setting breakpoints in Prolog buffers
* Creating New Modules:: Commands for populating new Prolog modules with predefined contents
* Documenting Code:: Commands for adding documentation to Prolog predicate definitions
* Usage Comments:: Commands for inserting comments that show example usage of your code
* Showing Prolog Docs:: Commands for showing documentation for Prolog predicates
* Showing Errors:: Commands for finding errors in Prolog code
* Exporting Predicates:: Commands for adding Prolog predicates to their module's export list
* Code Completion:: Auto-completion commands for Prolog code
* Insert Term DWIM:: Commands for smart insertion of Prolog terms based on the surrounding context
* Writing Tests:: Commands that facilitate writing Prolog unit tests
* Code Dependencies:: Commands for managing dependencies of Prolog source files on each other
* Term Search:: Search for Prolog terms matching a given structure
* Term Replace:: Consistently replace a set of terms in Prolog buffers
* Context Menu:: Right-click on Prolog code to open contextual menus
* Renaming Variables:: Replacing occurrences of one Prolog variable with another
* Numbered Variables:: Commands for managing numbers in names of related variables
* Macro Expansion:: Commands for expanding SWI-Prolog macros
* Extract Goal:: Commands for extracting part of a Prolog clause body to a separate predicate
@end menu
@node Indentation
@section Indentation
@cindex indentation
Sweep Prolog mode uses a bespoke @dfn{indentation engine} to determine
the appropriate indentation of each line of Prolog code. The
indentation engine analyses the syntactic context of a given line and
decides how far it should be indented based on a set of
@dfn{indentation rules}.
@table @kbd
@kindex TAB @r{(Sweep Prolog mode)}
@kindex C-i @r{(Sweep Prolog mode)}
@findex indent-for-tab-command
@item @key{TAB}
@itemx C-i
Indent the current line. If the region is active, indent all the
lines within it (@code{indent-for-tab-command}).
@end table
@defun sweeprolog-indent-line
Indent the current line according to SWI-Prolog conventions. This
function is used as the value of @code{indent-line-function} in Sweep
Prolog mode buffers.
@end defun
@findex sweeprolog-infer-indent-style
@deffn Command sweeprolog-infer-indent-style
Infer the @dfn{indentation style} of the current buffer from its
contents.
@end deffn
@defopt sweeprolog-indent-offset
Number of columns to indent nested code to in Sweep Prolog mode buffers.
@end defopt
The entry point of the indentation engine is the function
@code{sweeprolog-indent-line} which takes no arguments and indents the
line at point. Sweep Prolog mode cooperates with the standard Emacs
interface for indentation by arranging for
@code{sweeprolog-indent-line} to be called whenever a line should be
indented, notably when you press @code{TAB}. For a full description
of the available commands and options that pertain to indentation,
@xref{Indentation,,,emacs,}.
@cindex indentation style
@vindex indent-tabs-mode
The user option @code{sweeprolog-indent-offset} specifies how many
columns Sweep keeps empty between every level of indentation. The
standard Emacs variable @code{indent-tabs-mode} determines if
indentation can use tabs or only spaces. You may sometimes want to
adjust these options to match the indentation style used in an
existing Prolog codebase. The command
@code{sweeprolog-infer-indent-style} can do that for you by analyzing
the contents of the current buffer and updating the buffer-local
values of @code{sweeprolog-indent-offset} and @code{indent-tabs-mode}
accordingly. Consider adding @code{sweeprolog-infer-indent-style} to
@code{sweeprolog-mode-hook} to have it set up the indentation style
automatically in all Sweep Prolog mode buffers:
@lisp
(add-hook 'sweeprolog-mode-hook #'sweeprolog-infer-indent-style)
@end lisp
@menu
* Indentation Rules:: The intented indentation scenaria
@end menu
@node Indentation Rules
@subsection Indentation rules
Sweep Prolog mode indents lines according to the following rules:
@enumerate
@item
If the current line starts inside a string or a multi-line comment,
do not indent.
@item
If the current line starts with a top term, do not indent.
@item
If the current line starts with a closing parenthesis and the
matching opening parenthesis is part of a functor, indent to the
column of the opening parenthesis if any arguments appear on the
same line as the functor, otherwise indent to the start of the
functor.
This rule yields the following layouts:
@example prolog
some_functor(
some_arg
).
some_functor( some_arg
).
@end example
@item
If the current line is the first non-comment line of a clause body,
indent to the starting column of the head term plus the value of the
user option @code{sweeprolog-indent-offset} (by default, four extra
columns).
As an example, this rule yields the following layouts when
@code{sweeprolog-indent-offset} is set to the default value of four
columns:
@example prolog
some_functor(arg1, arg2) :-
body_term.
asserta( some_functor(arg1, arg2) :-
body_term
).
@end example
@item
If the current line starts with the right hand side operand of an
infix operator, indent to the starting column of the first operand
in the chain of infix operators of the same precedence.
This rule yields the following layouts:
@example prolog
head :- body1, body2, body3,
body4, body5.
A is 1 * 2 ^ 3 * 4 *
5.
A is 1 * 2 + 3 * 4 *
5.
@end example
@item
If the last non-comment line ends with a functor and its opening
parenthesis, indent to the starting column of the functor plus
@code{sweeprolog-indent-offset}.
This rule yields the following layout:
@example prolog
some_functor(
arg1, ...
@end example
@item
If the last non-comment line ends with a prefix operator, indent to
starting column of the operator plus @code{sweeprolog-indent-offset}.
This rule yields the following layout:
@example prolog
:- multifile
predicate/3.
@end example
@end enumerate
@node Highlighting
@section Semantic Highlighting
@cindex fontification
@cindex highlighting
@cindex syntax highlighting
@cindex semantic highlighting
Sweep Prolog mode highlights Prolog code through the standard Emacs
@code{font-lock} system (@pxref{Font Lock,,,emacs,}). Sweep Prolog
mode highlights different tokens in Prolog code according to their
semantics, determined through static analysis that Sweep performs on
demand. When you first open a buffer in Sweep Prolog mode, its entire
contents are analyzed to collect and cache cross reference data, and
Sweep highlight all of the code in the buffer accordingly. In
contrast, while you edit and move around the buffer, Sweep uses a
faster, local analysis for updating the semantic highlighting in
response to changes in the buffer.
@table @kbd
@kindex C-c C-c @r{(Sweep Prolog mode)}
@findex sweeprolog-analyze-buffer
@item C-c C-c
Analyze the current buffer and update cross-references
(@code{sweeprolog-analyze-buffer}).
@end table
@defopt sweeprolog-analyze-buffer-on-idle
Whether to analyze @code{sweeprolog-mode} buffers on idle. Defaults
to @code{t}.
@end defopt
@defopt sweeprolog-analyze-buffer-max-size