keykit-mode for Emacs
keykit-mode is an Emacs major mode for editing KeyKit code. If you don't know what is a major mode, or what is Emacs, then I guess this page is not for you :)
It is part of the GeoMaestro distribution (you can find it in the /xtra folder).
If you're not interesting in GeoMaestro, you may directly pick it here: stef-elisp.zip
Installation and customization
This code is intended for GNU Emacs v21.1 or later.
Put the files keykit-mode.el, kk_utils.el and query-sheet.el in your load path and add the following lines to your _emacs or .emacs file:
(autoload 'keykit-mode "keykit-mode" "KeyKit major mode." t)
(append '(("\\.\\(k[pc]?\\|tyk\\|toy\\)$" . keykit-mode)) auto-mode-alist))
To have fontification by default, add this line:
(add-hook 'keykit-mode-hook 'keykit-fontify)
The help system needs to be informed of the Keypath. So start Emacs, do a
M-x keykit-mode and select the "Customization" item in the KeyKit menu that should appear in the menu bar.
Two variables needs to be set in the customization group:
Kk Default Directory: your KeyKit directory
Kk Keypath: the list of directories making your Keypath (type
print(Keypath) at the KeyKit console to have this list)
While you are here, you can desactivate some items in the keykit-mode menu if you're not going to program the GeoMaestro system. Toggle
Kk Geomaestro Items off to do so.
The KeyKit menu
This first menu is subdivided in six parts:
- The first one is for customization, and also provides a toggle for the Outline minor mode.
- The second one manages remote KeyKit invocation:
- You can invoke lowkey (the batch version of KeyKit) on the current buffer. You may give a KeyKit command in the minibuffer, else the buffer is simply evaluated. Any output will be written in the *Shell Command Output* buffer.
This requires that the variable
kk-lowkey-executable fits your installation (on Linux it should work just as it is, on Windows you may have to give
kk-lowkey-executable a full name if the KeyKit binaries are not in the PATH)
- It is also possible to talk to KeyKit through TCP/IP. See below for more about this.
- The third and fourth parts handle indentation, motion, selection and commenting.
- The fifth part handles tabulation characters (which by default are not used when indenting the code, but are nonetheless required for documenting functions, as we will see below).
- The sixth part provides templates insertion. This is mostly useful for GeoMaestro programming: see this page for details on programming projectors, distortion functions and plug-ins.
The KK-doc menu: auto-documenting KeyKit code
The second menu is dedicated to the help system.
When you are writing a new KeyKit function, it is very interesting to document it on the fly if you think it will be useful for other people (or if you're afraid to forget what it does !). This can be done in the code itself by the mean of special comments that are actually keywords:
The above lines are inserted by the "Insert documentation fields" menu item. Here is an example of documented function:
#usage NulAndNil(any arguments you want)
#desc Does nothing: quite useless. But there's a message for you in the code.
#topics philosophy, eating, kangaroo
# hello, my friend.
All functions documented this way respond to the "man" item in the KK-doc menu. When you select "man", the minibuffer prompts for a function name; if your cursor is located on the name you want, just press
RETURN. A dedicated window will open and display the documentation.
Note that the "#" keywords must be followed by a tabulation: it is not required, but it makes it easier to use spaces to set up the documentation text. The tabulation is provided with the template. If you delete it or forget it when writing a keyword yourself, you will notice a difference in the keyword fontification: When the syntax is correct, the whole keyword appear in a single face; otherwise, its "#" is diplayed differently.
For all functions in the Keypath, documented or not, you can have direct access to their code with the "visit code" item. This makes it quite easy to edit a large amount of code spread over several files, and also to see how the usual KeyKit functions are written.
This also work for methods, but then you have to type the class name, dot plus the method name, like this (a GeoMaestro example):
"regexp search on topics" lists all functions whose #topics keywords fit a regular expression. The query result appears in the *Keypath search*. Clicking on a function name invokes "man" on it, clicking the corresponding file name visits its code.
The item "Make HTML man page" scans all code files in the
kk-HTML-doc-Keypath and writes HTML pages in the
kk-HTML-directory. The first one is called index.html
The customization group keykit-doc lets you choose a title and an external link, set the number of functions to be documented per page and choose an optional background picture.
See how it looks like here.
Word and regexp search
The last part of the KK-doc menu allows a search through the whole Keypath (that is, through all the code files) for either a string or a regular expression.
The query results appear in a new window called *Keypath search* as a list of all occurences found (this can be a lot if you use a broad regular expression). Each reference takes one line, which directly link to the corresponding occurence: just click on the line to jump there.
If you do not kill the *Keypath search* buffer, the results for the next search will be appended to the previous ones. Three large buttons at the beginning of this buffer make it possible to launch a search from there.
Clicking the [refresh] button redoes the corresponding search, erases the previous results and appends the new ones at the end of the buffer.
Driving KeyKit from Emacs via TCP/IP
On KeyKit side, the
launch_daemon_tcpip() function starts a task reading and writing to a local TCP/IP port (the task is called a "daemon" because it can restart automatically whenever it is killed or exited; this can be configured, though).
In GeoMaestro, this is done automatically at starting time if the parameter
LaunchTCPIPDaemon is set to 1 (this is NOT the default).
If you do not use GeoMaestro, you will need to add the KeyKit code file emacs_tcpip.k somewhere in your Keypath. If you ever install GeoMaestro later on, remove this file !
On Emacs side, a TCP/IP session is opened on the same local port by the command
M-x kk-tcpip or simply by selecting the "TCP/IP console" item in the KeyKit menu. This displays a buffer acting like a (quite powerful) KeyKit console.
It is then possible to have any region from a buffer in keykit-mode be directly evaluated by KeyKit (here, "directly" means that you don't have to #include the file you´re editing): just use the "Evaluate region" item in the KeyKit menu. This will not switch to the console buffer, though: you can do so at any time by clicking "TCP/IP console" again.
Set the customization parameter
nil if you don't want the console buffer to appear in a specific frame.
Console features and peculiarities:
The Emacs console provides all features inherited from comint-mode (input ring, accumulation, etc: see Emacs documentation or comint.el for more). Moreover:
- If the first character of the input is "
:", the rest is supposed to be wrapped in a
print(), so that for example "
:2+2" is equivalent to "
- If the first character of the input is a "
&", the rest is supposed to be wrapped in a
realtime(), so that it is immediately played. example: "
printf() output both in the current KeyKit console tool and in the Emacs console buffer.As a side effect, you may at times get in the Emacs buffer messages that were not intented to appear in the console (like the ones used in pop-up query windows)
- not all messages displayed in a regular KeyKit console will appear in the Emacs console buffer. Only the output of the functions
print() is automatically sent to Emacs. The messages issued from low-level C code can't be accessed from the high-level KeyKit langage in which GeoMaestro is entirely written and are thus invisible to Emacs.
Bugs and restrictions
I couldn't get comments to be fully managed, sorry, so here are some restrictions: avoid using double quotes in comments, it is not necessarily a problem (for indentation) but it can be, and it may break the comment fontification. Also, always have matching parentheses if any:
ph = 'a' # "this" may cause troubles
# while "this" should be fine
# ... but this: " is certainly not good
# (1) this is ok
# 2) this is not
Also, better not comment a code line featuring "#":
# ok for comment here
a = "#" # please no comment here
# here it's fine
... in most cases it is ok but this is not 100% sure...
There are certainly a few Evil Lurking Bugs that I am not aware of, so feedback is welcome.
-- Back --