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:
parent
325a7c0417
commit
e66af50a98
9 changed files with 133 additions and 16 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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))(
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
17
Functions/Zle/insert-unicode-char
Normal file
17
Functions/Zle/insert-unicode-char
Normal 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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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. *
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue