This is a work-in-progress version of seed7-mode 🚧 . A lot of features are implemented but there's still some areas that need improvements or fixes. Please create a bug report for any problem you detect.
The seed7-mode-version
command, bound to C-c v
in seed7-mode buffers,
display the version UTC time stamp of the file in the message area, at bottom
of the screen. Use this to verify the version of the seed7-mode.el code you
are using.
Please include this information in bug reports.
Several features of the seed7-mode
are customizable.
Use the seed7-mode-customize
command, bound to C-c C
to quickly open the
seed7-mode
customization buffer.
The command is also accessible from the top menu as can be see here. Once issued it opens the seed7-mode customization buffer.
Use the customization buffer to view or change one or several customizable user-option variables.
Since these control the behaviour of the seed7-mode
the changes will only
apply to buffers that are then opened in seed7-mode
. If you already have
a buffer using the mode, change to fundamental-mode
and then back to
seed7-mode
for the changes to take effect..
Font lock syntax highlighting for Seed7 supports different faces for different Seed7 syntactic elements, including various faces for different types of numbers and warning font to identify some syntactic errors in the code, but not all.
See the following example screenshots:
Screenshot | Description |
---|---|
Terminal-mode Emacs | Shows the default highlighting of Seed7 code on Emacs running in a macOS Terminal. |
Graphical Emacs | Shows the default highlighting of Seed7 code on a basic GUI Emacs running in a macOS with the default scheme. |
The seed7-mode supports the Emacs outline minor mode: collapse and expansion of blocks, where heading is the first line of a declaration block. This allows navigation and code manipulation by headings (blocks).
Screenshot | Description |
---|---|
bas.sd7 outline all collapsed | The prg/bas.sd7 file shown with outline-minor-mode
active after executing outline-hide-sublevels |
bas.sd7 outline with 2 expanded | The same prg/bas.sd7 file shown with outline-minor-mode
active after expanding 2 outlines with outline-show-entry
at lines 154 and 369. |
Provides a Seed7 top level menu entry which provides access to the commands. Here's some examples:
Screenshot | Description |
---|---|
Terminal menu 1 | Using the top menu to access Seed7 code browsing inside a terminal Emacs. |
Terminal menu 2 | The selecting the Seed7 item as a second step in the menu using a terminal Emacs. |
GUI Emacs menu | Using macOS GUI Emacs with iMenu to list the functions is the Seed7 file. Unlike Windows and most Linux desktops, the Emacs menu shows up inside the macOS top screen menu by default but it's also possible to make it show inside the Emacs frame as the next screen captures show. |
Navigation to structure menu | The menu can be opened inside the frame
explicitly with the menu-bar-open
command. Here it is showing the
navigation listing the structures
declared inside prg/bas.sd7 |
Comments menu | The comments-specific commands. |
Template insertion menu | The template insertion commands.
These can be expanded easily with
<TAB>
as described in the
Code Template Insertion
section. |
- Support Emacs imenu mode and Emacs Speedbar for:
- Seed7 procedures,
- Seed7 functions,
- Seed7 interfaces,
- Seed7 structures,
- Seed7 enums.
See the following example screenshots:
Screenshot | Description |
---|---|
Terminal Emacs Speedbar | Using Emacs Speedbar to navigate the Seed7/pgm directory, listing function, procedures, structures, etc... |
GUI Emacs Speedbar | Using macOS GUI Emacs with Speedbar in a separate GUI frame showing beside the local instance of the PEL Speedbar PDF. |
GUI Emacs menu | Using macOS GUI Emacs with iMenu to list the functions is the Seed7 file. Unlike Windows and most Linux desktops, the Emacs menu shows up inside the macOS top screen menu. |
Terminal menu 1 | Using the top menu to access Seed7 code browsing inside a terminal Emacs. |
Terminal menu 2 | The selecting the Seed7 item as a second step in the menu using a terminal Emacs. |
Terminal Ivy prompt | Instead of using the menu, using a prompt with completion driven by ivy to search and select Seed7 element. Shown inside a terminal Emacs. |
Code indentation is done automatically when the <tab>
key is pressed
from anywhere on the line, except when used to expand a callable parameter in most cases.
Automatic code indentation is also done when the <return>
key is pressed.
The auto-fill
mode is supported.
The following customizable user-option variables control Seed7 code indentation.
. | Variable | Purpose |
---|---|---|
. | seed7-auto-indent | Control whether auto-indentation of Seed7 code is active.
|
. | seed7-indent-width | Number of columns used for each indentation level of Seed7 code. Defaults to 2. |
. | indent-tabs-mode | Control whether Emacs inserts ASCII hard TAB characters when indenting. If set to nil Emacs will only use ASCII SPACE characters. If active (set to T or any non-nil value) Emacs will insert ASCII hard TAB character to fill indentation according to the number of columns of indentation required and the number of columns used to render a hard tab (as specified by tab-width). For Seed7 code, the convention is to avoid hard TAB characters in the code, therefore the indent-tab-mode should be turned off to prevent seed7-mode auto-indentation to insert hard TAB characters. Use the untabify command to replace all hard TAB characters in the buffer by the equivalent number of SPACE characters. |
. | tab-width | Controls the the column width of a hard TAB on display. |
Notes:
- One aspect of the auto indentation logic is that it checks (and extracts) the name of procedure and functions and the return type of the function. The auto-indentation will only work properly once these are identified. This acts as a reminder to fill in the missing parts.
- 🚧 As this code is still under early development please report any problem you may encounter.
Seed7 code templates are inserted at point when the <tab>
key is pressed
after one of the supported code identifier keywords under specific
constraints:
- When point is following one of the keywords from the first group and that is the only word on the current line, or
- when point is following one of the keywords of the second group and is
located just before a
)
character (with or without a space between point and the closing parenthesis. The second group holds keywords for argument declarations.
After successfully expanding the Seed7 code template, point is located at the
first location that must be filled. This location, and the following
locations that must be filled, are internally identified
by Emacs tempo markers. You can use the tempo-forward-mark
and
tempo-backward-mark
to move point to these markers. The seed7-mode
keyboard map binds the <backtab>
key to the tempo-forward-mark
command. So after expanding a code template, fill the first field and then
press <backtab>
to move point to the next field.
As mentioned above there are two groups of keywords, listed in the following tables.
First Group -- Statements:
Expand the following keywords when point is located just after any of these keywords, with the keyword being the only word on the current line.
Keyword | Expansion |
---|---|
inc | include statement |
const | constant declaration |
var | variable declaration |
. | |
proc | procedure declaration |
func | function declaration |
funcs | short function declaration |
. | |
enum | enum type declaration |
struct | struct type declaration |
. | |
case | case statement |
if | if statement |
ife | if statement with an else clause |
ifei | if statement with an elsif clause |
ifeie | if statement with an elsif and an else clause |
repeat | repeat - until statement |
while | while statement |
for | for statement |
foru | for-until statement |
fors | for-step statement |
fore | for-each statement |
foreu | for-each statement combined with an until condition |
forek | for-each-key statement |
foreku | for-each-key statement combined with an until condition |
fork | for-key statement |
forku | for-key statement combined with an until condition |
. | |
bl | Exception handler block |
gl | global - end global block. |
Second Group -- Argument Declarations
Expand the following keywords with <tab>
when point is located just after
any of these keywords and before the closing parenthesis of a parameter list.
Keyword | Expansion |
---|---|
in | Declaration of an in-parameter. |
inout | Declaration of an inout-parameter. |
invar | Declaration of an in-var-parameter. |
callbn | Declaration of a call-by-name parameter. |
ref | Declaration of a reference-parameter. |
val | Declaration of a value-parameter. |
Ref: | Abbrevs @ Emacs Manual |
---|---|
Ref: | Abbrev Concepts |
Ref: | Examining and Editing Abbrevs |
By default, the seed7-support-abbrev-mode user-option is on (non-nil). This makes seed7-mode support Seed7-specific abbreviations that can be automatically expanded when the abbrev-mode is active.
You can expand a set
of Seed7 keywords by typing their (system) abbreviation followed by a word-separating
character such as <space>
, <RET>` or ``;
and others.
All Seed7 abbreviations are short mnemonic character sequences that start with ;
.
Dynamically enable or disable the abbrev-mode
with the M-x abbrev-mode
command. List the abbreviations with M-x list-abbrevs
. You can create
other abbreviations and edit them with M-x edit-abbrevs
. You cannot
change the pre-defined Seed7 system abbreviations via the abbrev commands.
However you can change all Seed7 system abbreviations since the list is
customizable and defined by the seed7-abbreviations customizable user-option.
Of course you can also create your own abbreviations via the abbrev mode
commands to complement what is provided by seed7-mode.
While abbrev-mode is active, you can explicitly prevent expansion of the
keyword type C-q
after the keyword before any white-space or punctuation
character.
If you do not want to use Seed7-specific abbreviations, you can change the
customization of this user-variable with M-x customize-option RET
seed7-support-abbrev-mode
turning it off, changing the mode to another major
mode (such as fundamental-mode) and re-enabling the seed7-mode. If you Apply
and Save the customization, the setting will persist across Emacs sessions.
The list of default supported abbreviations is controlled by the seed7-abbreviations customizable user-option. You can modify the keyword or the expansion of any entry and add or delete entries these via customization. The new values are activated the next time a buffer starts the seed7-mode.
The default abbreviations are shown inside the 8 following tables:
- pragmas
- in-statement keywords
- in-middle statement keywords
- block clause keywords
- predefined types
- predefined constants
- predefined variables
- errinfo values
Abbreviation | Expansion |
---|---|
;de |
decls |
;in |
info |
;li |
library |
;msg |
message |
;na |
names |
;syn |
syntax |
;sys |
system |
;tr |
trace |
Meant to follow the is
keyword (but not imposed):
Abbreviation | Expansion |
---|---|
;fo |
forward |
;n |
new |
;u |
sub |
Others:
Abbreviation | Expansion |
---|---|
;no |
noop |
;ra |
raise |
;rt |
return |
Abbreviation | Expansion |
---|---|
;dt |
downto |
;exc |
exception |
;lo |
local |
;pa |
param |
;rg |
range |
;rs |
result |
;st |
step |
Abbreviation | Expansion |
---|---|
;ct |
catch |
;e |
else |
;ei |
elsif |
;o |
otherwise |
;w |
when |
Abbreviation | Expansion |
---|---|
;a |
array |
;bi |
bigInteger |
;br |
bigRational |
;b3 |
bin32 |
;b6 |
bin64 |
;bt |
bitset |
;bo |
boolean |
;bs |
bstring |
;ca |
category |
;c |
char |
;cf |
clib_file |
;co |
color |
;cx |
complex |
;db |
database |
;du |
duration |
;en |
enum |
;ex |
expr |
;fi |
file |
;fs |
fileSys |
;fl |
float |
;h |
hash |
;i |
integer |
;ob |
object |
;pro |
process |
;pr |
program |
;rat |
rational |
;rf |
reference |
;rfl |
ref_list |
;s |
set |
;sq |
sqlStatement |
;sti |
string |
;stu |
struct |
;tx |
text |
;ti |
time |
;ty |
type |
;v |
void |
;pw |
PRIMITIVE_WINDOW |
Abbreviation | Expansion |
---|---|
;em |
empty |
;f |
FALSE |
;inf |
Infinity |
;t |
TRUE |
Abbreviation | Expansion |
---|---|
;ck |
CONSOLE_KEYBOARD |
;gk |
GRAPH_KEYBOARD |
;kb |
KEYBOARD |
;sc |
STD_CONSOLE |
;se |
STD_ERR |
;si |
STD_IN |
;sn |
STD_NULL |
;so |
STD_OUT |
Abbreviation | Expansion |
---|---|
;ok |
OKAY_NO_ERROR |
;ae |
ACTION_ERROR |
;ce |
COPY_ERROR |
;cre |
CREATE_ERROR |
;dbe |
DATABASE_ERROR |
;dse |
DESTROY_ERROR |
;fe |
FILE_ERROR |
;ge |
GRAPHIC_ERROR |
;ie |
INDEX_ERROR |
;ine |
IN_ERROR |
;me |
MEMORY_ERROR |
;ne |
NUMERIC_ERROR |
;oe |
OVERFLOW_ERROR |
;re |
RANGE_ERROR |
Some of the commands have a built-in key binding in the seed7-key-map but not all of them. The PEL Seed7 support provides more key bindings using function keys.
. | Function | Key Binding | Description |
---|---|---|---|
. | seed7-beg-of-defun | C-M-a |
Move point backward to beginning of function or procedure. With optional repeat argument. |
. | seed7-end-of-defun | C-M-e |
Move point backward to beginning of function or procedure. With optional repeat argument. |
. | seed7-beg-of-next-defun | C-c C-n |
Move point forward to beginning of next function or procedure. With optional repeat argument. |
. | seed7-to-block-forward | C-c C-e |
Move point forward to the end line of the matching statement:
If none is found move to the end of the function or procedure. |
. | seed7-to-block-backward | C-c C-a |
Move point backward to the beginning line of the matching block or statement (listed above). |
The seed7-mode supports Emacs xref framework and implement an xref-backend for Seed7 code using the supplied s7xref.sd7 Seed7 program.
The seed7-xref user option, which defaults to s7xref
identifies the
program that should be used to parse the visited Seed7 file and extract
information about all identifiers and operators used by the Seed7n program or
library file. See the seed7-xref docstring for more information.
Once this is properly setup, you can use the following xref commands to navigate in Seed7 code.
. | Function | Key Binding | Description |
---|---|---|---|
. | xref-find-definitions | M-. |
Find the definition of the identifier at point. Move point to it if there is only one candidate. If there are several candidates, display the list with the currently active xref front-end. You can then select the appropriate candidate to jump to its code. |
. | xref-go-back | M-, |
Go back to the previous position in xref history. |
The current implementation does not yet display the signature of the identified candidates. This will be done soon.
There are other xref framework commands. They are not yet implemented to support Seed7. This will also be done.
. | Function | Key Binding | Description |
---|---|---|---|
. | seed7-mark-defun | C-M-h |
Mark the current function or procedure. With point between two; mark the next one. |
. | Function | Key Binding | Description |
---|---|---|---|
. | seed7-compile | Static check Seed7 file visited in current buffer. With optional argument compile it. All resulting warning or errors are shown in a compile-mode buffer. |
- The static checking and compilation commands are identified in customizable user options.
- The static checking defaults to
s7check
and the compilation tos7c
. - To perform static checking of Seed7 files, compile the s7check.sd7 part of seed7 program examples and use the generated executable.
. | Function | Key Binding | Description |
---|---|---|---|
. | seed7-toggle-comment-style | C-c ; |
Toggle between comments to line-end and block comments.
|
The seed7-mode is compatible with:
- Emacs comment-dwim command. The recommended key binding for it is
M-;
- Emacs which-function-mode, when active shows the name of the current Seed7 function or procedure in the mode line. It also works with Seed7 actions and forward declarations.
- The iedit package that allows selecting variables inside a specific block, function or procedure.
- The expand-region package to quickly select the current word, block, function/procedure.
- Drew Adam's hide-comnt package which provides the hide/show-comments-toggle command to hide or show all comments.
- The smart-dash-mode is quite useful for typing those pesky underscore characters. With this minor mode active just type a dash (easier type than underscore on most keyboards) and it will insert a underscore inside words or symbols and a dash otherwise.
More commands will be implemented.
Reference: | The Emacs Initialization File |
---|
Emacs can and will use a user initialization file, init.el if it finds one.
- Emacs looks for the init.el file inside the directory identified by
the user-emacs-directory variable, one of many variable controls Emacs behaviour.
- Emacs looks for the following files, in the following order by default:
~/.emacs
~/.emacs.el
~/.emacs.d/init.el
~.config/emacs/init.el
- Emacs looks for the following files, in the following order by default:
- Once started the name of the Emacs init file is stored inside the value of the user-init-file variable.
- It also stores the name of the Emacs directory inside the user-emacs-directory variable.
Inside Emacs you can see the current value of the above variables by typing the C-h o
followed by the name of the variable. For example:
- Type
C-h o user-emacs-directory RET
; that will open a buffer describing the purpose of this variable and show it's current value. It also has a link to the Emacs Lisp code that defines it (which is part of Emacs and you should not modify). - Type
C-h o user-init-file
to show the value of this variable.
The user-emacs-directory identifies the directory where Emacs looks for the init.el file. In Unix-like OS installations it is often set to "~/.emacs.d/". Under Windows it will be located somewhere else.
Changing from ~/.emacs to ~/.emacs.d/init.el
If you have used Emacs default you may be using the ~/.emacs
file for your
Emacs init file.
- Using a complete directory to hold your Emacs initialization file and other Emacs related files, like the downloaded packages, your spelling dictionaries, your persistent customization, etc...
- To get Emacs use the
~/.emacs.d/init.el
file instead:- Create the
~/.emacs.d
directory, - Move your
~/.emacs
or~/.emacs.el
file to~/.emacs.d/init.el
. - When you restart Emacs, check the value of user-emacs-directory and user-init-file; they should reflect the new location.
- Create the
Make sure your Emacs initialization file is stored inside the ~/.emacs.d
directory and is ~/.emacs.d/init.el
. If this is not the case read the
previous section. Once this is done proceed with the following:
1: Create the utils sub-directory to store stand-alone utilities Emacs lisp files like seed7-mode.el. That directory should be located inside the directory identified by Emacs user-emacs-directory:
- Under Unix-like OS, for example, you would normally create the ~/.emacs.d/utils directory.
2: Create the init.el file if it does not exists:
- Emacs user-emacs-directory identifies the directory where the init.el
file should be located.
- Under Unix-like OS, the file is normally ~/.emacs.d/init.el
- Create the file if it does not already exist.
- Emacs user-emacs-directory identifies the directory where the init.el
file should be located.
3: Update init.el: write code to find files in utils and auto-load seed7-mode
- Inside your init.el file, write the following code:
;;; -*-lexical-binding: t; -*- (push (expand-file-name "utils" user-emacs-directory) load-path) (autoload 'seed7-mode "seed7-mode" nil :interactive) (add-to-list 'auto-mode-alist '("\\.s\\(d7\\|7i\\)\\'" . seed7-mode))
- The first line activates lexical-binding. It must be the very first line of the file.
- The other lines can be anywhere, but must be executed (in case you have some conditional logic).
4: Download seed7_mode.el file and copy it in the utils directory
- The utils directory is the one you created above.
5: Byte compile seed7-mode.el
- Open Emacs and edit (visit) the seed7-mode.el file located in your utils directory.
- Byte compile it by typing the following command: M-x emacs-lisp-byte-compile-and-load
Byte compiling is not absolutely necessary but it will verify that everything is ok inside the file and will also speed up Emacs startup. Just remember to byte-compile that file every time you modify it, otherwise Emacs will complain that it's using a byte-compile file that is older than the source file.
To update to a later revision,
- Erase the seed7-mode.el and seed7-mode.elc files from the utils directory where you stored them.
- Download the new revision in the same directory.
- Byte-compile the new file as described in the previous section.
You can also use my PEL Emacs project which deals with all installation and control details of several packages including this seed7-mode.
- First install PEL as described in the PEL manual
- To activate the installation and activation of the seed7-mode package you
must set the PEL user-option for Seed7: pel-use-seed7 to the value
t
(which is one of the possible true values in Emacs Lisp).- Once PEL is installed, use the
C-h o pel-use-seed7 RET
key sequence to open the customization buffer to set this user option. Then close Emacs and restart it. PEL will download and install the file in your~/.emacs.d/utils
directory. - Open a Seed7 file, PEL provides extra command key bindings for Seed7 under
the
F12
key prefix.- See the PEL Seed7 PDF for more information about PEL Seed7 Support.
- The PEL Index PDF has links to several other PDF files on various Emacs-specific topics.
- Once PEL is installed, use the
With PEL, updating is a little simpler:
just delete your ~/.emacs.d/utils/seed7-mode.*
files and restart Emacs;
it will download the new version and byte-compile it.
Once this code is stable I will add the logic to make it a proper Emacs package and probably will include it under MELPA. But the code is far from being ready for that.
Any help, questions, suggestions are welcome!