ebina@URBANA.MCD.MOT.COM (Eric Bina) (10/14/90)
I have been told that what I have done is similar to resurfacing a highway to support horses. But then, some of us like horses. Anyways, what we have here is the Athena Text Widget with some modifications (hacks, corruptions, etc.) so that it will support vi-like modal editing. Please note that the vi-like changes in no way hinder the nasty ( <- my opinion) emacs-like editing functions that are already there. To switch between the editing modes use Ctrl-X. This was the only Control Key I could find that neither editor uses. Upon startup the Text Widget looks for a resource startMode(Class: StartMode) to decide which of the edit modes to start in. The default is the old emacs-like mode. The other possible values are "vi" and "insert" which represent the vi command and insert modes. I really should have added a converter for this resource, but I was being a minimalist (lazy) again. These changes involve minor changes to Text.c, Text.h, TextP.h (mostly just to add a resource which specifies what edit mode to start in), the addition of several large translation tables to TextTr.c, and the addition of several new actions to TextAction.c Wherever possible I tried to use the emacsian actions that were already there. As a result the vi-like functions are limited (crippled). I could, and probably will write a better version which will involve MAJOR changes to TextAction.c. But for all you minimalists out there, these are the minimal changes I needed to make to get the minimal functionality that I required. Functions implemented: Ctrl-X Switch to emacs-like mode. Ctrl-T Transpose characters. This was a nice little function already built into the current text widget that I didn't want to waste. Especially since 'xp' will no longer transpose characters because the cursor in the text widget is between characters, instead of on a character as in vi. Ctrl-P Form a paragraph. Another built-in that was already there that I didn't want to waste. I takes all the text between the previous and next blank lines and packs as many words as it can on a line, breaking at whole word boundries. Ctrl-L Redraw the text window. This also centers the current line in the text window since that was what the currently existing function did. Ctrl-F Move foreward one screen of text. Ctrl-B Move backward one screen of text. Ctrl-D Scroll foreward one line of text. Sorry, there was no builtin for half pages, and I didn't feel it was necessary enough to write one. Ctrl-U Scroll backward one line of text. Sorry, there was no builtin for half pages, and I didn't feel it was necessary enough to write one. Ctrl-H Move backward one character. BackSpace Whatever your backspace character is will move backward one character. Cursor-Left Move backward one character. h Move backward one character. l Move foreward one character. Space Move foreward one character. Cursor-Right Move foreward one character. Cursor-Up Move up one line. k Move up one line. j Move down one line. Cursor-Down Move down one line. LineFeed Move down one line. Return Move to the beginning of the next line. + Move to the beginning of the next line. - Move to the beginning of the previous line. 0 Move to the beginning of the current line. $ Move to the end of the current line. G Move to the end of the file. g Move to the beginning of the file. This isn't in vi, but since implementing <count>G would be major changes, I needed a way to do a '1G', and this was it. w or W Move to the beginning of the next word. Words are deliniated by white space. e or E Move to the end of the next word. Words are deliniated by white space. b or B Move to the beginning of the previous word. Words are deliniated by white space. } Move to the beginning of the next paragraph. Paragraphs are delineated by blank lines. { Move to the beginning of the previous paragraph. Paragraphs are delineated by blank lines. D Delete to end of current line. dd Delete all of current line. dw Delete next word. db Delete previous word. d} Delete next paragraph. There was no builtin to delete previous paragraph, and I didn't think it was essential. C Change text to end of current line. cc Change text in all of current line. cw Change next word. cb Change previous word. c} Change next paragraph. Y Yank text in all of current line. I know this is inconsistent, but it is what vi does. yy Yank text in all of current line. yw Yank next word. yb Yank previous word. y} Yank next paragraph. p or P insert last yanked or deleted text. Since the cursor is always between two characters there is no put before and put after. z. Center current line in text window. There was already a builtin for this one, but there were none for 'z-' and 'z<CR>' so I didn't implement those. "[a-f] Place text from next yank, delete, or change command into buffer '[a-f]', or get text for next put command from buffer '[a-f]'. These are all the buffers you get, since I am using CUT_BUFFERS 2-7. Just getting this required more hacking than I wanted to do, but I felt I needed a few buffers. Note that you should be able to yank into a buffer in one text widget, and then put from that buffer in any text widget on the same display. s Substitute arbitrary amount of text for next character. S Substitute arbitrary amount of text for current line. r Replace next character. R Replace arbitrary amount of characters. i or a Insert mode. There is no before and after, so these now have the same function. I Insert at beginning of current line. A Append at end of current line. o Open a new line after current line. O Open a new line before current line. x Delete next character. X Delete previous character. / Search forward. ? Search backward. J Join next line to end of current line. [2-9] Multiply the next operation this many times (default 1). This is a big difference from vi that allows an arbitrary count. If you need to do something more than 9 times you can stack these operations. '25dd' will delete the next 2 * 5 = 10 lines. Likewise '2222j' will move down 16 lines. I know this is awkward, but it was a builtin I could use instead of writing new code. I'm sure you will all find many minor (and major) differences between the functions of this widget and vi. I will try and point out a few major ones here: vi treats the end of a line as 'special' somehow. Cursor movements and deletions stop at the endpoints of lines unless the are commands that work on multiple lines. In the text widget the end of a line is just a <CR> character. And you can move over it, delete it, or replace it just like any other character. When you delete a line you are just deleting a range of characters and a <CR>, and that is what is in your cut buffer. So doing a put of a deleted or yanked line will not do what you expect unless you are at the beginning of a line. As has already been pointed out, counts before operations are completely different. Also, the change commands do not give the dollar sign to represent the range being changed. They immediately delete the range, and then leave you in insert mode. There is no undo! There is no '.'! There are no 'f' and 't' functions. Send comments, complaints, suggestions to Eric Bina ebina@urbana.mcd.mot.com Context diffs for Text.c, Text.h, TextP.h, TextAction.c, and TextTr.c follow: *** Text.c Sat Oct 13 16:00:54 1990 --- lib/Xaw/Text.c Sat Oct 13 16:00:13 1990 *************** *** 99,104 **** --- 99,108 ---- static caddr_t defaultSelectTypesPtr = (caddr_t)defaultSelectTypes; extern char *_XawDefaultTextTranslations1, *_XawDefaultTextTranslations2, *_XawDefaultTextTranslations3; + extern char *_XawViTextTranslations1, *_XawViTextTranslations2, + *_XawViTextTranslations3, *_XawViTextTranslations4; + extern char *_XawViInsertTranslations1; + char *DefaultTrans, *ViTrans, *InsertTrans; static Dimension defWidth = 100; static Dimension defHeight = DEFAULT_TEXT_HEIGHT; *************** *** 138,143 **** --- 142,149 ---- offset(text.scroll_horiz), XtRImmediate, (caddr_t) XawtextScrollNever}, {XtNwrap, XtCWrap, XtRWrapMode, sizeof(XawTextWrapMode), offset(text.wrap), XtRImmediate, (caddr_t) XawtextWrapNever}, + {XtNstartMode, XtCStartMode, XtRString, sizeof(String), + offset(text.start_mode), XtRString, "default"}, {XtNresize, XtCResize, XtRResizeMode, sizeof(XawTextResizeMode), offset(text.resize), XtRImmediate, (caddr_t) XawtextResizeNever}, {XtNautoFill, XtCAutoFill, XtRBoolean, sizeof(Boolean), *************** *** 273,281 **** int len1 = strlen (_XawDefaultTextTranslations1); int len2 = strlen (_XawDefaultTextTranslations2); int len3 = strlen (_XawDefaultTextTranslations3); ! char *buf = XtMalloc (len1 + len2 + len3 + 1); ! char *cp = buf; XawInitializeWidgetSet(); /* --- 279,295 ---- int len1 = strlen (_XawDefaultTextTranslations1); int len2 = strlen (_XawDefaultTextTranslations2); int len3 = strlen (_XawDefaultTextTranslations3); ! int vilen1 = strlen (_XawViTextTranslations1); ! int vilen2 = strlen (_XawViTextTranslations2); ! int vilen3 = strlen (_XawViTextTranslations3); ! int vilen4 = strlen (_XawViTextTranslations4); ! int inlen1 = strlen (_XawViInsertTranslations1); ! char *cp; + DefaultTrans = (char *)XtMalloc (len1 + len2 + len3 + 1); + ViTrans = (char *)XtMalloc (vilen1 + vilen2 + vilen3 + vilen4 + 1); + InsertTrans = (char *)XtMalloc (inlen1 + 1); + XawInitializeWidgetSet(); /* *************** *** 284,293 **** textClassRec.core_class.num_actions = textActionsTableCount; strcpy (cp, _XawDefaultTextTranslations1); cp += len1; strcpy (cp, _XawDefaultTextTranslations2); cp += len2; strcpy (cp, _XawDefaultTextTranslations3); ! textWidgetClass->core_class.tm_table = buf; XtAddConverter(XtRString, XtRScrollMode, CvtStringToScrollMode, NULL, 0); XtAddConverter(XtRString, XtRWrapMode, CvtStringToWrapMode, NULL, 0); --- 298,316 ---- textClassRec.core_class.num_actions = textActionsTableCount; + cp = DefaultTrans; strcpy (cp, _XawDefaultTextTranslations1); cp += len1; strcpy (cp, _XawDefaultTextTranslations2); cp += len2; strcpy (cp, _XawDefaultTextTranslations3); ! cp = ViTrans; ! strcpy (cp, _XawViTextTranslations1); cp += vilen1; ! strcpy (cp, _XawViTextTranslations2); cp += vilen2; ! strcpy (cp, _XawViTextTranslations3); cp += vilen3; ! strcpy (cp, _XawViTextTranslations4); ! cp = InsertTrans; ! strcpy (cp, _XawViInsertTranslations1); ! ! textWidgetClass->core_class.tm_table = DefaultTrans; XtAddConverter(XtRString, XtRScrollMode, CvtStringToScrollMode, NULL, 0); XtAddConverter(XtRString, XtRWrapMode, CvtStringToWrapMode, NULL, 0); *************** *** 515,520 **** --- 538,562 ---- } else if (ctx->text.scroll_horiz == XawtextScrollAlways) CreateHScrollBar(ctx); + + if ((strcmp(ctx->text.start_mode, "default") == 0)|| + (strcmp(ctx->text.start_mode, "Default") == 0)) + { + XtOverrideTranslations(ctx, XtParseTranslationTable(DefaultTrans)); + } + else if ((strcmp(ctx->text.start_mode, "vi") == 0)|| + (strcmp(ctx->text.start_mode, "Vi") == 0)|| + (strcmp(ctx->text.start_mode, "VI") == 0)) + { + XtOverrideTranslations(ctx, XtParseTranslationTable(ViTrans)); + } + else if ((strcmp(ctx->text.start_mode, "viinsert") == 0)|| + (strcmp(ctx->text.start_mode, "ViInsert") == 0)|| + (strcmp(ctx->text.start_mode, "Insert") == 0)|| + (strcmp(ctx->text.start_mode, "insert") == 0)) + { + XtOverrideTranslations(ctx, XtParseTranslationTable(InsertTrans)); + } } static void *************** *** 2736,2741 **** --- 2778,2805 ---- if (oldtw->text.insertPos != newtw->text.insertPos) { newtw->text.showposition = TRUE; redisplay = TRUE; + } + + if (oldtw->text.start_mode != newtw->text.start_mode) + { + if ((strcmp(newtw->text.start_mode, "default") == 0)|| + (strcmp(newtw->text.start_mode, "Default") == 0)) + { + XtOverrideTranslations(newtw, XtParseTranslationTable(DefaultTrans)); + } + else if ((strcmp(newtw->text.start_mode, "vi") == 0)|| + (strcmp(newtw->text.start_mode, "Vi") == 0)|| + (strcmp(newtw->text.start_mode, "VI") == 0)) + { + XtOverrideTranslations(newtw, XtParseTranslationTable(ViTrans)); + } + else if ((strcmp(newtw->text.start_mode, "viinsert") == 0)|| + (strcmp(newtw->text.start_mode, "ViInsert") == 0)|| + (strcmp(newtw->text.start_mode, "Insert") == 0)|| + (strcmp(newtw->text.start_mode, "insert") == 0)) + { + XtOverrideTranslations(newtw, XtParseTranslationTable(InsertTrans)); + } } _XawTextExecuteUpdate(newtw); *** Text.h Sat Oct 13 16:00:54 1990 --- lib/Xaw/Text.h Sat Oct 13 16:00:13 1990 *************** *** 97,102 **** --- 97,103 ---- #define XtNselection "selection" #define XtNtopMargin "topMargin" #define XtNwrap "wrap" + #define XtNstartMode "startMode" #define XtCAutoFill "AutoFill" #define XtCResize "Resize" *************** *** 103,108 **** --- 104,110 ---- #define XtCScroll "Scroll" #define XtCSelectTypes "SelectTypes" #define XtCWrap "Wrap" + #define XtCStartMode "StartMode" /* Return Error code for XawTextSearch */ *** TextP.h Sat Oct 13 16:00:54 1990 --- lib/Xaw/TextP.h Sat Oct 13 16:00:13 1990 *************** *** 160,165 **** --- 160,166 ---- Boolean auto_fill; /* Auto fill mode? */ XawTextScrollMode scroll_vert, scroll_horiz; /*what type of scrollbars.*/ XawTextWrapMode wrap; /* The type of wrapping. */ + char *start_mode; /* What edit mode to start in. */ XawTextResizeMode resize; /* what to resize */ XawTextMargin r_margin; /* The real margins. */ *** TextAction.c Sat Oct 13 16:00:54 1990 --- lib/Xaw/TextAction.c Sat Oct 13 16:00:13 1990 *************** *** 71,76 **** --- 71,82 ---- void _XawTextSetScrollBars(), _XawTextClearAndCenterDisplay(); Atom * _XawTextSelectionList(); + extern char *DefaultTrans, *ViTrans, *InsertTrans; + + int ReplaceCnt; + int Infinite; + int DeleteBuf = 1; + static void StartAction(ctx, event) TextWidget ctx; *************** *** 112,117 **** --- 118,124 ---- _XawTextCheckResize(ctx); _XawTextExecuteUpdate(ctx); ctx->text.mult = 1; + DeleteBuf = 1; } *************** *** 273,278 **** --- 280,318 ---- EndAction((TextWidget)w); } + static char *BufNames[] = { + "CUT_BUFFER0", + "CUT_BUFFER1", + "CUT_BUFFER2", + "CUT_BUFFER3", + "CUT_BUFFER4", + "CUT_BUFFER5", + "CUT_BUFFER6", + "CUT_BUFFER7" + }; + + static void + InsertChosenSelection(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; /* precedence list of selections to try */ + Cardinal *num_params; + { + char *bptr; + + StartAction((TextWidget)w, event); /* Get Time. */ + if ((DeleteBuf >= 0)&&(DeleteBuf < 8)) + { + bptr = BufNames[DeleteBuf]; + } + else + { + bptr = BufNames[1]; + } + GetSelection(w, ((TextWidget)w)->text.time, &bptr, 1); + EndAction((TextWidget)w); + } + /************************************************************ * * Routines for Moving Around. *************** *** 553,559 **** if (kill && from < to) { ptr = _XawTextGetText(ctx, from, to); ! XStoreBuffer(XtDisplay(ctx), ptr, strlen(ptr), 1); XtFree(ptr); } text.length = 0; --- 593,599 ---- if (kill && from < to) { ptr = _XawTextGetText(ctx, from, to); ! XStoreBuffer(XtDisplay(ctx), ptr, strlen(ptr), DeleteBuf); XtFree(ptr); } text.length = 0; *************** *** 602,607 **** --- 642,697 ---- EndAction(ctx); } + static void + _Yank(ctx, from, to, kill) + TextWidget ctx; + XawTextPosition from, to; + Boolean kill; + { + char *ptr; + + if (kill && from < to) { + ptr = _XawTextGetText(ctx, from, to); + XStoreBuffer(XtDisplay(ctx), ptr, strlen(ptr), DeleteBuf); + XtFree(ptr); + } + } + + static void + Yank(ctx, event, dir, type, include, kill) + TextWidget ctx; + XEvent *event; + XawTextScanDirection dir; + XawTextScanType type; + Boolean include, kill; + { + XawTextPosition from, to; + + StartAction(ctx, event); + to = SrcScan(ctx->text.source, ctx->text.insertPos, + type, dir, ctx->text.mult, include); + + /* + * If no movement actually happened, then bump the count and try again. + * This causes the character position at the very beginning and end of + * a boundry to act correctly. + */ + + if (to == ctx->text.insertPos) + to = SrcScan(ctx->text.source, ctx->text.insertPos, + type, dir, ctx->text.mult + 1, include); + + if (dir == XawsdLeft) { + from = to; + to = ctx->text.insertPos; + } + else + from = ctx->text.insertPos; + + _Yank(ctx, from, to, kill); + EndAction(ctx); + } + /*ARGSUSED*/ static void DeleteForwardChar(w, event, p, n) *************** *** 650,655 **** --- 740,767 ---- /*ARGSUSED*/ static void + KillForwardChar(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + DeleteOrKill((TextWidget) w, event, XawsdRight, XawstPositions, TRUE, TRUE); + } + + /*ARGSUSED*/ + static void + KillBackwardChar(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + DeleteOrKill((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE, TRUE); + } + + /*ARGSUSED*/ + static void KillForwardWord(w, event, p, n) Widget w; XEvent *event; *************** *** 697,702 **** --- 809,836 ---- /*ARGSUSED*/ static void + KillLine(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + TextWidget ctx = (TextWidget) w; + XawTextPosition end_of_line; + + StartAction(ctx, event); + ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, 1, FALSE); + end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, + XawsdRight, ctx->text.mult, TRUE); + + _DeleteOrKill(ctx, ctx->text.insertPos, end_of_line, TRUE); + EndAction(ctx); + _XawTextSetScrollBars(ctx); + } + + /*ARGSUSED*/ + static void KillToEndOfParagraph(w, event, p, n) Widget w; XEvent *event; *************** *** 706,711 **** --- 840,924 ---- DeleteOrKill((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE, TRUE); } + /*ARGSUSED*/ + static void + YankForwardWord(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + Yank((TextWidget) w, event, + XawsdRight, XawstWhiteSpace, FALSE, TRUE); + } + + /*ARGSUSED*/ + static void + YankBackwardWord(w, event, p, n) + TextWidget w; + XEvent *event; + String *p; + Cardinal *n; + { + Yank((TextWidget) w, event, + XawsdLeft, XawstWhiteSpace, FALSE, TRUE); + } + + /*ARGSUSED*/ + static void + YankToEndOfLine(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + TextWidget ctx = (TextWidget) w; + XawTextPosition end_of_line; + + StartAction(ctx, event); + end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, + XawsdRight, ctx->text.mult, FALSE); + if (end_of_line == ctx->text.insertPos) + end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, + XawsdRight, ctx->text.mult, TRUE); + + _Yank(ctx, ctx->text.insertPos, end_of_line, TRUE); + EndAction(ctx); + } + + /*ARGSUSED*/ + static void + YankLine(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + TextWidget ctx = (TextWidget) w; + XawTextPosition start_of_line; + XawTextPosition end_of_line; + + StartAction(ctx, event); + start_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, + XawstEOL, XawsdLeft, 1, FALSE); + end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, + XawsdRight, ctx->text.mult, TRUE); + + _Yank(ctx, start_of_line, end_of_line, TRUE); + EndAction(ctx); + } + + /*ARGSUSED*/ + static void + YankToEndOfParagraph(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + Yank((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE, TRUE); + } + void _XawTextZapSelection(ctx, event, kill) TextWidget ctx; *************** *** 1077,1082 **** --- 1290,1412 ---- /*ARGSUSED*/ static void + DefaultMode(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + TextWidget ctx = (TextWidget) w; + XtOverrideTranslations(w, XtParseTranslationTable(DefaultTrans)); + } + + /*ARGSUSED*/ + static void + ViMode(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + TextWidget ctx = (TextWidget) w; + XtOverrideTranslations(w, XtParseTranslationTable(ViTrans)); + } + + /*ARGSUSED*/ + static void + ReplaceTick(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + char strbuf[BUFSIZ]; + KeySym keysym; + int keylen; + + keylen = XLookupString (&event->xkey, strbuf, BUFSIZ, + &keysym, &compose_status); + if ((ReplaceCnt > 0)&&(keylen != 0)) + { + ReplaceCnt--; + if (ReplaceCnt == 0) + { + if (Infinite) + { + ReplaceCnt = 1; + } + else + { + XtOverrideTranslations(w, XtParseTranslationTable(ViTrans)); + } + } + } + } + + /*ARGSUSED*/ + static void + MayDelete(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + char strbuf[BUFSIZ]; + KeySym keysym; + int keylen; + + keylen = XLookupString (&event->xkey, strbuf, BUFSIZ, + &keysym, &compose_status); + if ((ReplaceCnt > 0)&&(keylen != 0)) + { + DeleteOrKill((TextWidget)w, event, XawsdRight, XawstPositions, TRUE, FALSE); + } + } + + /*ARGSUSED*/ + static void + InsertMode(w, event, p, n) + Widget w; + XEvent *event; + String *p; + Cardinal *n; + { + TextWidget ctx = (TextWidget) w; + int cnt; + + if (*n != 1) { + XtAppError(XtWidgetToApplicationContext(w), + "The insert action takes exactly one argument."); + XBell(XtDisplay(w), 0); + return; + } + + if ((p[0][0] == 'I')||(p[0][0] == 'i')) + { + cnt = 1; + Infinite = 1; + } + else + { + cnt = atoi(p[0]); + cnt = cnt * ctx->text.mult; + ctx->text.mult = 1; + Infinite = 0; + } + if ( cnt < 0 ) { + char buf[BUFSIZ]; + sprintf(buf, "%s %s", "Text Widget: The insert action's argument", + "must be a number greater than or equal to zero, or 'INF'."); + XtAppError(XtWidgetToApplicationContext(w), buf); + XBell(XtDisplay(w), 0); + return; + } + XtOverrideTranslations(w, XtParseTranslationTable(InsertTrans)); + ReplaceCnt = cnt; + } + + /*ARGSUSED*/ + static void InsertChar(w, event, p, n) Widget w; XEvent *event; *************** *** 1258,1263 **** --- 1588,1625 ---- ctx->text.mult *= mult; } + /* ARGSUSED */ + static void + SelectBuffer(w, event, params, num_params) + Widget w; + XEvent *event; + String * params; + Cardinal * num_params; + { + TextWidget ctx = (TextWidget) w; + int buf; + + if (*num_params != 1) { + XtAppError(XtWidgetToApplicationContext(w), + "The buffer-select action takes exactly one argument."); + XBell(XtDisplay(w), 0); + return; + } + + buf = atoi(params[0]); + + if ((buf < 0)||(buf > 7)) { + char buf[BUFSIZ]; + sprintf(buf, "%s %s", "Text Widget: The buffer-select action's argument", + "must be a number greater than or equal to zero and less than eight."); + XtAppError(XtWidgetToApplicationContext(w), buf); + XBell(XtDisplay(w), 0); + return; + } + + DeleteBuf = buf; + } + /* Function Name: StripOutOldCRs * Description: strips out the old carrige returns. * Arguments: ctx - the text widget. *************** *** 1571,1581 **** --- 1933,1952 ---- {"delete-previous-word", DeleteBackwardWord}, {"delete-selection", DeleteCurrentSelection}, /* kill bindings */ + {"kill-next-character", KillForwardChar}, + {"kill-previous-character", KillBackwardChar}, {"kill-word", KillForwardWord}, {"backward-kill-word", KillBackwardWord}, {"kill-selection", KillCurrentSelection}, {"kill-to-end-of-line", KillToEndOfLine}, + {"kill-line", KillLine}, {"kill-to-end-of-paragraph", KillToEndOfParagraph}, + /* yank bindings */ + {"yank-word", YankForwardWord}, + {"backward-yank-word", YankBackwardWord}, + {"yank-to-end-of-line", YankToEndOfLine}, + {"yank-line", YankLine}, + {"yank-to-end-of-paragraph", YankToEndOfParagraph}, #ifdef XAW_BC /* unkill bindings */ {"unkill", UnKill}, *************** *** 1596,1605 **** --- 1967,1983 ---- {"extend-adjust", ExtendAdjust}, {"extend-end", ExtendEnd}, {"insert-selection", InsertSelection}, + {"insert-chosen-selection", InsertChosenSelection}, /* Miscellaneous */ {"redraw-display", RedrawDisplay}, {"insert-file", _XawTextInsertFile}, {"search", _XawTextSearch}, + {"select-buffer", SelectBuffer}, + {"default-mode", DefaultMode}, + {"vi-mode", ViMode}, + {"may-delete", MayDelete}, + {"replace-tick", ReplaceTick}, + {"insert-mode", InsertMode}, {"insert-char", InsertChar}, {"insert-string", InsertString}, {"focus-in", TextFocusIn}, *** TextTr.c Sat Oct 13 16:00:55 1990 --- lib/Xaw/TextTr.c Sat Oct 13 16:00:13 1990 *************** *** 22,27 **** --- 22,28 ---- Ctrl<Key>U: multiply(4) \n\ Ctrl<Key>V: next-page() \n\ Ctrl<Key>W: kill-selection() \n\ + Ctrl<Key>X: vi-mode() \n\ Ctrl<Key>Y: insert-selection(CUT_BUFFER1) \n\ Ctrl<Key>Z: scroll-one-line-up() \n\ ", *_XawDefaultTextTranslations2 = "\ *************** *** 65,67 **** --- 66,195 ---- <Btn3Motion>: extend-adjust() \n\ <Btn3Up>: extend-end(PRIMARY, CUT_BUFFER0) \ "; + + char *_XawViTextTranslations1 = + "\ + Ctrl<Key>X: default-mode() \n\ + Ctrl<Key>T: transpose-characters() \n\ + Ctrl<Key>P: form-paragraph() \n\ + Ctrl<Key>L: redraw-display() \n\ + Ctrl<Key>F: next-page() \n\ + Ctrl<Key>B: previous-page() \n\ + Ctrl<Key>U: scroll-one-line-down() \n\ + Ctrl<Key>D: scroll-one-line-up() \n\ + Ctrl<Key>H: backward-character() \n\ + :<Key>\",:<Key>0: select-buffer(0) \n\ + :<Key>\",:<Key>a: select-buffer(2) \n\ + :<Key>\",:<Key>b: select-buffer(3) \n\ + :<Key>\",:<Key>c: select-buffer(4) \n\ + :<Key>\",:<Key>d: select-buffer(5) \n\ + :<Key>\",:<Key>e: select-buffer(6) \n\ + :<Key>\",:<Key>f: select-buffer(7) \n\ + :<Key>\\:,:<Key>r: insert-file() \n\ + :<Key>z,:<Key>\.: redraw-display() \n\ + :<Key>y,:<Key>y: yank-line() \n\ + :<Key>y,:<Key>w: yank-word() \n\ + :<Key>y,:<Key>b: backward-yank-word() \n\ + :<Key>y,:<Key>\}: yank-to-end-of-paragraph() \n\ + :<Key>y,:<Key>\{: yank-to-end-of-paragraph() \n\ + :<Key>d,:<Key>d: kill-line() \n\ + :<Key>d,:<Key>w: kill-word() \n\ + :<Key>d,:<Key>b: backward-kill-word() \n\ + :<Key>d,:<Key>\}: kill-to-end-of-paragraph() \n\ + :<Key>d,:<Key>\{: kill-to-end-of-paragraph() \n\ + :<Key>c,:<Key>c: kill-line() newline-and-backup() insert-mode(0) \n\ + :<Key>c,:<Key>w: kill-word() insert-mode(0) \n\ + :<Key>c,:<Key>b: backward-kill-word() insert-mode(0) \n\ + :<Key>c,:<Key>\}: kill-to-end-of-paragraph() insert-mode(0) \n\ + :<Key>c,:<Key>\{: kill-to-end-of-paragraph() insert-mode(0) \n\ + ", *_XawViTextTranslations2 = "\ + :<Key>Y: yank-line() \n\ + :<Key>D: kill-to-end-of-line() \n\ + :<Key>C: kill-to-end-of-line() insert-mode(0) \n\ + :<Key>e: forward-word() \n\ + :<Key>E: forward-word() \n\ + :<Key>w: forward-word() forward-word() backward-word() \n\ + :<Key>W: forward-word() forward-word() backward-word() \n\ + :<Key>b: backward-word() \n\ + :<Key>B: backward-word() \n\ + :<Key>\}: forward-paragraph() \n\ + :<Key>\{: backward-paragraph() \n\ + <Key>BackSpace: backward-character() \n\ + :<Key>h: backward-character() \n\ + :<Key>l: forward-character() \n\ + <Key>space: forward-character() \n\ + :<Key>j: next-line() \n\ + :<Key>k: previous-line() \n\ + :<Key>0: beginning-of-line() \n\ + :<Key>\$: end-of-line() \n\ + :<Key>g: beginning-of-file() \n\ + :<Key>G: end-of-file() \n\ + ", *_XawViTextTranslations3 = "\ + :<Key>s: kill-next-character() insert-mode(0) \n\ + :<Key>S: kill-line() newline-and-backup() insert-mode(0) \n\ + :<Key>r: insert-mode(1) \n\ + :<Key>R: insert-mode(INF) \n\ + :<Key>i: insert-mode(0) \n\ + :<Key>I: beginning-of-line() insert-mode(0) \n\ + :<Key>a: insert-mode(0) \n\ + :<Key>A: end-of-line() insert-mode(0) \n\ + :<Key>o: end-of-line() newline() insert-mode(0) \n\ + :<Key>O: beginning-of-line() newline-and-backup() insert-mode(0) \n\ + :<Key>x: kill-next-character() \n\ + :<Key>X: kill-previous-character() \n\ + :<Key>\?: search(backward) \n\ + :<Key>\/: search(forward) \n\ + :<Key>p: insert-chosen-selection() \n\ + :<Key>P: insert-chosen-selection() \n\ + :<Key>J: end-of-line() delete-next-character() \n\ + :<Key>2: multiply(2) \n\ + :<Key>3: multiply(3) \n\ + :<Key>4: multiply(4) \n\ + :<Key>5: multiply(5) \n\ + :<Key>6: multiply(6) \n\ + :<Key>7: multiply(7) \n\ + :<Key>8: multiply(8) \n\ + :<Key>9: multiply(9) \n\ + ", *_XawViTextTranslations4 = "\ + <Key>Escape: multiply(Reset) \n\ + <Key>Right: forward-character() \n\ + <Key>Left: backward-character() \n\ + <Key>Down: next-line() \n\ + <Key>Up: previous-line() \n\ + <Key>Delete: kill-selection() \n\ + <Key>Linefeed: next-line() \n\ + <Key>Return: next-line() beginning-of-line() \n\ + <Key>\+: next-line() beginning-of-line() \n\ + <Key>\-: previous-line() beginning-of-line() \n\ + <Key>: no-op() \n\ + <FocusIn>: focus-in() \n\ + <FocusOut>: focus-out() \n\ + <Btn1Down>: select-start() \n\ + <Btn1Motion>: extend-adjust() \n\ + <Btn1Up>: extend-end(PRIMARY, CUT_BUFFER0) \n\ + <Btn2Down>: insert-selection(PRIMARY, CUT_BUFFER0) \n\ + <Btn3Down>: extend-start() \n\ + <Btn3Motion>: extend-adjust() \n\ + <Btn3Up>: extend-end(PRIMARY, CUT_BUFFER0) \ + "; + + char *_XawViInsertTranslations1 = + "\ + Ctrl<Key>X: default-mode() \n\ + <Key>Escape: vi-mode() \n\ + <Key>BackSpace: delete-previous-character() replace-tick() \n\ + <Key>Delete: delete-previous-character() replace-tick() \n\ + <Key>Linefeed: newline() replace-tick() \n\ + <Key>Return: newline() replace-tick() \n\ + <Key>: may-delete() insert-char() replace-tick() \n\ + <FocusIn>: focus-in() \n\ + <FocusOut>: focus-out() \n\ + <Btn1Down>: select-start() \n\ + <Btn1Motion>: extend-adjust() \n\ + <Btn1Up>: extend-end(PRIMARY, CUT_BUFFER0) \n\ + <Btn2Down>: insert-selection(PRIMARY, CUT_BUFFER0) \n\ + <Btn3Down>: extend-start() \n\ + <Btn3Motion>: extend-adjust() \n\ + <Btn3Up>: extend-end(PRIMARY, CUT_BUFFER0) \ + "; +