-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathconv.85
executable file
·1686 lines (1407 loc) · 79.8 KB
/
conv.85
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
-*-Text-*-
File: CONV Node: Top Up: (DIR) Next: Init
Programming in TECO for EMACS
* Menu:
* Init Files: Init INIT files and what they can do.
* Syntax: Syntax Syntax library source files to be compiled by
the EMACS library compiler in the PURIFY library.
Description of TECO mode, good for editing
source code for libraries.
* Libraries: Lib Other conventions for Libraries and sources.
* Ivory: (Ivory)Top The IVORY library has an alternative
compressor and purifier mechanism.
* Programming: Prog Conventions for TECO programs to be operated
in the EMACS enviromnment.
* Buffers:: Data structures for EMACS buffers.
* Windows:: Data structures for two window mode.
* Complete:: How to read names with completion.
* Variables: Vars Named variable (QFoo, etc) conventions.
* Major Modes: Major How to define new major modes.
* Submodes:: How to define submodes.
* Prefix:: Prefix characters, such as C-X.
* Hooks:: Variables which EMACS will call at specific times.
* Novice:: Setting up restricted subsets for beginners.
* Dump:: Dumping EMACS environments.
* Build:: Building and dumping the standard EMACS environment.
* Wall Charts:: Making wall charts.
* Abstracts:: Making abstracts of libraries (for documentation)
and source listings and source indexes of
TECO code (good for studying the code).
* Q-registers: Qregs Conventions for use of Q-registers.
* FS ^R PREV: FS^RPREV Conventions for setting/examining FS ^R PREV.
* Debugging: Debug Debugging aids in EMACS.
* TDEBUG: (TDEBUG) TDEBUG is a package for stepping and
breakpoints in TECO code.
File: CONV Node: Init, Up: Top, Previous: Top, Next: Syntax
INIT Files.
This is not a full description of how to write init files,
because such a description has to include a full course on TECO
programming. People who want to learn to program in TECO should
follow this course of action: find a DEC TECO manual and read it
(much of that will apply to this TECO as well, though many individual
commands are different or missing in DEC TECO), look through the
TECORD file, then read this file. After that, you can read some EMACS
source code and init files using TECORD and this file as a reference.
Each user can have his own file of TECO commands for EMACS to
execute each time he starts it up. EMACS looks for the file
<hsname>;<user> EMACS and then for <hsname>;* EMACS, where <hsname>
stands for the user's home directory. If neither file exists, the
file EMACS;* EMACS (the default init file) is used instead.
On Twenex, the init file is called EMACS.INIT in your login directory,
and the default init file is <EMACS>EMACS.INIT.
You can cause an EMACS to read another user's init file by giving it
that user's name as its XUNAME; just do <user>^S in DDT immediately
before starting the EMACS. To avoid running your own init file,
specify a name like FOO which has no init file.
Setting up the default character definitions and named variables
need not be done in an init file, since that is done before the EMACS
environment is dumped out. As a result, your init file need only
define those commands which you wish to change. Use MM Load Lib to
load any additional libraries (or the :EJ command, for libraries which
have no & Setup <library> Library function). To obtain a function as a
value so you can put it on a character, simply use M.M <name> . The
U command can define a character, as in for example U..^RX which puts
its argument on Meta-X. The character is specified in the same manner
as in an EVARS file; *Note EVARS: (EMACS)Init. Use M.V to create and
assign a variable, or better yet M.C to give it some documentation as
well. *Note Vars: Vars, for details of how to use M.V and M.C.
When the init file is started, all q-registers not used by EMACS
(and described herein) will probably be zero. One exception is Q1,
which contains the version number of EMACS :EJ (on ITS, [PURE] >), as
a string. The default init file types this out as the "EMACS version
number".
If you have no init file, EMACS runs the default init file, which is
the init file on the EMACS directory. This does various things such
as processing a command line from the superior, loading LISPT if
necessary, printing the EMACS version number and offering help, ...
Most people will find that they wish to perform the actions of the
default init file after their own peculiar initializations.
To do this, just end your own init file with
ER EMACS;* EMACS @Y ET@ > :M(HFX*)
(On Twenex, do EREMACS;EMACS INIT or ER<EMACS>EMACS.INIT instead)
This practice is recommended because some of the things in the default
init file are important for the proper functioning of EMACS.
The above sample of code calls the default init file with an empty
buffer. If you call it with text in the buffer, that text is used
instead of the job's command line arguments.
To prevent the default init file from printing its help message,
create the variable Inhibit Help Message and make it nonzero.
If you have enough of your own functions to have a private library of
them, you need not have both the library and an init file to load the
library. You can just call your library <user> EMACS and give it a
~Filename~ of INIT and a & Setup INIT Library function to perform the
other initialization. The & Setup INIT Library function should end by
jumping to the default init file, just like an ordinary init file made
of text should.
File: CONV Node: Syntax, Up: Top, Previous: Init, Next: Lib
Syntactic Conventions for EMACS Library Source Files
The fundamental basis of EMACS is the library, which contains a set
of functions written in TECO, together with their names and
documentation. There is one standard library which contains the main
body of EMACS, and there are other libraries that are loaded sometimes
automatically or by request. For more information on how to use
libraries, *Note Use: (EMACS)Libraries. This node describes how to
write library source files, and the next node describes how to compile
them.
A source file of EMACS functions contains one function on each page.
Each function has a name and documentation as well as its definition.
These source files are processed by a compressor which deletes spaces
and comments and performs other syntactic transformations before they
are run. You can also ask to compress and install a single function,
for testing, by pointing at it and using MM Compile.
Every function definition should end with a CRLF, after which may
come a ^L and the next function definition. Function definitions are
separated only by CRLF ^L CRLF. A ^L in the middle of the line is
just part of a function. If you want to put CRLF ^L CRLF inside a
function, use CRLF ^]^Q^L CRLF.
The Function Name
Every function's definition begins with the function name, which is
preceded by a ! and followed by :!. You must not ever put a :!, even
with spaces in between, in a source file except to end a function
name. The function name must be the first thing on a page except for a
CRLF which must follow the previous formfeed on pages after the first.
The name conventions are that subroutine names start with "& " and
names of commands intended to be put on characters start with "^R ".
This is to keep them from limiting the user's ability to abbreviate
the names of commands he wishes to type. Another convention is that
"#" begins the names of commands which form a dispatch table. For
example, in INFO, the command M causes # INFO M to be run. If you
define a command named # INFO +, that will automatically give you an
INFO command called +.
The Function Documentation
After the function name comes a space, an !, and then the function
class. Then, after another space, the rest of the line is the "brief"
documentation which is used when only a single line is wanted. It
should be a complete sentence. The function class should be the
character C for a command which users should call by name, S for a
command intended to be used as a subroutine, and ^R for a command
intended to be placed on a character. The function class does not
restrict how the function can actually be used; some of the
documentation commands filter commands to be described by class.
The function may have only the brief documentation. In this case,
the brief documentation should be followed by an !. Otherwise, the
lines following the brief documentation are the full documentation,
which ends with the first !. The ! must be at the end of its line,
and should not be an excuse to omit punctuation for the last sentence,
since it will not be seen by the user. To put an ! in the text of the
documentation, use control-^.
If you wish to refer to one or two character commands in the
documentation, you should not just put in the characters of the
command, since that would make the documentation wrong for users who
move their commands around. The thing to do instead is to put in the
full name of the function which you are referring to, surrounded by
characters. When the documentation is printed out, this is replaced
by the name of the character which is connected to the function, if
there is one. If there isn't one, the function's name is used
instead. For example, you could use ^R Exit to refer to the command
to exit from a recursive edit, which in the standard environment can
be invoked with either Control-Altmode or C-M-C, and when the
documentation is printed it will say "Control-Altmode" or
"Control-Meta-C". The construct cannot be used in the brief
documentation because only the command which prints the full
documentation knows how to process it.
For even more flexibility in the documentation of a function, if the
string between the characters starts with an Altmode, it is
considered a TECO program to be executed, rather than a function name
to be looked up. It does not undergo the same syntactic preprocessing
that the function definitions do;; spaces are represented as spaces,
not as underlines, etc. The TECO program can either print text out or
insert it in the buffer (from which M-X Describe will print it out).
When this TECO program is run, it receives the name of the function as
a postcomma argument (a string pointer) or the numeric code for the
character being described as a precomma argument, or both. A string
containing the command character sequence being described can be
passed as a precomma argument instead of a number.
The Function Definition
After the line ending with !, the next line contains the beginning
of the function definition proper. Usually, a blank line is put there
to improve readability. You must remember that the definition will
not be used as written, but will be processed syntactically first: all
spaces and tabs, except those following a ^Q, will be deleted. all
_'s not following a ^Q will be turned into spaces. !* is taken to
start a comment and everything from there up to and including the
following ! is deleted (again, a ^Q will prevent this). Double CRLFs
are converted to single ones. Normally, you should use ^]^Q to do
such quoting, since that is safe in all contexts. Inside search
commands and file commands a ^Q by itself is enough.
TECO Mode
The major mode TECO Mode is useful for editing EMACS source files.
Comments are defined to start with !* and end with !. Tab is set to
the command ^R Indent Nested, which normally moves the current line to
be under the previous line. With an argument, it takes the argument
to be the number of levels "up" to go, where up means a lesser amount
of indentation. Thus, Tab with an argument of 2 or more is good for
the first line after the end of a conditional or iteration. In
addition, unindented lines and lines containing only comments are
ignored. In addition, Meta-' is defined to move forward over a TECO
conditional, and Meta-" to move back. These commands ignore quotes
that are inside comments.
File: CONV Node: Lib, Up: Top, Previous: Syntax, Next: Prog
Library File Conventions
The command Generate Library, in the library PURIFY, is used to
generate :EJ'able libraries from source files following the syntactic
conventions. The operation has two logical subparts: compression,
which removes spaces and comments, and extracts the documentation into
separately named functions; and purification, which converts the
intermediate form into a :EJ'able library. It is possible to divide
the source for a large library into several subfiles, which will be
compressed separately but purified together. This saves time if only
some of the subfiles are modified, since the compressed versions are
saved in separate files and reused if more recent than the sources.
Generate Library handles such multi-file sources automatically if all
the source files' names are given to it.
One of the source files going into a library should define a
"function" named ~Filename~. The "definition" of this function should
be some kind of identification for the file. It should usually be the
same as the first filename of the library. The documentation for
~Filename~ should describe the purpose of the library as a whole. It
should NOT have a function class ("S", "C" or "^R") at the front.
Generate Library automatically creates a ~Directory~ object which
contains a list of all the functions in the file. A library should
never contain two functions with the same name (~Filename~ is an
exception: see below).
Sometimes it is desirable to merge several library sources into one
:EJ file. If you always like to use, say, TAGS :EJ, and have a
private library, you may save space and increase speed by including
the source of TAGS when generating your private library. This,
however, means that you need to be able to override the ~Filename~
function which comes from the source of TAGS. Generate Library solves
this problem by deleting all but the first ~Filename~. Your private
source file must come first, and contain a ~Filename~, to override the
one in the TAGS source.
Libraries intended to be accessed via the Run Library command should
contain a function named <ENTRY>, which will be the default entry
point, so that the user need not specify the entry point name. In
addition, they MUST have a ~FILENAME~ which is identical to the actual
first name of the file, so that Run Library can tell whether the
library is already loaded.
If a library contains a function named & Setup <libname> Library,
where <libname> is the library's ~Filename~ name, then whenever the
library is loaded with MM Load Library that function will be called.
It can be used to connect some of the library's functions to
characters, for example. If it is used for that purpose, then it
should allow the user to override it by setting up a named variable.
For example, the TAGS library has an & Setup TAGS Library function,
which defines Meta-. as a command. However, if the variable TAGS
Setup Hook is nonzero, & Setup TAGS Library executes that variable
instead of its default actions. Thus, a user's init file can specify
where the TAGS commands should go if TAGS is ever loaded, by defining
TAGS Setup Hook.
If you wish, you can put a function called & Kill <libname> Library
in the library. If the library is killed with the Kill Libraries
command, this function will be called. A string pointer to the
library in core will be passed to it as an argument. The & Kill
function might try to remove pointers into the library from important
places where they were put by the & Setup <libname> Library function.
It is probably not worth while looking for characters which have been
connected to functions in the library, since this is painful and slow,
and the worst that can happen is that those commands will cause errors
when used. However, if pointers into the library were placed in
important FS flags, it may be essential to remove them if TECO is to
continue functioning properly.
It is a good idea for an & Kill <libname> library function to
execute the value of <libname> Kill Hook if it exists and is nonzero.
In addition to the names of functions, there are several names that
(usually or always) be found in libraries. For every function FOO, an
object named ~DOC~ FOO is available, that contains FOO's
documentation. In addition, ~DIRECTORY~ contains a list (one per
line) of all the functions that the file wishes to advertise that it
contains. Special things such as described in this section, and all
commands with ~ in their names, are not included.
~INVERT~ is supposed to be a function that is the inverse of the
loader function. That is, <object in file>,<pointer to file> fed to
the ~INVERT~ function should return a string containing the name of
the object. You should not have to be aware of ~INVERT~, because it
will be provided automatically, and called by & Macro Name when
necessary.
The BARE library, which contains "definitions" for the sake of
documentation of the built-in functions used to define some command
characters, has a different loader function and so must be generated
in a special way. The command MM BARE Library
Generatesource-file-name will generate and write out the BARE
library. The difference in the loader function is simply that if a
function's definition is three characters long or fewer then it is
treated as the name of a command character (as in .^RA for C-A) and
that character's initial raw-TECO definition is returned instead. If
the function's definition as found in the ordinary way is longer than
three characters, it really is the definition. This way,
documentation strings act normally but the command names themselves
can return the raw TECO commands as their definitions. BARE has a
~INVERT~ function which knows how to find the names of raw TECO
commands as well as strings in the library. However, & Macro Name has
to know specially that such commands, which are positive numbers
rather than strings, should be passed to the BARE library to invert.
File: CONV Node: Prog, Up: Top, Previous: Lib, Next: Buffers
Programming Conventions
For good programming practise, every CRLF that is not
part of a string argument should be followed by an indentation
to a position that indicates the current depth in iterations
and conditionals. Use of the Tab command will make this easy.
Since the FS S ERROR flag is normally set in EMACS, searches that
are followed by ";" must always be given the ":" modifier; otherwise,
they will cause errors when they fail, before noticing the ";". This
is because, if FS S ERROR is not set, a user who types an iteration
in the minibuffer and omits the ";" is likely to cause himself extreme
lossage. The Tab TECO command is disabled in the EMACS environment,
and is a no-op. Use 9I or I^]^Q<tab> to insert a tab.
Calling Subroutines
Use named subroutines whenever convenient. The subroutine
should usually have documentation beginning with "S "
so that users doing a "List Commands" will not see it, and
a name beginning with "& " so that it will not interfere with the
user's attempt to abbreviate command names.
Call the subroutine with M( M.M&_Subroutine) (note the
_ is used to get a space). MM&_Subroutine would work, but
functions are not supposed to depend on having no-dot q-regs
set up.
Use M.A to run a function in a specific library, loading the library
temporarily if necessary. For example: M(M.A DIRED& DIRED Enter)
calls the function & DIRED Enter in the DIRED library. M.A is
analogous to M.M. Both M.A and M.M accept a variable named MM Foo as
a definition of the function named Foo, and this takes precedence over
an actual definition of Foo in a loaded library.
^R Mode
The normal EMACS command level is precisely the TECO ^R command,
with characters redefined to run EMACS functions or user-supplied
functions. All of the information in TECORD on the ^R command,
facilities available for functions which are definitions of
characters, and what values should be returned by such functions, are
very important for anyone who writes functions which are to be placed
on characters.
The Mark
The mark is kept in TECO's "Ring buffer of point". It's value can
be obtained with :^V with no argument; <arg>:^V will push a new value
of the mark. ^V with no colon can be used to pop the mark (read TECO
ORDER for details). One consequence of this scheme is that there is
always a mark somewhere. Note that the C-W EMACS command POPS the
mark, rather than leaving a useless mark at point.
Recursive Editing Levels
A recursive editing level is implemented by the TECO command ^R.
Commands that call ^R on data that the user is likely not to regard
as "the thing he is editing" should do 0[..F before the ^R, to turn
off auto-saving, and inhibit window, buffer or file switching (either
of which would cause garbage results if allowed to proceed). See the
& Check Top Level subroutine. They should also bind the default
filenames to GAZONK .DEL, which will prevent the user from screwing
himself with a C-X C-W.
No non-dotted Q-regs should be reserved by functions, except for
user interfaces like MM. Also, avoid using double-dot Q-regs except
as defined in TECORD. All temporary Q-regs should be pushed and
popped. All functions should return with ^\ if possible, except for
those like M.A which need to leave something on the stack to be popped
later.
Numeric Arguments
The TECO commands ^X and ^Y refer to the values of the precomma and
postcomma arguments. (A function invoked with a character command
gets only a postcomma argument). If there was no argument, the
default value (zero or one, depending) is returned. To find out
whether there was an argument, use F^XF^Y.
F^XF^Y"N succeeds if there was an explicit argument (C-U or
otherwise). This makes it convenient to use the function as a
subroutine, since then one can give it any argument to mean
"C-U", and no argument to mean "no C-U". F^XF^Y can also be used to
check individually for precomma arguments or postcomma arguments.
The Mode Line
Anything that changes information which is displayed in the mode
line should do 1FS MODE CHANGE so that FS MODE MACRO will eventually
be run to update q-register ..J and thus the mode line.
Printing in the Echo Area
The @FT command can be used to print in the echo area. To clear the
echo area, do :I*^PC FS ECHO DISP. The echo area is normally
cleared after each command which uses it. If you want to print in the
echo area and prevent the message from being erased after the command,
you must set FS ECHO ACTIVE to zero after printing the message.
Reading Input
Commands that read input should do M.I before actually doing the FI
to read a character of input. M.I is in charge of prompting. It also
supplies a definition for FS HELP MAC that will handle the Help
character if it is typed at that time. The user may redefine .I if he
wishes to eliminate prompting, but even so he should still define all
his functions to use M.I so that other users will receive the behavior
they want. For more info on using M.I, do M-X Describe& Prepare for
Input.
M.I is useful for input read a character at a time. Other ways of
reading input are & Read Line, which reads a line terminated by a
Return, and & Minibuffer, which reads input allowing the user to edit
it in the minibuffer. See the code of those two functions for calling
conventions.
The TECO command F^K allows a function to take a string argument if
called with M-X, or read a line if invoked with a character command.
Do 1,F^KFoo:_ to read the argument in whichever fashion is
appropriate, prompting with "Foo: " if the argument is read from the
terminal, and return a pointer to the string containing the value.
This can be followed with a [1 command to store the string in
q-register 1.
File: CONV Node: Buffers, Up: Top, Previous: Prog, Next: Windows
EMACS Buffer Data Structures
An EMACS buffer is not the same thing as a TECO buffer object. A
TECO buffer an anonymous object which is a string stored in a special
way, so that it can be edited by the TECO program. It contains text,
the cursor location, and virtual boundaries, plus flags for modified
and read-only, and that is all. Selection is controlled by the
q-register ..O: whichever buffer object is put in ..O, that buffer
is the one edited by all TECO commands. An EMACS buffer is a more
complicated structure and a TECO buffer is just part of it.
All information about EMACS buffers is stored in a qvector called
the buffer table, which lives in q-register .B. This table contains a
sequence of variable-length entries, each describing one buffer. The
first word in each entry is its length in words; the next 12 have fixed
meanings; the remained describe the EMACS buffer's local variables, 2
words per variable. The index in words of the start of a buffer's
entry is called the buffer's index. The index of a buffer is needed
to access the components of the buffer's entry; but it can't be
expected to stay fixed while other buffers are selected, since a
buffer earlier in the table might have to make its entry larger to
create new local variables. Therefore, to remember one buffer for a
while, you must always use its name, not its index. Killing a buffer
that is not selected can change the current buffer's index! It knows
how to change the value of QBuffer Index if this happens.
An EMACS buffer has, among other things, a name, a TECO buffer, a
major mode, and visited filenames.
It also has a buffer number which identifies it uniquely from all
other buffers ever created earlier or later in the same EMACS. This
number is not the same as the buffer index. It is computed when the
buffer is created (by incrementing QNext Buffer Number) and
remembered while the buffer exists.
A buffer also has some "TECO-default filenames". These are not the
same in meaning to the visited filenames, though often they are equal.
When the buffer is selected, these names are made the TECO filename
defaults. When the buffer is deselected, the TECO filename defaults
are remembered here for the next selection.
Format of a Buffer Table Entry
Each fixed word in the buffer table entry has a symbolic name. These
names are just comments, so the numeric offset must be used as well,
but the name helps clarify the code and makes it easier to identify
places that need to be changed if the entry format is changed.
For example, to refer to the name of a buffer whose buffer index is in
Q1, you would write Q:.B(Q1+1!*Bufnam!)
Word 0: the length of this entry, in words.
Word 1!*bufnam!: the name of this buffer, a string.
Word 2!*bufvis!: the filenames visited in the buffer, a string, or 0.
Word 3!*bufmod!: the name of the major mode the buffer is in, a string, such as "LISP".
This may not be accurate for the buffer which is selected.
Word 4!*bufbuf!: the TECO buffer used to hold the text.
Word 5!*buftdf!: the TECO-default filenames remembered for this buffer.
They are 0 in a buffer that has never been selected.
This is not accurate for the buffer which is selected.
Word 6!*bufwin!: the FS WINDOW associated with the buffer.
This is not accurate for the buffer which is selected.
Word 7!*bufnum!: the buffer's buffer number.
Word 8!*bufdat!: the creation date of last file visited or saved.
This is used to give the warnings about files changed
on disk since they were visited.
Word 9!*bufver!: the version number of the last file read or written.
Word 10!*bufsav!: controlls auto-save for this buffer. Zero if no
auto saving. If 1, auto save as the visited file name.
Otherwise it should be a string which contains the names to
save as.
Word 11!*bufsiz!: the size of the buffer at the time of the last visit
or real save or auto save.
Word 12!*bufnwr!: the read protection flag for the buffer.
Positive means the buffer can be changed but the file cannot
be saved unless you insist. Negative means the buffer cannot
be changed.
Word 13!*buflcl!: the beginning of the local variables of the buffer.
Words 13,14: these describe one local variable of this buffer.
Word 13 is the string which is the variable's name.
Word 14 is the value. When the buffer is selected, this is
the global value. When the buffer is not selected, this is
the local value. The TECO command F^G is used for swapping
the local and global values of variables.
Words 15,16: the next local variable, etc.
The Current Buffer
The index of the current buffer is kept in QBuffer Index. All
information about it could be obtained from that through the buffer
table. However, the most important information is kept redundantly in
variables to be convenient to access. The name of the buffer is kept
in QBuffer Name, and the visited filenames are in QBuffer
Filenames, which will be zero if no file is visited. The current
major mode is in QMode, but looking at the name of the mode is
usually the wrong way to do something. The TECO buffer of the current
EMACS buffer can normally be found in ..O.
Switching between EMACS buffers officially is slow. For specific
temporary purposes, it is often enough to put an EMACS buffer's TECO
buffer object into Q..O temporarily so that the text of the buffer can
be manipulated. This is how Kill Some Buffers lets you examine a
buffer that you might want to kill.
Special Purpose Buffers
Often an EMACS subsystem will need to store data permanently.
Sometimes it is convenient to create a special EMACS buffer for this.
For example, TAGS keeps the tag table in a buffer called *TAGS*. This
allows the EMACS file visiting operations to be used as subroutines by
Visit Tag Table. It also allows the tag table to be selected by the
EMACS user when he wants to examine it.
Since M-. needs to look at the tag table, for efficiency a redundant
pointer to the TECO buffer object of the *TAGS* buffer is kept in a
variable. This saves M-. from having to search for the *TAGS* buffer
in the buffer table.
The convention for such special purpose buffers is that their names
start and end with stars.
The Previous Buffer
QPrevious Buffer contains the name of the buffer selected before
the current one. C-X B will use this as the default buffer to select.
Searching the Buffer Table
To refer to a buffer given its name or its buffer number, it is
necessary to search the buffer table, which contains the entries of
the buffers in order of creation. The subroutine & Find Buffer does
this. & Find File searches for a buffer visiting a given filename.
In either case, the buffer index is returned.
File: CONV Node: Windows, Up: Top, Previous: Buffers, Next: Complete
Data Structures for Two Window Mode
TECO can only deal with a single display window. When EMACS is in
two window mode, TECO is just displaying one buffer in a small window.
Only one EMACS buffer is selected, as always. Various information
about the buffer in the other window is remembered in a special set of
variables. Some information is kept which overrides what is
remembered in the buffer table, so that it is possible to select the
same buffer in both windows with different values of point, for
example.
When in two window mode, each window has several variables
describing its contents. Some of them are set up only when the window
is not selected; some are always valid. For window one, these are:
Window 1 Buffer the name of the EMACS buffer in window 1.
Window 1 Window the FS WINDOW setting for window 1. Valid only when
the window is not selected.
Window 1 Point the value of point in window 1. Valid only when the
window is not selected.
Window 1 Size the height of the window, in lines.
Window two has a similar set of variables. These variables stay
around when two window mode is left, so that if it is used again
things can be as they were before. To get information about either
window 1 or window 2, deciding which one at run time, put either
character (1 or 2) in a q-register such as Q1 and look at
QWindow_1_Buffer, etc.
In addition, there are these variables:
Other Window Buffer
the TECO buffer object of the EMACS buffer in the
other window.
Total Size the total size of the two windows plus the line
between them.
Default Size the setting of FS LINES in one window mode, saved
here while in two window mode.
To tell whether two window mode is in effect, see if QWindow 2
Size exists. If it does, two windows are being shown. This variable
can be killed with no loss of information when reentering one window
mode because its value can be deduced from QWindow 1 Size together
with QTotal Size. When two window mode is in effect, to tell which
window is selected, use FS TOPLINE. Window 1 is selected if it is
zero.
Redisplay of both windows when EMACS is continued is done by putting
& Multi-Window Refresh in FS REFRESH. This uses the variable QOther
Window Buffer to redisplay without having to do an EMACS buffer
switch.
File: CONV Node: Complete, Up: Top, Previous: Windows, Next: Vars
Completion
Completion is the feature whereby, when a command name is being read
in, Altmode and Space cause the appearance of characters determined by
the ones already read. It is possible to provide completion when
reading something other than a command name. Here is how.
The basic way to read something with completion is to use the F
command with the 8 bit set in its precomma argument. For example,
8,F Command:_
reads a command name with completion and returns it as a string.
To read something other than a command name, you must supply a table
of allowed strings. This table has the same form as the variable
table (that which lives in Q..Q): it is a qvector whose first element
is a number, the number of elements per entry, and whose following
elements are any number of entries. The first element of each entry
should be the string which is the name of the entry.
For completion's sake, it does not matter how long the entries are,
since only the name of each entry is used. The table can have one
element per entry, if its only purpose is completion. It can have
more than one element per entry if you wish. For example, the actual
variable table itself, which has three elements per entry, can be used
for completion of variable names.
Specify the table to be used for completion by putting it in the
variable CRL List before doing the F, and setting the 2 bit in the
argument to the F. Thus,
Q..Q[CRL_List
12.,F Variable_to_frobnicate:_
To allow the user to specify names which are not in the table, turn
on the 20. bit in the precomma argument. If this bit is set, the user
can type any string at all, followed by Return, and it will be
accepted. Only if the user types Altmode will it be rejected.
Normally, Return also rejects any string which is not in the table.
If you like, you can use Linefeed to specify names not in the table,
and make Return continue to insist on an existing name. To do this,
set the variable CRL Non-match Method to 4. (The normal behavior is
obtained with the value 2).
The 40. bit in the precomma arg says that Return should be allowed
as the first character typed. An empty string is returned as the
specified name.
You can additionally restrict completion to those names which start
with a prefix, at the same time making the prefix invisible to the
user (he does not have to type it, and does not see it echo). For
example, suppose your library LOSER uses variables with names such as
LOSER Object FOO to represent LOSER's definition of the object FOO.
Then you can read the name of a LOSER object with completion by doing
:I*LOSER_Object[CRL_Prefix
Q..Q[CRL_List
12.,F LOSER_Object:_
Then only variables with names starting with LOSER Object will be
considered. The user can type F and complete it to FOO; he does not
see the "LOSER Object" as part of the string, and just "FOO" is
returned.
You should set the variable CRL Name Type to a string which
describes what sort of name is being read. It is used as part of the
message printed if the user asks for help while typing the name.
The value of CRL Help is printed as additional help, after the
standard completion help, if that variable is not zero.
The hook CRL Name Lister allows you to customize the display done
if the user types "?" to list the possible completions of what he has
typed. It is called at two different times, with arguments to allow
it to distinguish the reason it was called.
For each possible completion, the CRL Name Lister is called once,
with a postcomma arg which is an index into the table in CRL List.
That table is also in Q.1 at the time. The function should insert
information about that name into the buffer beginning at point, and
include a CRLF at the end.
The function CRL Name Lister is called again after all the possible
completions have been processed. This time it will receive 1 as a
precomma arg. The text previously inserted in the temporary buffer
for all the alternatives is still there. The function might take the
opportunity to sort the list of names, or insert a heading.
File: CONV Node: Vars, Up: Top, Previous: Complete, Next: Major
Named Variable Conventions
EMACS makes extensive use of named variables, and provides features
for creating, destroying, editing, and listing them.
The basic way of getting the value of a named variable that already
exists is to do Q<name>. See TECORD for details. If you are
not sure whether a variable exists, you can do <default> FO..Q <name>
which will return the value if the variable exists, or <default> if
the variable does not exist. :FO can be used to tell whether a
variable exists. Any TECO command that can use a q-register, except
for ^], can also use an existing named variable if it is given the
name of the variable, surrounded by Altmodes, as the q-reg name.
Although TECO allows unambiguous abbreviations of the name to be used,
it is unwise to use abbreviations in a program.
To create a variable, do M.V<name>. Unlike Q and FO, M.V
deliberately does not handle abbreviations. It does discard leading
and trailing spaces (in a library source file, spaces and tabs are
deleted anyway, and to get a real space you must use "_"). If the
variable already exists, nothing will happen, but its value will be
returned. If it does not exist, it will be created with a value of 0,
and 0 will be returned.
<value>M.V<name> can also be used. This creates the variable if it
doesn't exist, but also in any case sets its value to <value>. The
value returned by the M.V will be <value>.
To give a variable a comment, use M.C<name><comment>. This sets
the variable's comment to <comment>, creating the variable first if
necessary. <value>M.C<name><comment> will set the variable to
<value> if it creates the variable. It will not change the value if
the variable already exists. This is NOT the same as what M.V does!
What M.C does is good for defaulting variables which are options,
whereas what M.V does is good for setting a variable for internal use
while making sure that it exists. M.C's value is the value of the
variable.
Sometimes it is more efficient for changing a variable's value to
redefine some command characters, instead of having one definition
which always checks the value of the variable. Do this by providing a
function to be run whenever the variable's value is changed. This function
is supplied by making it the variable's comment. Whenever the comment
begins with a "!" it is taken to be a function to be run in this manner.
The function is given the variable's new value as an argument. For
example, the comment could be "!! FS^rmdly" to copy the variable's
value into the FS ^R MDLY flag. This is (approximately) what is used
for the variable Auto Save Interval.
If you want a variable to be presented for editing by MM Edit
Options, you should give the variable a comment which starts with a
"*". If the variable is to have a function to run when it changes, and
so the comment must start with a "!", then the variable is an option
if the comment starts with "!*". NOTE: if you are not careful, the
TECO code to set up such a variable will contain "!*" which will be
taken as the beginning of a comment. Leaving a space (which will be
removed by compression) between the "!" and the "*" will prevent such
lossage. See where the file EINIT sets up such variables if this
isn't clear.
You can examine the value, and comment if any, of a variable by
doing MM Describe<name>, just as you would ask for the documentation
of a function.
Overriding Command Definitions
You can override the library definition of a function by defining
a variable named "MM " followed by the function name. M.M checks for
such a variable before looking the name up in the loaded libraries.
MM Compile installs the compiled function in just this way. A few such
MM variables are present in the default environment. This is to make
calling certain key subroutines more efficient; M.M takes less time
finding the variable than searching the libraries.
Listing and Killing Variables
To see a list of all existing variables, do MM List Variables with
a null string argument. Each variable's name and value (abbreviated
if too long) will be shown. A list of variables whose names contain
<string> can be seen by doing MM List Variables<string>.
To destroy a variable, do M(M.M Kill Variable)<name> to run
MM Kill Variable. This is necessary only in special situations.
Local Variables
Variables can be local to an individual buffer. To make a variable
local to the current buffer, do <value>M.L<name>. From then on,
setting the variable when the current buffer is selected will not
affect its global value, which other buffers will continue to see,
nor will changing that global value affect the local value. Each
buffer in which the variable is made local has its own value for the
variable, while all other buffers share one global value.
Doing M.L has the side-effect of creating the variable globally
with the value of 0 if it did not already exist globally. Local
variables will be created automatically when a file is visited which
contains a local modes specification at the end. They are also the
way in which major modes perform their redefinitions.
Not only variables, but q-registers as well, and command
character definitions, can be made local. To make a q-register
local, use the Make Local Q-register command, with the q-register name
as a string argument: M(M.M Make Local Q-reg)A makes QA local, and
M(M.M Make Local Q-reg).^RF makes the definition of Control-F local.
You can also make a TECO FS flag local by specifying "FS" followed by
the name of the flag as the "q-register" name. For example, M(M.M
Make Local Q-register)FSCTLMTA. Inside Major Mode functions, this
function is available as M.Q.
Temporary and Permanent Locals
There are two types of local variables: permanent ones and temporary
ones. The permanent ones have to be the first on the list; they
remain forever local in the buffer that has them. All others are
temporary; these disappear when you switch major modes. The locals
created by major modes are temporary, which is how one major mode gets
undone when a new one is selected. Other locals created by local mode
lists and by random use of M.L are also temporary.
The initial buffer is given a set of permanent local variables when
the EMACS environment is built. The way permanent locals are told
from temporary ones is that the number of permanent ones is kept in
the variable QInitial Local Count, and the first that many locals
are permanent.
When a new buffer is created, some or all of the locals of the
previously selected buffer are copied into it. If Default Major Mode
is empty, they are all copied (thus, the major mode is copied). If
Default Major Mode specifies a mode, then only the permanent locals
are copied into the new buffer. The value of Initial Local Count is
used to tell how many there are. Some of these locals are
reinitialized, however; and you can reinitialize others in the Buffer
Creation Hook.
To add a new permanent local to a buffer, use 2,M.L<varname>. This
adds a local at the front of the list instead of at the end, and
increments the value of Initial Local Count (which requires making IT
into a permanent local as well, if it isn't one already, but that
happens automatically).
To increase the set of permanent local variables of all buffers, you
can simply create a few locals in your init file with M.L and then
increase QInitial Local Count. This will give the initial buffer
extra locals, and all other buffers will get them through the copying.
To do this for all users at your site, you can modify & Load Essential
Environment at the end where it creates the standard set, to create a
few extra.
You can also cause each buffer to get extra permanent locals when it
is created, in the Buffer Creation Hook, by using 2,M.L inside it.
File: CONV Node: Major, Up: Top, Previous: Vars, Next: Submodes
Defining Major Modes.
Each major mode is embodied by a command, such as MM TECO Mode or
MM Lisp Mode. A major mode can be created simply by defining an
appropriate command. However, major mode commands must work in a
particular way.
Major modes make all their redefinitions by creating local
variables. This is how each buffer can have its own major mode.
Buffer switching does not consciously "switch" modes; it just swaps the
local variables, which has that effect.
The first thing which each major mode command must do is eliminate
the local variables, if any, made by the previous major mode. This is
done by calling M(M.M &_Init_Buffer_Locals). All local variables of
the current buffer, except those made when the buffer was created, are
killed, and the global values reassert themselves. In addition, &
Init Buffer Locals leaves Q.Q bound to the Make Local Q-register
command until the major mode command returns with .
Then, the major mode function should create any local variables and
local q-registers that it wants. Supplying a 1, argument to M.L
causes M.L to run much faster, assuming that the specified variable is
not already local. Example: 1,(:I*;) M.L Comment_Start. This is
recommended for cuatious use by major mode commands. Command
characters can be redefined by using M.Q, since character definitions
count as q-registers. Example: M.M ^R_Indent_for_Lisp M.Q ^^I makes
the Tab character local to the current buffer, and redefines it for
Lisp. The "1," argument can be used with M.Q also.
Many major modes have their own values of the delimiter dispatch
table Q..D. They construct these values by making Q..D a local
q-register, copying the value of Q..D that is lying around with
:I..D..D, and then changing the necessary entries with the
command MM & Alter ..D. This is so that any other changes to ..D made
by the user will not be discarded. A new ..D should be constructed
only the first time a mode is entered. It should be saved in a
variable such as Text ..D or Lisp ..D, and retrieved from there when
the mode is entered again. This way, if the user changes ..D with the
command Edit ..D, his changes remain in effect whenever he is in that
mode. He can also define the variable in advance in his initfile if
he knows that, whenever he is in a certain mode, he wants his ..D to
be just so.
Finally, the major mode function should do
1M(M.M &_Set_Mode_Line <mode name> ^\
& Set Mode Line makes the new mode appear in the mode line, and the 1
as argument tells it to do everything else appropriate for finishing
up the change of major mode: Setting the variable QMode, running
the value of <Mode> Mode Hook if it is defined.
Exiting with ^\ causes the binding of Q.Q, left by & Init Buffer
Locals, to be popped, as well as any other bindings made by the major
mode function.
File: CONV Node: Submodes, Up: Top, Previous: Major, Next: Prefix
Submodes and ..F
A submode is just a command which rebinds commands or variables and
then calls ^R recursively on the same buffer. A submode's name
usually starts with the word "Edit", as in "Edit Picture". Submodes
are to be distinguished from commands such as Edit ..D which call ^R
recursively on some other text.
For submodes to indicate that they are active, the variable Submode
is provided. Binding QSubmode to FOO causes [FOO] to appear in the
mode line after the name of the major mode. However, you must call
& Set Mode Line yourself before entering ^R, and you must do an FN
command to cause & Set Mode Line to be called on the way out (even if
you come out via a throw or an MM Top Level). Usually, the Edit FOO
submode will put FOO in the Submode variable.
Submodes need not bind ..F to zero. Because the buffer is not
bound, it works reasonably well to switch files, buffers or windows
inside a submode. However, you stay inside the submode when you
switch, which you may not like. Someday there may be a different
implementation of Submodes which makes them local to a buffer. In
fact, submodes are not fully worked out at this time.
File: CONV Node: Prefix, Up: Top, Previous: Submodes, Next: Hooks
Defining Prefix Characters.
An EMACS environment can contain any number of prefix characters,
although EMACS normally contains only one - C-X.
To define a prefix character, you must choose a place to put the
dispatch table for it. This can be a q-register or a variable. Call
MM Make Prefix Character<q-reg name> which returns a string which is
a definition of a prefix character which will look in the specified
q-register for the dispatch table. Then put this string into the
desired character's definition. Normally, dispatch tables are made 96
characters long. If you want Rubout to be available as a subcommand,