The short answer is no, there is no way to submit a code block in SAS using a single keystroke.
Let me explain why.
A region of text is determined by two aspects of the cursor, point and mark. Point is the current position of the cursor relative to the start of the file. Mark is a variable containing a possible position of the cursor. Region is the text between the point and the mark.
Submitting a code block can be viewed as a two step process:
- Select a region.
- Submit the selected region to the compiler.
To bind this process to a single key requires being able to select a region using code. The process would go something as follows.
- Create a command-style macro which first selects a region, probably
using the
FIND
command to locate the end of a block (searching for
a carriage return, line feed, "run;" statement, etc.).
- Set the mark.
- Move the point to the start of the region.
- Select the region.
- Execute the region using the
SUBMIT
, GSUBMIT
, or END
commands.
- Compile the macro and bind it to a function key using the
KEYS
menu.
There are two problems with this.
First, there is no way to set the mark in the Enhanced Editor (EE) using code. Without a mark, a region cannot be defined and the process described above fails. The MARK
command referred to by @guest applies only to the Program Editor. To see this, try pressing Ctrl+M
or issuing the MARK
command from the command line in the EE. You will receive the following message:
ERROR: The MARK command is not supported by the Enhanced Editor.
Second, it is unclear how to select a region using code. The documentation for all of this is disparate and incomplete. Without a way to set the mark, I did not spend too much time investigating how to select.
Tantilizingly, however, is the ability to set the mark in the EE using a keyboard macro. How or why this differs from the MARK
command is beyond me. It is also possible to select a region. While a seeming lack of code commands to set mark and select prevents us from creating a single keystroke submit, keyboard macros enable us to develop a two keystoke approach.
Submitting Code
Under Tools > Options > Preferences > Results
I have checked "View results as they are generated". This forces the results window to take the foreground after code is submitted.
In the KEYS screen, I have the following:
Key Definition
--- ----------
F3 clear log; end; log; wpgm;
F4 clear log; end;
When I press F3
,
- the log is cleared (
clear log;
)
- the selected region is submitted (
end;
)
- the log window is selected (
log;
)
- the most recent program window is selected (
wpgm;
)
This means the results are not immediately displayed to me, depsite the Preferences setting set above. If I want to see the results, I instead press F4
. This clears the log and submits the code, but does not select any other windows.
To open the KEYS screen, either type KEYS
into the command line in the top left corner of the EE interface or submit dm 'KEYS';
. Changes to the KEYS menu must first be saved before they take effect.
Keyboard Macros
For instructions on creating Keyboard Macros.
Select a Single Line of Code
Create a keyboard macro which does the following.
- Move cursor to beginning of line
- Extend selection to end of line
I have this bound to Ctrl+Enter
. I may then execute a line of code using Ctrl+Enter > F3
.
Manual Code Selecting/Folding
This approach requires collapsible code sections be enabled. To do this, goto Tools > Options > Enhanced Editor > General
and check the 'Collapse code sections' check boxes.
Within the Keyboad Macros,
- Assign a command to 'Mark current position' (
Ctrl+Space
).
- Assign 'Toggle expand current line' (
Alt+P
)
- Assign 'Extend selection from mark' (
Alt+L
)
Once this has been done, place your cursor at the end of a folding block, such as to the right of the semi-colon in a run;
statment. Execute the sequence:
- Mark current position
- Toggle expand current line
- Toggle expand current line
- Extend selection from mark
A side effect of 'Toggle expand current line' is that when a code block is folded, the point moves to the beginning of the folding block. Since we set the mark at the end of the block, this allows us to define and select a region.
In terms of the keys I have assigned, this is Ctrl+Space > Alt+P > Alt+P > Alt+L
. Note that Alt
may remain pressed during the last three steps of this sequence so that it becomes Ctrl+Space > Alt (P-P-L)
. Therefore, to manually submit a folding block using the keyboard, place the cursor at the end of a block and issue Ctrl+Space > Alt (P-P-L) > F3
.
Automatic Code Selection/Folding
This automatic process relies on a side-effect of the 'Toggle expand current line' keyboard macro which is described in the previous section. The manual code folding/selecting process is automated using the search function.
The overall process can be seen in two parts:
- Find the end of a folding block.
- Select the folding block.
Folding blocks are defined by the following.
Beginning of a block:
proc <name/options> ;
data <name/options> ;
%macro <name/options> ;
End of a block:
The semi-colon toggles the block boundary in the EE. The EE naively looks for keyword pairs. So, even though it's nonsense to the compiler, it is possible to define a data-%mend
folding block.
The following gives the commands which need to be issued by a keyboard macro for each part.
I. Finding the end-of-block statement
- Move cursor to beginning of line (This ensures that the folding block boundary is included in the forward search set in Step 3).
- Reset search.
- Set search direction to forward.
- Set search to case insensitive.
- Set search to ignore text in comments.
- Set search to code.
- Turn on regular expression mode for searching.
- Set search to string
\<[rqm][ue][ni][dt]*\>;
- Find next occurance using the current settings.
- Move cursor right (When an end-of-block statement is found, the entire word is highlighted. Moving the cursor to the right places the point at the end of the folding block, to the right of the semi-colon.).
II. Selecting the folding block
- Mark current position.
- Toggle expand current line. (Folds the section with the side-effect of moving the cursor to the start of the block).
- Toggle expand current line. (Unfolds the selection to allow highlighting. The cursor remains at the beginning of the block).
- Extend selection to mark.
I have this sequence bound to Ctrl+Shift+Enter
.
Note that the search settings altered in the macro do not extend globally. That is, if you hit Ctrl+F
and have 'Regular expression search' unchecked, if you again open Ctrl+F
after running this macro, you will see that 'Regular expression search' remains unchecked.
Let me explain the regular expression in Step 8 because it is not immediately obvious.
The Ctrl+F
dialog does not use Perl Regular Expressions. It uses something else, probably whatever regex syntax came before Perl was integreated into SAS. To see what options are available, click on the arrow beside the "Find text:" text box in the Find dialog. The options we use are given below:
\<
matches the beginning of a word
\>
matches the end of a word
[]
matches a set of characters (via exclusive OR)
*
forces 0 or more occurances of the preceeding character(s)
The regular expression \<[rqm][ue][ni][dt]*\>;
means that the word must start with r
, q
, or m
. The second character can only be u
or e
. The third character can only be n
or i
. If a fourth character exists, it must either be d
or t
. The last character must be ;
. Therefore, only the keywords run;
, quit;
and mend;
will be found. Words containg full or partial matches, such as ammend
or treatment
, are skipped.
Disadvantages to this approach
- Keywords other than
run;
, quit;
and mend;
are not supported.
- Folding blocks inside folding blocks are not supported. This method is not 'smart' in that it cannot discern which keyword pairs define the outer block.
- People who like to put the name of their macro in the
mend
statement are not supported. Since the regex expression requires a semi-colon at the end, a statement of the form %mend MacroName;
will be skipped over.
Based on months of research, this appears to be as complete a solution as can be developed. The lynch pin(s) needed are a code based ability to set mark and to select a region within the Enhanced Editor. If anyone knows of a way to do this, please let others know so that someone may implement the single-key-submit process outlined in the first part of this answer.