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 {