summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2005-11-24 10:25:33 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2005-11-24 10:25:33 +0000
commite66af50a984b9b693fd6bbbf5f806612cdd03b66 (patch)
treef00e013b62fceea6f1eded9f78f846781b983613
parent325a7c041715f7602ad55161cf15e14b24f97b97 (diff)
downloadzsh-e66af50a984b9b693fd6bbbf5f806612cdd03b66.tar.gz
zsh-e66af50a984b9b693fd6bbbf5f806612cdd03b66.zip
22014: argument-base, insert-unicode-char
-rw-r--r--ChangeLog9
-rw-r--r--Doc/Zsh/contrib.yo14
-rw-r--r--Doc/Zsh/zle.yo17
-rw-r--r--Functions/Zle/.distfiles1
-rw-r--r--Functions/Zle/insert-unicode-char17
-rw-r--r--Src/Zle/iwidgets.list1
-rw-r--r--Src/Zle/zle.h1
-rw-r--r--Src/Zle/zle_main.c1
-rw-r--r--Src/Zle/zle_misc.c88
9 files changed, 133 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a8d74d3b..4ab7ceea9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* 22013: INSTALL, NEWS, Completion/compinstall,
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 5a70880ee..43d2812ff 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -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
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
character U+0180, the set of special characters less so. However, it it
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
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-off)
item(tt(predict-on))(
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 1daffde00..40bc24988 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -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
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()
texinode(Completion)(Miscellaneous)(Arguments)(Zle Widgets)
subsect(Completion)
diff --git a/Functions/Zle/.distfiles b/Functions/Zle/.distfiles
index e6d1cf3d6..5bce7ce04 100644
--- a/Functions/Zle/.distfiles
+++ b/Functions/Zle/.distfiles
@@ -9,6 +9,7 @@ edit-command-line forward-word-match
history-pattern-search history-search-end
incarg incremental-complete-word
insert-composed-char insert-files
+insert-unicode-char
keeper kill-word-match
match-words-by-style narrow-to-region
narrow-to-region-invisible predict-on
diff --git a/Functions/Zle/insert-unicode-char b/Functions/Zle/insert-unicode-char
new file mode 100644
index 000000000..0ffd29418
--- /dev/null
+++ b/Functions/Zle/insert-unicode-char
@@ -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
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index bf1abdadc..cc9ef20f9 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -13,6 +13,7 @@
"accept-and-menu-complete", acceptandmenucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
"accept-line", acceptline, 0
"accept-line-and-down-history", acceptlineanddownhistory, 0
+"argument-base", argumentbase, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
"backward-char", backwardchar, 0
"backward-delete-char", backwarddeletechar, ZLE_KEEPSUFFIX
"backward-delete-word", backwarddeleteword, ZLE_KEEPSUFFIX
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index c47efae9a..2981f9a83 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -205,6 +205,7 @@ struct modifier {
int mult; /* repeat count */
int tmult; /* repeat count actually being edited */
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 */
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index abcd06221..4f1079747 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1153,6 +1153,7 @@ initmodifier(struct modifier *mp)
mp->mult = 1;
mp->tmult = 1;
mp->vibuf = 0;
+ mp->base = 10;
}
/* Reset command modifiers, unless the command just executed was a prefix. *
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index b3706f2d0..869e0a435 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -518,12 +518,9 @@ quotedinsert(char **args)
return selfinsert(args);
}
-/**/
-int
-digitargument(UNUSED(char **args))
+static int
+parsedigit(int inkey)
{
- int sign = (zmult < 0) ? -1 : 1;
-
#ifdef MULTIBYTE_SUPPORT
/*
* 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
* encoding.
*/
- if (!idigit(lastchar))
- return 1;
#else
/* allow metafied as well as ordinary digits */
- if (!idigit(lastchar & 0x7f))
- return 1;
+ inkey &= 0x7f;
#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))
zmod.tmult = 0;
if (zmod.flags & MOD_NEG) {
/* If we just had a negative argument, this is the digit, *
* rather than the -1 assumed by negargument() */
- zmod.tmult = sign * (lastchar & 0xf);
+ zmod.tmult = sign * newdigit;
zmod.flags &= ~MOD_NEG;
} else
- zmod.tmult = zmod.tmult * 10 + sign * (lastchar & 0xf);
+ zmod.tmult = zmod.tmult * zmod.base + sign * newdigit;
zmod.flags |= MOD_TMULT;
prefixflag = 1;
return 0;
@@ -594,12 +616,16 @@ universalargument(char **args)
if (gotk == '-' && !digcnt) {
minus = -1;
digcnt++;
- } else if (idigit(gotk)) {
- pref = pref * 10 + (gotk & 0xf);
- digcnt++;
} else {
- ungetbyte(gotk);
- break;
+ int newdigit = parsedigit(gotk);
+
+ if (newdigit >= 0) {
+ pref = pref * zmod.base + newdigit;
+ digcnt++;
+ } else {
+ ungetbyte(gotk);
+ break;
+ }
}
}
if (digcnt)
@@ -611,6 +637,36 @@ universalargument(char **args)
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
copyprevword(UNUSED(char **args))