1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-28 05:00:59 +01:00

22014: argument-base, insert-unicode-char

This commit is contained in:
Peter Stephenson 2005-11-24 10:25:33 +00:00
parent 325a7c0417
commit e66af50a98
9 changed files with 133 additions and 16 deletions

View file

@ -1,3 +1,12 @@
2005-11-24 Peter Stephenson <pws@csr.com>
* 22014: Doc/Zsh/Contrib.yo, Doc/Zsh/zle.yo,
Functions/Zle/.distfiles, Functions/Zle/insert-unicode-char,
Src/Zle/iwidgets.list, Src/Zle/zle.h, Src/Zle/zle_main.c,
Src/Zle/zle_misc.c: internal widget argument-base sets
numeric base for next prefix argument, widget insert-unicode-char
uses this to insert Unicode character by \U........
2005-11-23 Peter Stephenson <pws@csr.com> 2005-11-23 Peter Stephenson <pws@csr.com>
* 22013: INSTALL, NEWS, Completion/compinstall, * 22013: INSTALL, NEWS, Completion/compinstall,

View file

@ -693,6 +693,9 @@ The function may be run outside zle in which case it prints the character
(together with a newline) to standard output. Input is still read from (together with a newline) to standard output. Input is still read from
keystrokes. keystrokes.
See tt(insert-unicode-char) for an alternative way of inserting Unicode
characters using their hexadecimal character number.
The set of accented characters is reasonably complete up to Unicode The set of accented characters is reasonably complete up to Unicode
character U+0180, the set of special characters less so. However, it it character U+0180, the set of special characters less so. However, it it
is very sporadic from that point. Adding new characters is easy, is very sporadic from that point. Adding new characters is easy,
@ -917,6 +920,17 @@ narrow-to-region -p $'Editing restricted region\n' \
zle recursive-edit zle recursive-edit
narrow-to-region -R state) narrow-to-region -R state)
) )
tindex(insert-unicode-char)
item(tt(insert-unicode-char))(
When first executed, the user inputs a set of hexadecimal digits.
This is terminated with another call to tt(insert-unicode-char).
The digits are then turned into the corresponding Unicode character.
For example, if the widget is bound to tt(^XU), the character sequence
`tt(^XU 4 c ^XU)' inserts tt(L) (Unicode U+004c).
See tt(insert-composed-char) for a way of inserting characters
using a two-character mnemonic.
)
tindex(predict-on) tindex(predict-on)
tindex(predict-off) tindex(predict-off)
item(tt(predict-on))( item(tt(predict-on))(

View file

@ -1519,6 +1519,23 @@ Inside a widget function, if passed an argument, i.e. `tt(zle
universal-argument) var(num)', the numerical argument will be set to universal-argument) var(num)', the numerical argument will be set to
var(num); this is equivalent to `tt(NUMERIC=)var(num)'. var(num); this is equivalent to `tt(NUMERIC=)var(num)'.
) )
tindex(argument-base)
item(tt(argument-base))(
Use the existing numeric argument as a numeric base, which must be in the
range 2 to 36 inclusive. Subsequent use of tt(digit-argument) and
tt(universal-argument) will input a new prefix in the given base.
The usual hexadecimal convention is used: the letter tt(a) or tt(A)
corresponds to 10, and so on. Arguments in bases requiring digits from 10
upwards are more conveniently input with tt(universal-argument), since
tt(ESC-a) etc. are not usually bound to tt(digit-argument).
The function can be used with a command argument inside a user-defined
widget. The following code sets the base to 16 and lets the user input a
hexadecimal argument until a key out of the digit range is typed:
example(zle argument-base 16
zle universal-argument)
)
enditem() enditem()
texinode(Completion)(Miscellaneous)(Arguments)(Zle Widgets) texinode(Completion)(Miscellaneous)(Arguments)(Zle Widgets)
subsect(Completion) subsect(Completion)

View file

@ -9,6 +9,7 @@ edit-command-line forward-word-match
history-pattern-search history-search-end history-pattern-search history-search-end
incarg incremental-complete-word incarg incremental-complete-word
insert-composed-char insert-files insert-composed-char insert-files
insert-unicode-char
keeper kill-word-match keeper kill-word-match
match-words-by-style narrow-to-region match-words-by-style narrow-to-region
narrow-to-region-invisible predict-on narrow-to-region-invisible predict-on

View file

@ -0,0 +1,17 @@
# Make hex integers appear as 0x...
setopt localoptions cbases
if [[ $LASTWIDGET = insert-unicode-char ]]; then
# Second call; we should have a usable prefix.
# If we don't, give up.
(( ${+NUMERIC} )) || return 1
# Convert it back to hex, padded with zeroes to 8 digits plus the 0x...
local -i 16 -Z 10 arg=$NUMERIC
# ...and use print to turn this into a Unicode character.
LBUFFER+="$(print -n "\U${arg##0x}")"
else
# Set the base to 16...
zle argument-base 16
# ...wait for user to type hex keys then call this widget again.
zle universal-argument
fi

View file

@ -13,6 +13,7 @@
"accept-and-menu-complete", acceptandmenucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX "accept-and-menu-complete", acceptandmenucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
"accept-line", acceptline, 0 "accept-line", acceptline, 0
"accept-line-and-down-history", acceptlineanddownhistory, 0 "accept-line-and-down-history", acceptlineanddownhistory, 0
"argument-base", argumentbase, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
"backward-char", backwardchar, 0 "backward-char", backwardchar, 0
"backward-delete-char", backwarddeletechar, ZLE_KEEPSUFFIX "backward-delete-char", backwarddeletechar, ZLE_KEEPSUFFIX
"backward-delete-word", backwarddeleteword, ZLE_KEEPSUFFIX "backward-delete-word", backwarddeleteword, ZLE_KEEPSUFFIX

View file

@ -205,6 +205,7 @@ struct modifier {
int mult; /* repeat count */ int mult; /* repeat count */
int tmult; /* repeat count actually being edited */ int tmult; /* repeat count actually being edited */
int vibuf; /* vi cut buffer */ int vibuf; /* vi cut buffer */
int base; /* numeric base for digit arguments (usually 10) */
}; };
#define MOD_MULT (1<<0) /* a repeat count has been selected */ #define MOD_MULT (1<<0) /* a repeat count has been selected */

View file

@ -1153,6 +1153,7 @@ initmodifier(struct modifier *mp)
mp->mult = 1; mp->mult = 1;
mp->tmult = 1; mp->tmult = 1;
mp->vibuf = 0; mp->vibuf = 0;
mp->base = 10;
} }
/* Reset command modifiers, unless the command just executed was a prefix. * /* Reset command modifiers, unless the command just executed was a prefix. *

View file

@ -518,12 +518,9 @@ quotedinsert(char **args)
return selfinsert(args); return selfinsert(args);
} }
/**/ static int
int parsedigit(int inkey)
digitargument(UNUSED(char **args))
{ {
int sign = (zmult < 0) ? -1 : 1;
#ifdef MULTIBYTE_SUPPORT #ifdef MULTIBYTE_SUPPORT
/* /*
* It's too dangerous to allow metafied input. See * It's too dangerous to allow metafied input. See
@ -531,23 +528,48 @@ digitargument(UNUSED(char **args))
* of digits. We are assuming ASCII is a subset of the multibyte * of digits. We are assuming ASCII is a subset of the multibyte
* encoding. * encoding.
*/ */
if (!idigit(lastchar))
return 1;
#else #else
/* allow metafied as well as ordinary digits */ /* allow metafied as well as ordinary digits */
if (!idigit(lastchar & 0x7f)) inkey &= 0x7f;
return 1;
#endif #endif
/* remember lastchar is not a wide character */
if (zmod.base > 10)
{
if (lastchar >= 'a' && lastchar < 'a' + zmod.base - 10)
return lastchar - 'a' + 10;
else if (lastchar >= 'A' && lastchar < 'A' + zmod.base - 10)
return lastchar - 'A' + 10;
else if (idigit(lastchar))
return lastchar - '0';
else
return -1;
}
else if (lastchar >= '0' && lastchar < '0' + zmod.base)
return lastchar - '0';
else
return -1;
}
/**/
int
digitargument(UNUSED(char **args))
{
int sign = (zmult < 0) ? -1 : 1;
int newdigit = parsedigit(lastchar);
if (newdigit < 0)
return 1;
if (!(zmod.flags & MOD_TMULT)) if (!(zmod.flags & MOD_TMULT))
zmod.tmult = 0; zmod.tmult = 0;
if (zmod.flags & MOD_NEG) { if (zmod.flags & MOD_NEG) {
/* If we just had a negative argument, this is the digit, * /* If we just had a negative argument, this is the digit, *
* rather than the -1 assumed by negargument() */ * rather than the -1 assumed by negargument() */
zmod.tmult = sign * (lastchar & 0xf); zmod.tmult = sign * newdigit;
zmod.flags &= ~MOD_NEG; zmod.flags &= ~MOD_NEG;
} else } else
zmod.tmult = zmod.tmult * 10 + sign * (lastchar & 0xf); zmod.tmult = zmod.tmult * zmod.base + sign * newdigit;
zmod.flags |= MOD_TMULT; zmod.flags |= MOD_TMULT;
prefixflag = 1; prefixflag = 1;
return 0; return 0;
@ -594,12 +616,16 @@ universalargument(char **args)
if (gotk == '-' && !digcnt) { if (gotk == '-' && !digcnt) {
minus = -1; minus = -1;
digcnt++; digcnt++;
} else if (idigit(gotk)) {
pref = pref * 10 + (gotk & 0xf);
digcnt++;
} else { } else {
ungetbyte(gotk); int newdigit = parsedigit(gotk);
break;
if (newdigit >= 0) {
pref = pref * zmod.base + newdigit;
digcnt++;
} else {
ungetbyte(gotk);
break;
}
} }
} }
if (digcnt) if (digcnt)
@ -611,6 +637,36 @@ universalargument(char **args)
return 0; return 0;
} }
/* Set the base for a digit argument. */
/**/
int
argumentbase(char **args)
{
int multbase;
if (*args)
multbase = (int)zstrtol(*args, NULL, 0);
else
multbase = zmod.mult;
if (multbase < 2 || multbase > ('9' - '0' + 1) + ('z' - 'a' + 1))
return 1;
zmod.base = multbase;
/* reset modifier, apart from base... */
zmod.flags = 0;
zmod.mult = 1;
zmod.tmult = 1;
zmod.vibuf = 0;
/* ...but indicate we are still operating on a prefix argument. */
prefixflag = 1;
return 0;
}
/**/ /**/
int int
copyprevword(UNUSED(char **args)) copyprevword(UNUSED(char **args))