(fix_submap_inheritance, get_keyelt, store_in_keymap,
[bpt/emacs.git] / src / xdisp.c
index 495e1f4..b9128fa 100644 (file)
@@ -1,5 +1,5 @@
 /* Display generation from window structure and buffer text.
-   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 1997
+   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 1998
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -51,8 +51,6 @@ extern int command_loop_level;
 
 extern int minibuffer_auto_raise;
 
-extern int nonascii_insert_offset;
-
 extern Lisp_Object Qface;
 
 extern Lisp_Object Voverriding_local_map;
@@ -292,7 +290,9 @@ message_dolog (m, len, nlflag, multibyte)
       int old_windows_or_buffers_changed = windows_or_buffers_changed;
       int point_at_end = 0;
       int zv_at_end = 0;
+      Lisp_Object old_deactivate_mark;
 
+      old_deactivate_mark = Vdeactivate_mark;
       oldbuf = current_buffer;
       Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
       current_buffer->undo_list = Qt;
@@ -301,9 +301,9 @@ message_dolog (m, len, nlflag, multibyte)
       oldbegv = Fpoint_min_marker ();
       oldzv = Fpoint_max_marker ();
 
-      if (oldpoint == Z)
+      if (PT == Z)
        point_at_end = 1;
-      if (oldzv == Z)
+      if (ZV == Z)
        zv_at_end = 1;
 
       BEGV = BEG;
@@ -334,15 +334,13 @@ message_dolog (m, len, nlflag, multibyte)
       else if (! multibyte
               && ! NILP (current_buffer->enable_multibyte_characters))
        {
-         int c, i = 0;
+         int i = 0;
+         unsigned char *msg = (unsigned char *) m;
          /* Convert a single-byte string to multibyte
             for the *Message* buffer.  */
          while (i < len)
            {
-             c = m[i++];
-             /* Convert non-ascii chars as if for self-insert.  */
-             if (c >= 0200 && c <= 0377)
-               c += nonascii_insert_offset;
+             int c = unibyte_char_to_multibyte (msg[i++]);
              insert_char (c);
            }
        }
@@ -360,12 +358,12 @@ message_dolog (m, len, nlflag, multibyte)
 
          if (this_bol > BEG)
            {
-             scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
+             scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
              prev_bol = PT;
              prev_bol_byte = PT_BYTE;
 
-             dup = message_log_check_duplicate (prev_bol, this_bol,
-                                                prev_bol_byte, this_bol_byte);
+             dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
+                                                this_bol, this_bol_byte);
              if (dup)
                {
                  del_range_both (prev_bol, prev_bol_byte,
@@ -418,6 +416,7 @@ message_dolog (m, len, nlflag, multibyte)
       set_buffer_internal (oldbuf);
       windows_or_buffers_changed = old_windows_or_buffers_changed;
       message_log_need_newline = !nlflag;
+      Vdeactivate_mark = old_deactivate_mark;
     }
 }
 
@@ -930,7 +929,7 @@ prepare_menu_bars ()
       Lisp_Object tail, frame;
       int count = specpdl_ptr - specpdl;
 
-      record_unwind_protect (Fstore_match_data, Fmatch_data (Qnil, Qnil));
+      record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
 
       FOR_EACH_FRAME (tail, frame)
        {
@@ -1633,7 +1632,7 @@ update_menu_bar (f, save_match_data)
 
          set_buffer_internal_1 (XBUFFER (w->buffer));
          if (save_match_data)
-           record_unwind_protect (Fstore_match_data, Fmatch_data (Qnil, Qnil));
+           record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
          if (NILP (Voverriding_local_map_menu_flag))
            {
              specbind (Qoverriding_terminal_local_map, Qnil);
@@ -2524,7 +2523,6 @@ try_window_id (window)
   int selective = (INTEGERP (current_buffer->selective_display)
                   ? XINT (current_buffer->selective_display)
                   : !NILP (current_buffer->selective_display) ? -1 : 0);
-
   struct position val, bp, ep, xp, pp;
   int scroll_amount = 0;
   int delta;
@@ -2603,8 +2601,7 @@ try_window_id (window)
       val.hpos = bp.prevhpos - width + lmargin;
       val.tab_offset = bp.tab_offset + bp.prevhpos - width;
       did_motion = 1;
-      pos--;
-      DEC_POS (pos_byte);
+      DEC_BOTH (pos, pos_byte);
     }
 
   bp.vpos = vpos;
@@ -2867,8 +2864,7 @@ try_window_id (window)
        {
          val.hpos = xp.prevhpos - width + lmargin;
          val.tab_offset = xp.tab_offset + bp.prevhpos - width;
-         pos--;
-         DEC_POS (pos_byte);
+         DEC_BOTH (pos, pos_byte);
        }
 
       blank_end_of_window = 1;
@@ -3121,6 +3117,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
   register GLYPH *leftmargin;
   register GLYPH *p1prev;
   register GLYPH *p1start;
+  GLYPH *p1_wide_column_end = (GLYPH *) 0;
   int prevpos, prevpos_byte;
   int *charstart;
   FRAME_PTR f = XFRAME (w->frame);
@@ -3275,10 +3272,8 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
           || left_edge->hpos > 0)
         {
           pos = left_edge->bufpos;
-         /* Since this should not be a valid multibyte character, we
-             can decrease POS by 1.  */
-         pos--;
-         pos_byte = left_edge->bytepos - 1;
+         pos_byte = left_edge->bytepos;
+         DEC_BOTH (pos, pos_byte);
           hpos = left_edge->prevhpos;
         }
       else
@@ -3330,6 +3325,8 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
 
   while (p1 < endp)
     {
+      int eat_following_binary_data;
+
       if (pos >= pause)
        {
          int e_t_h;
@@ -3424,6 +3421,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
                      cursor_hpos = p1 - leftmargin;
                    }
                  pos = next_boundary;
+                 pos_byte = CHAR_TO_BYTE (pos);
                  last_invis_skip = pos;
                  last_invis_prop = prop;
                }
@@ -3534,6 +3532,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
        break;
 
       p1prev = p1;
+      p1_wide_column_end = (GLYPH *) 0;
 
       if (multibyte)
        c = STRING_CHAR_AND_LENGTH (p, limit_byte - pos_byte, len), p += len;
@@ -3572,10 +3571,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
              int opoint = PT, opoint_byte = PT_BYTE;
 
              invis = 1;
-             if (! NILP (current_buffer->enable_multibyte_characters))
-               INC_BOTH (pos, pos_byte);
-             else
-               pos++, pos_byte++;
+             INC_BOTH (pos, pos_byte);
              scan_newline (pos, pos_byte, ZV, ZV_BYTE, 1, 1);
              if (FETCH_BYTE (pos_byte - 1) == '\n')
                {
@@ -3718,24 +3714,32 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
       else if (len == 1)
        {
          /* C is not a multibyte character.  */
-         if (p1 >= leftmargin)
-           *p1 = (fix_glyph
-                  (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
-                       && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp)))
-                       ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
-                   current_face)
-                  | rev_dir_bit);
-         p1++;
-         if (p1 >= leftmargin && p1 < endp)
-           *p1 = MAKE_GLYPH (f, (c >> 6) + '0', current_face) | rev_dir_bit;
-         p1++;
-         if (p1 >= leftmargin && p1 < endp)
-           *p1 = (MAKE_GLYPH (f, (7 & (c >> 3)) + '0', current_face)
-                  | rev_dir_bit);
-         p1++;
-         if (p1 >= leftmargin && p1 < endp)
-           *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face) | rev_dir_bit;
-         p1++;
+         eat_following_binary_data = multibyte && BASE_LEADING_CODE_P (c);
+         
+       label_display_binary_data:
+         do {
+           if (p1 >= leftmargin && p1 < endp)
+             *p1 = (fix_glyph
+                    (f, (dp && INTEGERP (DISP_ESCAPE_GLYPH (dp))
+                         && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (dp)))
+                         ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'),
+                     current_face)
+                    | rev_dir_bit);
+           p1++;
+           if (p1 >= leftmargin && p1 < endp)
+             *p1 = MAKE_GLYPH (f, (c >> 6) + '0', current_face) | rev_dir_bit;
+           p1++;
+           if (p1 >= leftmargin && p1 < endp)
+             *p1 = (MAKE_GLYPH (f, (7 & (c >> 3)) + '0', current_face)
+                    | rev_dir_bit);
+           p1++;
+           if (p1 >= leftmargin && p1 < endp)
+             *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face) | rev_dir_bit;
+           p1++;
+         } while (eat_following_binary_data
+                  && (pos_byte + len) < limit_byte
+                  && ! CHAR_HEAD_P (*p)
+                  && ((c = *p++), len++));
        }
       else
        {
@@ -3752,6 +3756,17 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
                *p1 = g, g |= GLYPH_MASK_PADDING;
              p1++;
            }
+
+         p1_wide_column_end = p1;
+         /* Check if binary data follows it.  */
+         if (pos_byte + len < limit_byte
+             && ! CHAR_HEAD_P (*p))
+           {
+             eat_following_binary_data = 1;
+             c = *p++;
+             len++;
+             goto label_display_binary_data;
+           }
        }
 
       prevpos = pos;
@@ -3817,17 +3832,17 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
          pos = prevpos;
          pos_byte = prevpos_byte;
 
-         if (len == 1)
-           /* C is not a multi-byte character.  We can break it and
-              start from the middle column in the next line.  So,
-              adjust VAL.HPOS to skip the columns output on this
-              line.  */
+         if (p1_wide_column_end < endp)
+           /* As ENDP is not in the middle of wide-column character,
+              we can break the line at ENDP and start from the middle
+              column in the next line.  So, adjust VAL.HPOS to skip
+              the columns output on this line.  */
            val.hpos += p1prev - endp;
          else
            {
-             /* C is a multibyte character.  Since we can't broke it
-                in the middle, the whole character should be driven
-                into the next line.  */
+             /* We displayed a wide-column character at around ENDP.
+                Since we can't broke it in the middle, the whole
+                character should be driven into the next line.  */
              /* As the result, the actual columns occupied by the
                 text on this line is less than WIDTH.  VAL.TAB_OFFSET
                 must be adjusted.  */
@@ -3902,8 +3917,7 @@ display_text_line (w, start, start_byte, vpos, hpos, taboffset, ovstr_done)
            {
              *p1++ = fix_glyph (f, continuer, 0);
              val.vpos = 0;
-             lastpos--;
-             DEC_POS (lastpos_byte);
+             DEC_BOTH (lastpos, lastpos_byte);
              val.tab_offset = taboffset + width;
            }
        }
@@ -4061,7 +4075,7 @@ display_menu_bar (w)
   Lisp_Object items, tail;
   register int vpos = 0;
   register FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
-  int maxendcol = FRAME_WIDTH (f) + WINDOW_LEFT_MARGIN (w);
+  int maxendcol = FRAME_WIDTH (f);
   int hpos = 0;
   int i;
 
@@ -5368,7 +5382,9 @@ of the top or bottom of the window.");
   mode_line_inverse_video = 1;
 
   DEFVAR_INT ("line-number-display-limit", &line_number_display_limit,
-    "*Maximum buffer size for which line number should be displayed.");
+    "*Maximum buffer size (in characters) for line number display\n\
+If the buffer is bigger than this, the line number does not appear\n\
+in the mode line..");
   line_number_display_limit = 1000000;
 
   DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,