aboutsummaryrefslogtreecommitdiffstats
path: root/src/cmds.c
diff options
context:
space:
mode:
authorStefan Monnier2010-09-13 16:40:48 +0200
committerStefan Monnier2010-09-13 16:40:48 +0200
commitcc390e46c7ba95b76ea133d98fd386214cd01709 (patch)
treeead4400d22bd07214b782ff7e46e79d473fac419 /src/cmds.c
parentc566235d981eba73c88bbff00b6a1d88360b6e9f (diff)
parentc5fe4acb5fb456d6e8e147d8bc7981ce56c5c03d (diff)
downloademacs-cc390e46c7ba95b76ea133d98fd386214cd01709.tar.gz
emacs-cc390e46c7ba95b76ea133d98fd386214cd01709.zip
Merge from trunk
Diffstat (limited to 'src/cmds.c')
-rw-r--r--src/cmds.c144
1 files changed, 53 insertions, 91 deletions
diff --git a/src/cmds.c b/src/cmds.c
index 4cb6ca199e7..f12e759b7a6 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -32,17 +32,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "dispextern.h" 32#include "dispextern.h"
33#include "frame.h" 33#include "frame.h"
34 34
35Lisp_Object Qkill_forward_chars, Qkill_backward_chars, Vblink_paren_function; 35Lisp_Object Qkill_forward_chars, Qkill_backward_chars;
36 36
37/* A possible value for a buffer's overwrite-mode variable. */ 37/* A possible value for a buffer's overwrite-mode variable. */
38Lisp_Object Qoverwrite_mode_binary; 38Lisp_Object Qoverwrite_mode_binary;
39 39
40/* Non-nil means put this face on the next self-inserting character. */
41Lisp_Object Vself_insert_face;
42
43/* This is the command that set up Vself_insert_face. */
44Lisp_Object Vself_insert_face_command;
45
46static int internal_self_insert (int, int); 40static int internal_self_insert (int, int);
47 41
48DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0, 42DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0,
@@ -310,50 +304,31 @@ After insertion, the value of `auto-fill-function' is called if the
310 { 304 {
311 int character = translate_char (Vtranslation_table_for_input, 305 int character = translate_char (Vtranslation_table_for_input,
312 XINT (last_command_event)); 306 XINT (last_command_event));
313 if (XINT (n) >= 2 && NILP (current_buffer->overwrite_mode)) 307 int val = internal_self_insert (character, XFASTINT (n));
314 { 308 if (val == 2)
315 XSETFASTINT (n, XFASTINT (n) - 2); 309 nonundocount = 0;
316 /* The first one might want to expand an abbrev. */ 310 frame_make_pointer_invisible ();
317 internal_self_insert (character, 1);
318 /* The bulk of the copies of this char can be inserted simply.
319 We don't have to handle a user-specified face specially
320 because it will get inherited from the first char inserted. */
321 Finsert_char (make_number (character), n, Qt);
322 /* The last one might want to auto-fill. */
323 internal_self_insert (character, 0);
324 }
325 else
326 while (XINT (n) > 0)
327 {
328 int val;
329 /* Ok since old and new vals both nonneg */
330 XSETFASTINT (n, XFASTINT (n) - 1);
331 val = internal_self_insert (character, XFASTINT (n) != 0);
332 if (val == 2)
333 nonundocount = 0;
334 frame_make_pointer_invisible ();
335 }
336 } 311 }
337 312
338 return Qnil; 313 return Qnil;
339} 314}
340 315
341/* Insert character C. If NOAUTOFILL is nonzero, don't do autofill 316/* Insert N times character C
342 even if it is enabled.
343 317
344 If this insertion is suitable for direct output (completely simple), 318 If this insertion is suitable for direct output (completely simple),
345 return 0. A value of 1 indicates this *might* not have been simple. 319 return 0. A value of 1 indicates this *might* not have been simple.
346 A value of 2 means this did things that call for an undo boundary. */ 320 A value of 2 means this did things that call for an undo boundary. */
347 321
348static Lisp_Object Qexpand_abbrev; 322static Lisp_Object Qexpand_abbrev;
323static Lisp_Object Qpost_self_insert_hook, Vpost_self_insert_hook;
349 324
350static int 325static int
351internal_self_insert (int c, int noautofill) 326internal_self_insert (int c, int n)
352{ 327{
353 int hairy = 0; 328 int hairy = 0;
354 Lisp_Object tem; 329 Lisp_Object tem;
355 register enum syntaxcode synt; 330 register enum syntaxcode synt;
356 Lisp_Object overwrite, string; 331 Lisp_Object overwrite;
357 /* Length of multi-byte form of C. */ 332 /* Length of multi-byte form of C. */
358 int len; 333 int len;
359 /* Working buffer and pointer for multi-byte form of C. */ 334 /* Working buffer and pointer for multi-byte form of C. */
@@ -396,32 +371,22 @@ internal_self_insert (int c, int noautofill)
396 /* This is the character after point. */ 371 /* This is the character after point. */
397 int c2 = FETCH_CHAR (PT_BYTE); 372 int c2 = FETCH_CHAR (PT_BYTE);
398 373
399 /* Column the cursor should be placed at after this insertion.
400 The correct value should be calculated only when necessary. */
401 int target_clm = 0;
402
403 /* Overwriting in binary-mode always replaces C2 by C. 374 /* Overwriting in binary-mode always replaces C2 by C.
404 Overwriting in textual-mode doesn't always do that. 375 Overwriting in textual-mode doesn't always do that.
405 It inserts newlines in the usual way, 376 It inserts newlines in the usual way,
406 and inserts any character at end of line 377 and inserts any character at end of line
407 or before a tab if it doesn't use the whole width of the tab. */ 378 or before a tab if it doesn't use the whole width of the tab. */
408 if (EQ (overwrite, Qoverwrite_mode_binary) 379 if (EQ (overwrite, Qoverwrite_mode_binary))
409 || (c != '\n' 380 chars_to_delete = n;
410 && c2 != '\n' 381 else if (c != '\n' && c2 != '\n')
411 && ! (c2 == '\t'
412 && XINT (current_buffer->tab_width) > 0
413 && XFASTINT (current_buffer->tab_width) < 20
414 && (target_clm = ((int) current_column () /* iftc */
415 + XINT (Fchar_width (make_number (c)))),
416 target_clm % XFASTINT (current_buffer->tab_width)))))
417 { 382 {
418 int pos = PT; 383 int pos = PT;
419 int pos_byte = PT_BYTE; 384 int pos_byte = PT_BYTE;
385 /* Column the cursor should be placed at after this insertion.
386 The correct value should be calculated only when necessary. */
387 int target_clm = ((int) current_column () /* iftc */
388 + n * XINT (Fchar_width (make_number (c))));
420 389
421 if (target_clm == 0)
422 chars_to_delete = 1;
423 else
424 {
425 /* The actual cursor position after the trial of moving 390 /* The actual cursor position after the trial of moving
426 to column TARGET_CLM. It is greater than TARGET_CLM 391 to column TARGET_CLM. It is greater than TARGET_CLM
427 if the TARGET_CLM is middle of multi-column 392 if the TARGET_CLM is middle of multi-column
@@ -433,14 +398,18 @@ internal_self_insert (int c, int noautofill)
433 chars_to_delete = PT - pos; 398 chars_to_delete = PT - pos;
434 399
435 if (actual_clm > target_clm) 400 if (actual_clm > target_clm)
436 { 401 { /* We will delete too many columns. Let's fill columns
437 /* We will delete too many columns. Let's fill columns
438 by spaces so that the remaining text won't move. */ 402 by spaces so that the remaining text won't move. */
403 EMACS_INT actual = PT_BYTE;
404 DEC_POS (actual);
405 if (FETCH_CHAR (actual) == '\t')
406 /* Rather than add spaces, let's just keep the tab. */
407 chars_to_delete--;
408 else
439 spaces_to_insert = actual_clm - target_clm; 409 spaces_to_insert = actual_clm - target_clm;
440 } 410 }
441 } 411
442 SET_PT_BOTH (pos, pos_byte); 412 SET_PT_BOTH (pos, pos_byte);
443 hairy = 2;
444 } 413 }
445 hairy = 2; 414 hairy = 2;
446 } 415 }
@@ -451,10 +420,10 @@ internal_self_insert (int c, int noautofill)
451 && synt != Sword 420 && synt != Sword
452 && NILP (current_buffer->read_only) 421 && NILP (current_buffer->read_only)
453 && PT > BEGV 422 && PT > BEGV
454 && (!NILP (current_buffer->enable_multibyte_characters) 423 && (SYNTAX (!NILP (current_buffer->enable_multibyte_characters)
455 ? SYNTAX (XFASTINT (Fprevious_char ())) == Sword 424 ? XFASTINT (Fprevious_char ())
456 : (SYNTAX (UNIBYTE_TO_CHAR (XFASTINT (Fprevious_char ()))) 425 : UNIBYTE_TO_CHAR (XFASTINT (Fprevious_char ())))
457 == Sword))) 426 == Sword))
458 { 427 {
459 int modiff = MODIFF; 428 int modiff = MODIFF;
460 Lisp_Object sym; 429 Lisp_Object sym;
@@ -479,16 +448,30 @@ internal_self_insert (int c, int noautofill)
479 448
480 if (chars_to_delete) 449 if (chars_to_delete)
481 { 450 {
482 string = make_string_from_bytes (str, 1, len); 451 int mc = ((NILP (current_buffer->enable_multibyte_characters)
452 && SINGLE_BYTE_CHAR_P (c))
453 ? UNIBYTE_TO_CHAR (c) : c);
454 Lisp_Object string = Fmake_string (make_number (n), make_number (mc));
455
483 if (spaces_to_insert) 456 if (spaces_to_insert)
484 { 457 {
485 tem = Fmake_string (make_number (spaces_to_insert), 458 tem = Fmake_string (make_number (spaces_to_insert),
486 make_number (' ')); 459 make_number (' '));
487 string = concat2 (tem, string); 460 string = concat2 (string, tem);
488 } 461 }
489 462
490 replace_range (PT, PT + chars_to_delete, string, 1, 1, 1); 463 replace_range (PT, PT + chars_to_delete, string, 1, 1, 1);
491 Fforward_char (make_number (1 + spaces_to_insert)); 464 Fforward_char (make_number (n + spaces_to_insert));
465 }
466 else if (n > 1)
467 {
468 USE_SAFE_ALLOCA;
469 unsigned char *strn, *p;
470 SAFE_ALLOCA (strn, unsigned char*, n * len);
471 for (p = strn; n > 0; n--, p += len)
472 memcpy (p, str, len);
473 insert_and_inherit (strn, p - strn);
474 SAFE_FREE ();
492 } 475 }
493 else 476 else
494 insert_and_inherit (str, len); 477 insert_and_inherit (str, len);
@@ -496,7 +479,6 @@ internal_self_insert (int c, int noautofill)
496 if ((CHAR_TABLE_P (Vauto_fill_chars) 479 if ((CHAR_TABLE_P (Vauto_fill_chars)
497 ? !NILP (CHAR_TABLE_REF (Vauto_fill_chars, c)) 480 ? !NILP (CHAR_TABLE_REF (Vauto_fill_chars, c))
498 : (c == ' ' || c == '\n')) 481 : (c == ' ' || c == '\n'))
499 && !noautofill
500 && !NILP (current_buffer->auto_fill_function)) 482 && !NILP (current_buffer->auto_fill_function))
501 { 483 {
502 Lisp_Object tem; 484 Lisp_Object tem;
@@ -514,22 +496,9 @@ internal_self_insert (int c, int noautofill)
514 hairy = 2; 496 hairy = 2;
515 } 497 }
516 498
517 /* If previous command specified a face to use, use it. */ 499 /* Run hooks for electric keys. */
518 if (!NILP (Vself_insert_face) 500 call1 (Vrun_hooks, Qpost_self_insert_hook);
519 && EQ (current_kboard->Vlast_command, Vself_insert_face_command))
520 {
521 Fput_text_property (make_number (PT - 1), make_number (PT),
522 Qface, Vself_insert_face, Qnil);
523 Vself_insert_face = Qnil;
524 }
525 501
526 if ((synt == Sclose || synt == Smath)
527 && !NILP (Vblink_paren_function) && INTERACTIVE
528 && !noautofill)
529 {
530 call0 (Vblink_paren_function);
531 hairy = 2;
532 }
533 return hairy; 502 return hairy;
534} 503}
535 504
@@ -550,20 +519,13 @@ syms_of_cmds (void)
550 Qexpand_abbrev = intern_c_string ("expand-abbrev"); 519 Qexpand_abbrev = intern_c_string ("expand-abbrev");
551 staticpro (&Qexpand_abbrev); 520 staticpro (&Qexpand_abbrev);
552 521
553 DEFVAR_LISP ("self-insert-face", &Vself_insert_face, 522 Qpost_self_insert_hook = intern_c_string ("post-self-insert-hook");
554 doc: /* If non-nil, set the face of the next self-inserting character to this. 523 staticpro (&Qpost_self_insert_hook);
555See also `self-insert-face-command'. */);
556 Vself_insert_face = Qnil;
557
558 DEFVAR_LISP ("self-insert-face-command", &Vself_insert_face_command,
559 doc: /* This is the command that set up `self-insert-face'.
560If `last-command' does not equal this value, we ignore `self-insert-face'. */);
561 Vself_insert_face_command = Qnil;
562 524
563 DEFVAR_LISP ("blink-paren-function", &Vblink_paren_function, 525 DEFVAR_LISP ("post-self-insert-hook", &Vpost_self_insert_hook,
564 doc: /* Function called, if non-nil, whenever a close parenthesis is inserted. 526 doc: /* Hook run at the end of `self-insert-command'.
565More precisely, a char with closeparen syntax is self-inserted. */); 527This run is run after inserting the charater. */);
566 Vblink_paren_function = Qnil; 528 Vpost_self_insert_hook = Qnil;
567 529
568 defsubr (&Sforward_point); 530 defsubr (&Sforward_point);
569 defsubr (&Sforward_char); 531 defsubr (&Sforward_char);