Mercurial > hg > xemacs-beta
comparison src/indent.c @ 272:c5d627a313b1 r21-0b34
Import from CVS: tag r21-0b34
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:28:48 +0200 |
parents | 3d6bfa290dbd |
children | 6330739388db |
comparison
equal
deleted
inserted
replaced
271:c7b7086b0a39 | 272:c5d627a313b1 |
---|---|
527 pos->contin ? Qt : Qnil); | 527 pos->contin ? Qt : Qnil); |
528 } | 528 } |
529 | 529 |
530 #endif /* 0 */ | 530 #endif /* 0 */ |
531 | 531 |
532 /* Helper for vmotion_1 - compute vertical pixel motion between | |
533 START and END in the line start cache CACHE. This just sums | |
534 the line heights, including both the starting and ending lines. | |
535 */ | |
536 static int | |
537 vpix_motion (line_start_cache_dynarr *cache, int start, int end) | |
538 { | |
539 int i, vpix; | |
540 | |
541 assert (start <= end); | |
542 assert (start >= 0); | |
543 assert (end < Dynarr_length (cache)); | |
544 | |
545 vpix = 0; | |
546 for (i = start; i <= end; i++) | |
547 vpix += Dynarr_atp (cache, i)->height; | |
548 | |
549 return vpix; | |
550 } | |
551 | |
552 /***************************************************************************** | |
553 vmotion_1 | |
554 | |
555 Given a starting position ORIG, move point VTARGET lines in WINDOW. | |
556 Returns the new value for point. If the arg ret_vpos is not nil, it is | |
557 taken to be a pointer to an int and the number of lines actually moved is | |
558 returned in it. If the arg ret_vpix is not nil, it is taken to be a | |
559 pointer to an int and the vertical pixel height of the motion which | |
560 took place is returned in it. | |
561 ****************************************************************************/ | |
562 static Bufpos | |
563 vmotion_1 (struct window *w, Bufpos orig, int vtarget, | |
564 int *ret_vpos, int *ret_vpix) | |
565 { | |
566 struct buffer *b = XBUFFER (w->buffer); | |
567 int elt; | |
568 | |
569 elt = point_in_line_start_cache (w, orig, (vtarget < 0 | |
570 ? -vtarget | |
571 : vtarget)); | |
572 | |
573 /* #### This assertion must be true before the if statements are hit | |
574 but may possibly be wrong after the call to | |
575 point_in_line_start_cache if orig is outside of the visible | |
576 region of the buffer. Handle this. */ | |
577 assert (elt >= 0); | |
578 | |
579 /* Moving downward. */ | |
580 if (vtarget > 0) | |
581 { | |
582 int cur_line = Dynarr_length (w->line_start_cache) - 1 - elt; | |
583 Bufpos ret_pt; | |
584 | |
585 if (cur_line > vtarget) | |
586 cur_line = vtarget; | |
587 | |
588 /* The traditional FSF behavior is to return the end of buffer | |
589 position if we couldn't move far enough because we hit it. */ | |
590 if (cur_line < vtarget) | |
591 ret_pt = BUF_ZV (b); | |
592 else | |
593 ret_pt = Dynarr_atp (w->line_start_cache, cur_line + elt)->start; | |
594 | |
595 while (ret_pt > BUF_ZV (b) && cur_line > 0) | |
596 { | |
597 cur_line--; | |
598 ret_pt = Dynarr_atp (w->line_start_cache, cur_line + elt)->start; | |
599 } | |
600 | |
601 if (ret_vpos) *ret_vpos = cur_line; | |
602 if (ret_vpix) | |
603 *ret_vpix = vpix_motion (w->line_start_cache, elt, cur_line + elt); | |
604 return ret_pt; | |
605 } | |
606 else if (vtarget < 0) | |
607 { | |
608 if (elt < -vtarget) | |
609 { | |
610 if (ret_vpos) *ret_vpos = -elt; | |
611 if (ret_vpix) | |
612 *ret_vpix = vpix_motion (w->line_start_cache, 0, elt); | |
613 /* #### This should be BUF_BEGV (b), right? */ | |
614 return Dynarr_atp (w->line_start_cache, 0)->start; | |
615 } | |
616 else | |
617 { | |
618 if (ret_vpos) *ret_vpos = vtarget; | |
619 if (ret_vpix) | |
620 *ret_vpix = vpix_motion (w->line_start_cache, elt + vtarget, elt); | |
621 return Dynarr_atp (w->line_start_cache, elt + vtarget)->start; | |
622 } | |
623 } | |
624 else | |
625 { | |
626 /* No vertical motion requested so we just return the position | |
627 of the beginning of the current line. */ | |
628 if (ret_vpos) *ret_vpos = 0; | |
629 if (ret_vpix) | |
630 *ret_vpix = vpix_motion (w->line_start_cache, elt, elt); | |
631 | |
632 return Dynarr_atp (w->line_start_cache, elt)->start; | |
633 } | |
634 | |
635 RETURN_NOT_REACHED(0) /* shut up compiler */ | |
636 } | |
637 | |
532 /***************************************************************************** | 638 /***************************************************************************** |
533 vmotion | 639 vmotion |
534 | 640 |
535 Given a starting position ORIG, move point VTARGET lines in WINDOW. | 641 Given a starting position ORIG, move point VTARGET lines in WINDOW. |
536 Returns the new value for point. If the arg ret_vpos is not nil, it is | 642 Returns the new value for point. If the arg ret_vpos is not nil, it is |
538 returned in it. | 644 returned in it. |
539 ****************************************************************************/ | 645 ****************************************************************************/ |
540 Bufpos | 646 Bufpos |
541 vmotion (struct window *w, Bufpos orig, int vtarget, int *ret_vpos) | 647 vmotion (struct window *w, Bufpos orig, int vtarget, int *ret_vpos) |
542 { | 648 { |
543 struct buffer *b = XBUFFER (w->buffer); | 649 return vmotion_1 (w, orig, vtarget, ret_vpos, NULL); |
544 int elt; | |
545 | |
546 elt = point_in_line_start_cache (w, orig, (vtarget < 0 | |
547 ? -vtarget | |
548 : vtarget)); | |
549 | |
550 /* #### This assertion must be true before the if statements are hit | |
551 but may possibly be wrong after the call to | |
552 point_in_line_start_cache if orig is outside of the visible | |
553 region of the buffer. Handle this. */ | |
554 assert (elt >= 0); | |
555 | |
556 /* Moving downward. */ | |
557 if (vtarget > 0) | |
558 { | |
559 int cur_line = Dynarr_length (w->line_start_cache) - 1 - elt; | |
560 Bufpos ret_pt; | |
561 | |
562 if (cur_line > vtarget) | |
563 cur_line = vtarget; | |
564 | |
565 /* The traditional FSF behavior is to return the end of buffer | |
566 position if we couldn't move far enough because we hit it. */ | |
567 if (cur_line < vtarget) | |
568 ret_pt = BUF_ZV (b); | |
569 else | |
570 ret_pt = Dynarr_atp (w->line_start_cache, cur_line + elt)->start; | |
571 | |
572 while (ret_pt > BUF_ZV (b) && cur_line > 0) | |
573 { | |
574 cur_line--; | |
575 ret_pt = Dynarr_atp (w->line_start_cache, cur_line + elt)->start; | |
576 } | |
577 | |
578 if (ret_vpos) *ret_vpos = cur_line; | |
579 return ret_pt; | |
580 } | |
581 else if (vtarget < 0) | |
582 { | |
583 if (elt < -vtarget) | |
584 { | |
585 if (ret_vpos) *ret_vpos = -elt; | |
586 /* #### This should be BUF_BEGV (b), right? */ | |
587 return Dynarr_atp (w->line_start_cache, 0)->start; | |
588 } | |
589 else | |
590 { | |
591 if (ret_vpos) *ret_vpos = vtarget; | |
592 return Dynarr_atp (w->line_start_cache, elt + vtarget)->start; | |
593 } | |
594 } | |
595 else | |
596 { | |
597 /* No vertical motion requested so we just return the position | |
598 of the beginning of the current line. */ | |
599 if (ret_vpos) *ret_vpos = 0; | |
600 | |
601 return Dynarr_atp (w->line_start_cache, elt)->start; | |
602 } | |
603 | |
604 RETURN_NOT_REACHED(0) /* shut up compiler */ | |
605 } | 650 } |
606 | 651 |
607 DEFUN ("vertical-motion", Fvertical_motion, 1, 2, 0, /* | 652 DEFUN ("vertical-motion", Fvertical_motion, 1, 2, 0, /* |
608 Move to start of frame line LINES lines down. | 653 Move to start of frame line LINES lines down. |
609 If LINES is negative, this is moving up. | 654 If LINES is negative, this is moving up. |
638 | 683 |
639 /* Note that the buffer's point is set, not the window's point. */ | 684 /* Note that the buffer's point is set, not the window's point. */ |
640 BUF_SET_PT (XBUFFER (w->buffer), bufpos); | 685 BUF_SET_PT (XBUFFER (w->buffer), bufpos); |
641 | 686 |
642 return make_int (vpos); | 687 return make_int (vpos); |
688 } | |
689 } | |
690 | |
691 DEFUN ("vertical-motion-pixels", Fvertical_motion_pixels, 1, 2, 0, /* | |
692 Move to start of frame line LINES lines down. | |
693 If LINES is negative, this is moving up. | |
694 | |
695 This function is identical in behavior to `vertical-motion' | |
696 except that the vertical pixel height of the motion which | |
697 took place is returned instead of the actual number of lines | |
698 moved. A motion of zero lines returns the height of the | |
699 current line. | |
700 | |
701 The optional second argument WINDOW specifies the window to use | |
702 for parameters such as width, horizontal scrolling, and so on. | |
703 The default is the selected window. Note that this function | |
704 sets WINDOW's buffer's point, not WINDOW's point. | |
705 */ | |
706 (lines, window)) | |
707 { | |
708 if (NILP (window)) | |
709 window = Fselected_window (Qnil); | |
710 CHECK_WINDOW (window); | |
711 { | |
712 Bufpos bufpos; | |
713 int vpix; | |
714 struct window *w = XWINDOW (window); | |
715 | |
716 CHECK_INT (lines); | |
717 | |
718 bufpos = vmotion_1 (XWINDOW (window), BUF_PT (XBUFFER (w->buffer)), | |
719 XINT (lines), NULL, &vpix); | |
720 | |
721 /* Note that the buffer's point is set, not the window's point. */ | |
722 BUF_SET_PT (XBUFFER (w->buffer), bufpos); | |
723 | |
724 return make_int (vpix); | |
643 } | 725 } |
644 } | 726 } |
645 | 727 |
646 | 728 |
647 void | 729 void |
653 DEFSUBR (Fmove_to_column); | 735 DEFSUBR (Fmove_to_column); |
654 #if 0 /* #### */ | 736 #if 0 /* #### */ |
655 DEFSUBR (Fcompute_motion); | 737 DEFSUBR (Fcompute_motion); |
656 #endif | 738 #endif |
657 DEFSUBR (Fvertical_motion); | 739 DEFSUBR (Fvertical_motion); |
740 DEFSUBR (Fvertical_motion_pixels); | |
658 } | 741 } |
659 | 742 |
660 void | 743 void |
661 vars_of_indent (void) | 744 vars_of_indent (void) |
662 { | 745 { |