re-fresh
[nedit-bw.git] / GTsAndAtsInMenus.diff
blobe7b084efd7bd0a6c902a1bec235762fb40be202f
1 From: Tony Balinskt <ajbj@free.fr>
2 Subject: [PATCH] Allow '>' and '@' to appear in menu items
4 Two consecutive '>'s are treated as a single '>' in a displayed menu item,
5 rather than being used to generate a submenu. Similarly, doubled '@'s will
6 not start language mode interpretation.
8 ---
10 source/userCmds.c | 72 +++++++++++++++++++++++++++++++++++++++++++++---------
11 1 file changed, 60 insertions(+), 12 deletions(-)
13 diff --quilt old/source/userCmds.c new/source/userCmds.c
14 --- old/source/userCmds.c
15 +++ new/source/userCmds.c
16 @@ -262,6 +262,8 @@ static void manageMenuWidgets(UserMenuLi
17 static void removeAccelFromMenuWidgets(UserMenuList *menuList);
18 static void assignAccelToMenuWidgets(UserMenuList *menuList, WindowInfo *window);
19 static void manageUserMenu(selectedUserMenu *menu, WindowInfo *window);
20 +static char *nextNonDoubledChr(const char *str, char ch);
21 +static char *dropDoubledChr(char *str, char ch);
22 static void createMenuItems(WindowInfo *window, selectedUserMenu *menu);
23 static void okCB(Widget w, XtPointer clientData, XtPointer callData);
24 static void applyCB(Widget w, XtPointer clientData, XtPointer callData);
25 @@ -1799,6 +1801,46 @@ static void manageUserMenu(selectedUserM
29 +** Find the first separator ch - any doubled occurrence of ch is ignored.
30 +** Returns the address of the ch separator or NULL.
31 +*/
32 +static char *nextNonDoubledChr(const char *str, char ch)
34 + char *p = (char *)str;
35 + for (;;) {
36 + p = strchr(p, ch);
37 + if (!p)
38 + return p;
39 + if (p[1] == ch) {
40 + p += 2;
41 + }
42 + else
43 + break;
44 + }
45 + return p;
48 +/*
49 +** Removes the second ch in every sequence of two ch characters in str (in
50 +** place) returning str.
51 +*/
52 +static char *dropDoubledChr(char *str, char ch)
54 + char *from = str;
55 + char *to;
56 + while (*from != ch && *from)
57 + ++from;
58 + to = from;
59 + while (*from) {
60 + if (from[0] == ch && from[1] == ch)
61 + ++from;
62 + *to++ = *from++;
63 + }
64 + *to = *from;
65 + return str;
68 +/*
69 ** Create either the variable Shell menu, Macro menu or Background menu
70 ** items of "window" (driven by value of "menuType")
72 @@ -1848,12 +1890,15 @@ static void createMenuItems(WindowInfo *
73 namePtr = fullName;
74 subPane = menu->sumMenuPane;
75 for (;;) {
76 - subSep = strchr(namePtr, '>');
77 + subSep = nextNonDoubledChr(namePtr, '>');
78 if (subSep == NULL) {
79 - btn = createUserMenuItem(subPane, namePtr, item, n,
80 + subMenuName = copySubstring(namePtr, strlen(namePtr));
81 + dropDoubledChr(dropDoubledChr(subMenuName, '>'), '@');
82 + btn = createUserMenuItem(subPane, subMenuName, item, n,
83 (XtCallbackProc)(menuType == SHELL_CMDS ? shellMenuCB :
84 (menuType == MACRO_CMDS ? macroMenuCB : bgMenuCB)),
85 (XtPointer)window);
86 + XtFree(subMenuName);
87 if (menuType == BG_MENU_CMDS && !strcmp(item->cmd, "undo()\n"))
88 window->bgMenuUndoItem = btn;
89 else if (menuType == BG_MENU_CMDS && !strcmp(item->cmd,"redo()\n"))
90 @@ -1871,6 +1916,7 @@ static void createMenuItems(WindowInfo *
91 newSubPane = findInMenuTree(menuTree, nTreeEntries, hierName);
92 if (newSubPane == NULL) {
93 subMenuName = copySubstring(namePtr, subSep - namePtr);
94 + dropDoubledChr(dropDoubledChr(subMenuName, '>'), '@');
95 newSubPane = createUserSubMenu(subPane, subMenuName, &btn);
96 XtFree(subMenuName);
97 menuTree[nTreeEntries].name = hierName;
98 @@ -3171,7 +3217,7 @@ static int getSubMenuDepth(const char *m
100 /* determine sub-menu depth by counting '>' of given "menuName" */
101 subSep = menuName;
102 - while ((subSep = strchr(subSep, '>')) != NULL ) {
103 + while ((subSep = nextNonDoubledChr(subSep, '>')) != NULL ) {
104 depth ++;
105 subSep ++;
107 @@ -3231,7 +3277,7 @@ static void parseMenuItemName(char *menu
108 int nbrLM = 0;
109 int size;
111 - atPtr = firstAtPtr = strchr(menuItemName, '@');
112 + atPtr = firstAtPtr = nextNonDoubledChr(menuItemName, '@');
113 if (atPtr != NULL) {
114 if (!strcmp(atPtr+1, "*")) {
115 /* only language is "*": this is for all but language specific
116 @@ -3243,9 +3289,12 @@ static void parseMenuItemName(char *menu
117 /* setup a list of all language modes related to given menu item */
118 while (atPtr != NULL) {
119 /* extract language mode name after "@" sign */
120 - for(endPtr=atPtr+1; isalnum((unsigned char)*endPtr) || *endPtr=='_' ||
121 - *endPtr=='-' || *endPtr==' ' || *endPtr=='+' || *endPtr=='$' ||
122 - *endPtr=='#'; endPtr++);
123 + /* should the condition be
124 + isprint((unsigned char)*endPtr) && *endPtr != '@'
125 + instead? */
126 + for(endPtr=atPtr+1;
127 + isalnum((unsigned char)*endPtr) || strchr("_- +$#", *endPtr);
128 + endPtr++);
130 /* lookup corresponding language mode index; if PLAIN is
131 returned then this means, that language mode name after
132 @@ -3292,7 +3341,7 @@ static void generateUserMenuId(userMenuI
133 /* find sub-menus, stripping off '>' until item name is
134 reached */
135 subSep = info->umiName;
136 - while ((subSep = strchr(subSep, '>')) != NULL) {
137 + while ((subSep = nextNonDoubledChr(subSep, '>')) != NULL) {
138 hierName = copySubstring(info->umiName, subSep - info->umiName);
139 curSubMenu = findSubMenuInfo(subMenus, hierName);
140 if (curSubMenu == NULL) {
141 @@ -3354,11 +3403,10 @@ static char *stripLanguageMode(const cha
143 char *firstAtPtr;
145 - firstAtPtr = strchr(menuItemName, '@');
146 + firstAtPtr = nextNonDoubledChr(menuItemName, '@');
147 if (firstAtPtr == NULL)
148 - return XtNewString(menuItemName);
149 - else
150 - return copySubstring(menuItemName, firstAtPtr-menuItemName);
151 + firstAtPtr = strchr(menuItemName, '\0');
152 + return copySubstring(menuItemName, firstAtPtr-menuItemName);
155 static void setDefaultIndex(userMenuInfo **infoList, int nbrOfItems,