command-wait(2)command-wait - Conditional wait command
n command-wait
When a positive argument n is given command-wait waits for n milliseconds before returning, this wait cannot be interrupted. If a negative argument is given, command-wait waits for -n milliseconds but the command will return if the user interrupts with any input activity (i.e. presses a key).
When no argument or an argument of 0 is given command-wait waits until either the calling command's .wait command variable is undefined or it is set to false (0). When no argument is given events such as user input, screen updates etc. are still processed, this interface is best used when a main macro must wait and process input until an exit criteria has been met, the user input is best processed by setting the $buffer-input(5) variable to a second macro. The macro gdiff(3) uses this command in this way, also see a comprehensive example below.
When no argument is given user input and screen update events are ignored, this is typically used when MicroEmacs is used in pipe mode, see option -p of me(1), see the example below.
The following macro code will display a message on the screen for a fixed 5 seconds:
16 screen-poke 10 10 0 "Hello World!" 5000 command-wait
Similarly the following macro code will display a message for up to 5 seconds or till the user presses a key:
16 screen-poke 10 10 0 "Hello World!" -5000 command-wait
The following example shows how command-wait can be used to run a system process making MicroEmacs wait until the process has completed before continuing, yet giving feedback from the process to the user and allowing the user to kill the launched process. The process run is a recursive directory listing which will take a long time and give a lot of feed back, to kill the process with a prompt use delete-buffer (bound to 'C-x k') or use abort-command (bound to 'C-g') to kill immediately:
0 define-macro test-ipipe-macro ; add extra macro code to process output here !if ¬ @# ; the process has finished set-variable .test.wait 0 !endif !emacro 0 define-macro test-input-macro !if &seq @cck "redraw" @# screen-update !return !elif &seq @cck "callback" !force execute-named-command @cc !return !elif &seq @cck "idle-pick" !abort !elif &seq @cc "delete-buffer" !force !force set-variable #l0 @mc1 "Abort test [y/n]? " "nNyY" !if &and &iseq #l0 "y" .test.wait !force ipipe-kill !endif !elif &seq @cc "abort-command" !force ipipe-kill set-variable .test.wait 0 !endif !emacro define-macro test set-variable #l0 &con &band $system 0x100 "dir /s c:\\" "ls -R /" set-variable .wait 1 !force !force !force 0x82 ipipe-shell-command #l0 "*test*" test-ipipe-macro set-variable #l2 $status !if &band #l1 1 !force 0 delete-buffer "*cc-cmdline*" !endif find-buffer "*test*" set-variable $buffer-input test-input-macro !force !force !force command-wait set-variable $buffer-input "" ml-write "[test complete]" !emacro
The following macro code demonstrates how MicroEmacs can be used as a command-line tool, piping the output of another sub-process as it goes. In this example MicroEmacs executes a system directory listing command and prints the output to stdout using ml-write.
ml-write "Loading pipetest.emf" define-macro pipetest-ipipe !if ¬ @# end-of-buffer !else goto-alpha-mark "I" !endif ml-write &spr "In pipetest-ipipe %d %d %d" @# .line $window-line set-variable #l0 $window-line set-variable $window-line .line !while &les $window-line #l0 -1 ml-write @wl forward-line !done set-variable .line $window-line !if ¬ @# -2 ml-write "Process finished" set-variable .start-up.wait 0 !endif !emacro define-macro start-up ml-write "Got into start-up" set-variable .wait 1 set-variable .pipetest-ipipe.line 1 set-variable #l0 &con &band $system 0x100 "dir" "ls -l" -2 ml-write &cat "About to execute: " #l0 0xc0 ipipe-shell-command #l0 "*test*" pipetest-ipipe 0 command-wait ml-write "start-up continues" exit-emacs !emacro ml-write "Loading pipetest.emf complete"
To run this example, save the above macro code to pipetest.emf and then run:
me -n -p @pipetest.emf
Use the -P option for additional debug lines, printed to stderr. Windows users must use a console capable version of MicroEmacs, i.e. mec32.exe or mecw32.exe.
When the given wait time is smail the system's clock frequency can play a large part in the accuracy, for example on Windows the documented smallest time for SetTimer(3) is 10 milisconds (see USER_TIMER_MINIMUM) but in practice tends to be more like 16ms. The following code can be run to test the granularity of a system:
set-variable #g0 $unix-time 1 command-wait set-variable #g1 $unix-time 1 command-wait set-variable #g2 $unix-time 1 command-wait set-variable #g3 $unix-time 1 command-wait set-variable #g4 $unix-time list-variables
The values of #g0 to #g5 should increase by just over 0.001 (1ms), any more indicates a limitation of the system clock. This issue can be demonstrated by the following example which attempts to create a stable 'frame-rate' by allowing for the time taken by the code on each loop, the desired frequency can be adjusted by the changing the first variable:
; change the following variable to change the target delay (in ms) set-variable #l9 100 set-variable #l8 0 set-variable #l7 $unix-time set-variable #l1 -1 set-variable #l2 0 !repeat set-variable #l0 $unix-time ; Do work here... ml-write &spr "Loop: %4d %s" &inc #l1 1 &mid #l0 7 6 set-variable #l8 &add #l8 #l2 ; This gets the current time and removes the time at the start of our loop work, this is removed from our target frame-rate !iif &les &set #l2 &sub #l9 &fmu 1000 &fsub $unix-time #l0 1 set-variable #l2 1 #l2 command-wait !until &equ #l1 100 set-variable #l6 $unix-time set-variable #l8 &add #l8 #l2 ml-write &spr "Result: %d iterations took %.3fsec, average time %.2fms, average value for command-wait %.2f" #l1 &fsub #l6 #l7 &fmul 1000 &fdiv &fsub #l6 #l7 #l1 &fdiv #l8 #l1
When the desired frequency is large or the system clock frequency is large this code is accurate, but if the clock frequency is, say, 16ms then a desired frequency of 20ms will typically have a large 12ms error caused by the system clock (command-wait will end up waiting 2 times 16ms on each loop). If accuracy is required, use an appropriate OS, such as any UNIX system.
the use of create-callback(2) intead of command-wait typically creates a better user experience as it allows the system to continue to functioning normally while waiting for the next loop.
(c) Copyright JASSPA 2025
Last Modified: 2025/09/09
Generated On: 2025/09/29