diff options
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/iwidgets.list | 1 | ||||
-rw-r--r-- | Src/Zle/zle.h | 1 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 1 | ||||
-rw-r--r-- | Src/Zle/zle_misc.c | 88 |
4 files changed, 75 insertions, 16 deletions
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)) |