From a2a3094f4fbe3485c4cd1d970387ad207a084180 Mon Sep 17 00:00:00 2001 From: handa Date: Fri, 15 Apr 2005 11:28:44 +0000 Subject: [PATCH] Include dlfcn.h. (Mword): New variable. (show_cursor): Check Mlanguage text property of the cursor position only. (delete_char): Pay attention to the change of line beginning position because of filling. (insert_chars): Likewise. (word_constituent_p, forward_word, backward_word): New functions. (KeyProc): Assign XK_b and XK_f for back/foreward word. (line_break): Delete extern. (LineBreakProc): Use mdraw_default_line_break. (FilterProc): New function. (main): Handle --filter arg. Initialize Mword. --- example/medit.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 12 deletions(-) diff --git a/example/medit.c b/example/medit.c index 7f56f80..5b6aacc 100644 --- a/example/medit.c +++ b/example/medit.c @@ -95,6 +95,7 @@ #include #include #include +#include #include #include @@ -172,6 +173,8 @@ int nchars; /* == mtext_len (mt) */ MDrawControl control, input_status_control; MTextProperty *selection; +MSymbol Mword; + MFace *face_default; MFace *face_xxx_large; MFace *face_box; @@ -490,7 +493,7 @@ redraw_cursor (int clear) /* Update the information about the location of cursor to the position $POS. If $FULL is nonzero, update the information fully only from - the information about the top line. Otherwise, truct the current + the information about the top line. Otherwise, trust the current information in the structure $CUR. */ void update_cursor (int pos, int full) @@ -795,14 +798,8 @@ show_cursor (XtPointer client_data) if (control.cursor_pos < nchars) { - MSymbol sym = Mnil; + MSymbol sym = mtext_get_prop (mt, control.cursor_pos, Mlanguage); - if (control.cursor_pos > 0 - && mtext_ref_char (mt, control.cursor_pos - 1) != '\n') - sym = mtext_get_prop (mt, control.cursor_pos - 1, Mlanguage); - if (sym == Mnil) - sym = mtext_get_prop (mt, control.cursor_pos, Mlanguage); - if (sym == Mnil) { XtSetArg (arg[0], XtNborderWidth, 0); @@ -902,8 +899,9 @@ delete_char (int n) { MDrawMetric rect; MDrawGlyphInfo info; - int old_y1, new_y1; + int y0, old_y1, new_y1; int from, to; + int line_from = cursor.line_from; if (n > 0) from = cursor.from, to = from + n; @@ -942,6 +940,10 @@ delete_char (int n) update_top (top.from); update_cursor (from, 1); + y0 = cur.y0; + if (line_from != cursor.line_from) + y0 -= 1; + TEXT_EXTENTS (cur.from, bol (to, 1), rect); new_y1 = cur.y0 + rect.height; @@ -956,6 +958,7 @@ insert_chars (MText *newtext) int n = mtext_len (newtext); MDrawMetric rect; int y0, old_y1, new_y1; + int line_from; if (SELECTEDP ()) { @@ -966,9 +969,15 @@ insert_chars (MText *newtext) } y0 = cur.y0; + if (cursor.line_from > 0 + && mtext_ref_char (mt, cursor.line_from - 1) != '\n') + y0 -= control.min_line_descent; + TEXT_EXTENTS (cur.from, bol (cur.to - 1, 1), rect); old_y1 = y0 + rect.height; + line_from = cursor.line_from; + /* Now insert chars. */ mtext_ins (mt, cursor.from, newtext); nchars += n; @@ -984,6 +993,57 @@ insert_chars (MText *newtext) } +int +word_constituent_p (int c) +{ + MSymbol category = (MSymbol) mchar_get_prop (c, Mcategory); + char *name = category != Mnil ? msymbol_name (category) : NULL; + + return (name && (name[0] == 'L' || name[0] == 'M')); +} + + +void +forward_word () +{ + int pos = cursor.from; + + while (pos < nchars && ! word_constituent_p (mtext_ref_char (mt, pos))) + pos++; + if (pos < nchars) + { + MTextProperty *prop = mtext_get_property (mt, pos, Mword); + + if (prop) + pos = mtext_property_end (prop); + else + while (pos < nchars && word_constituent_p (mtext_ref_char (mt, pos))) + pos++; + } + update_cursor (pos, 0); +} + +void +backward_word () +{ + int pos = cursor.from; + + while (pos > 0 && ! word_constituent_p (mtext_ref_char (mt, pos - 1))) + pos--; + if (pos > 0) + { + MTextProperty *prop = mtext_get_property (mt, pos - 1, Mword); + + if (prop) + pos = mtext_property_start (prop); + else + while (pos > 0 && word_constituent_p (mtext_ref_char (mt, pos - 1))) + pos--; + } + update_cursor (pos, 0); +} + + /* Convert the currently selected text to UTF8-STRING or COMPOUND-TEXT. It is called when someone requests the current value of the selection. */ @@ -1589,6 +1649,22 @@ KeyProc (Widget w, XEvent *event, String *str, Cardinal *num) ScrollProc (w, NULL, (XtPointer) -1); break; + case XK_b: + if (key_event->state >= Mod1Mask) + { + lose_selection (NULL, NULL); + backward_word (); + break; + } + + case XK_f: + if (key_event->state >= Mod1Mask) + { + lose_selection (NULL, NULL); + forward_word (); + break; + } + default: if (ret > 0) { @@ -1735,8 +1811,6 @@ BidiProc (Widget w, XtPointer client_data, XtPointer call_data) redraw (0, win_height, 1, 0); } -extern int line_break (MText *mt, int pos, int from, int to, int line, int y); - void LineBreakProc (Widget w, XtPointer client_data, XtPointer call_data) { @@ -1748,7 +1822,7 @@ LineBreakProc (Widget w, XtPointer client_data, XtPointer call_data) else { control.max_line_width = win_width; - control.line_break = (data == 1 ? NULL : line_break); + control.line_break = (data == 1 ? NULL : mdraw_default_line_break); } for (i = 0; i < 3; i++) { @@ -1764,6 +1838,25 @@ LineBreakProc (Widget w, XtPointer client_data, XtPointer call_data) } void +FilterProc (Widget w, XtPointer client_data, XtPointer call_data) +{ + char *filter_module = (char *) client_data; + void *handle; + void (*func) (MText *, int, int); + + if (! SELECTEDP ()) + return; + handle = dlopen (filter_module, RTLD_NOW); + if (! handle) + return; + *(void **) (&func) = dlsym (handle, "filter"); + if (func) + (*func) (mt, mtext_property_start (selection), + mtext_property_end (selection)); + dlclose (handle); +} + +void CursorProc (Widget w, XtPointer client_data, XtPointer call_data) { int data = (int) client_data; @@ -2420,6 +2513,7 @@ main (int argc, char **argv) int font_width, font_ascent, font_descent; int with_xim = 0; int i, j; + char *filter = NULL; setlocale (LC_ALL, ""); /* Create the top shell. */ @@ -2468,6 +2562,11 @@ main (int argc, char **argv) { with_xim = 1; } + else if (! strcmp (argv[i], "--filter")) + { + i++; + filter = argv[i]; + } else if (argv[i][0] != '-') { filename = strdup (argv[i]); @@ -2492,6 +2591,8 @@ main (int argc, char **argv) nchars = mtext_len (mt); + Mword = msymbol ("word"); + { MFace *face = mface (); @@ -2749,6 +2850,14 @@ main (int argc, char **argv) for (i = 0; i < num_input_methods + 2; i++) InputMethodMenus[i] = menus[i].w; + if (filter) + { + SetMenu (menus[0], 0, filter, NULL, FilterProc, filter, 0); + w = create_menu_button (ShellWidget, HeadWidget, w, "Filter", + "Filter Menu", menus, 1, + "Select filter to run"); + } + input_status_width = font_width * 8; input_status_height = (font_ascent + font_descent) * 2.4; input_status_pixmap = XCreatePixmap (display, RootWindow (display, screen), -- 1.7.10.4