Skip to content

Commit

Permalink
emacs: Fix ESC [ <letter> macros
Browse files Browse the repository at this point in the history
In the friendly manual page, we find the following under "Emacs
Editing Mode" (note that M- stands for the historic 'meta'
modifier key but actually means ESC on all current systems):

       M-[letter Soft-key - Your alias list is searched for an
                 alias by the name __letter and if an alias of this
                 name is defined, its value will be inserted on the
                 input queue.  This can be used to program function
                 keys on many terminals.

The bug: unlike the M-letter variant, the above simply does not
work. For example, if an alias __x is defined, ESC [ x just beeps.

Analysis: In this case, ed_macro() in completion.c is called from
escape() in emacs.c with i set to '_' (emacs.c lines 1179, 1184).
The ed_macro() code in completion.c makes the bug clear:

604:	/* undocumented feature, macros of the form
	   <ESC>[c evoke alias __c */
605:	if(i=='_')
606:		ep->e_macro[2] = ed_getchar(ep,1);
607:	else
608:		ep->e_macro[2] = 0;
609:	if (isalnum(i)&&(np=nv_search(ep->e_macro,sh.alias_tree,0))
	&&(out=nv_getval(np)))
		//...handle the macro

The bug is on line 606. If i is '_' (so we have 'ESC [' in emacs),
it gets another character, but it does not update i, so that
isalnum(i) on line 609 checks if a constant value '_' is
alphanumeric, which is always false. The fix is obvious: on line
606, set i to the value returned by ed_getchar().

Tracing this bug in historic source code, I determined it was there
as early as ksh88, when this code was introduced! Yet, at some
point, someone seems to have thought it was a good idea to document
this in the manual page (while forgetting to edit the comment that
says the feature is undocumented). So either they used a fixed
version but the fix was never committed to AT&T's version control
system, or they documented it without ever trying it.

The closed-source ksh88 that shipped with Solaris 10 (2005), as
/usr/bin/ksh and /usr/xpg4/bin/sh, has this feature working. So it
did get fixed somewhere at some point, but the fix never made it
into any publicly available source code -- until now.
  • Loading branch information
McDutchie committed Dec 22, 2024
1 parent 9172b73 commit cc5668c
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 3 deletions.
6 changes: 6 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ This documents significant changes in the dev branch of ksh 93u+m.
For full details, see the git log at: https://github.com/ksh93/ksh
Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.

2024-12-22:

- In the emacs/gmacs line editor, the ESC [ <letter> macro feature, which is
documented to input the value of the alias __<letter>, now actually works.
A decades-old bug in internal variable handling rendered it inoperative.

2024-12-21:

- Fixed a bug in the emacs/gmacs line editor where a command repeat count
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/ksh93/edit/completion.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,9 +601,9 @@ int ed_macro(Edit_t *ep, int i)
genchar buff[LOOKAHEAD+1];
if(i != '@')
ep->e_macro[1] = i;
/* undocumented feature, macros of the form <ESC>[c evoke alias __c */
/* macros of the form <ESC>[c evoke alias __c */
if(i=='_')
ep->e_macro[2] = ed_getchar(ep,1);
ep->e_macro[2] = i = ed_getchar(ep,1);
else
ep->e_macro[2] = 0;
if (isalnum(i)&&(np=nv_search(ep->e_macro,sh.alias_tree,0))&&(out=nv_getval(np)))
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <ast_release.h>
#include "git.h"

#define SH_RELEASE_DATE "2024-12-21" /* must be in this format for $((.sh.version)) */
#define SH_RELEASE_DATE "2024-12-22" /* must be in this format for $((.sh.version)) */
/*
* This comment keeps SH_RELEASE_DATE a few lines away from SH_RELEASE_SVER to avoid
* merge conflicts when cherry-picking dev branch commits onto a release branch.
Expand Down

0 comments on commit cc5668c

Please sign in to comment.