worley@EDDIE.MIT.EDU (Dale Worley) (10/26/89)
The line-counting operations (goto-line and count-lines) don't work
correctly when selective-display is on, because they don't count ^M's
as end-of-line characters. I've modified them to handle this
correctly. In order to do this, I made a lisp-callable interface to
the search_buffer routine, called "search-buffer". This routine gives
you the fullest power of Emacs' internal search routines.
Unfortunately, I haven't had time to fully test these routines, but
they're simple enough that there shouldn't be much trouble with them.
*** search.c.orig.2 Wed Oct 25 11:23:03 1989
--- search.c Wed Oct 25 11:56:24 1989
***************
*** 942,947 ****
--- 942,1013 ----
return search_command (string, bound, noerror, count, 1, 1);
}
+ DEFUN ("search-buffer", Fsearch_buffer, Ssearch_buffer, 1, 5, 0,
+ "Arguments are STRING, POS, BOUND, N, RE.\n\
+ Search for the Nth occurrence of STRING in the current buffer,\n\
+ starting at position POS and stopping at position BOUND, treating\n\
+ STRING as a literal string if RE is false or as a regular expression\n\
+ if RE is true.\n\
+ If N is positive, searching is forward and BOUND must be greater than FROM.\n\
+ If N is negative, searching is backward and BOUND must be less than FROM.\n\
+ POS defaults to the point, BOUND defaults to the beginning/end of the buffer,\n\
+ N defaults to 1, and RE defaults to false.\n\
+ \n\
+ Returns -x if only N-x occurrences found (x > 0), or else the position\n\
+ at the beginning of the Nth occurrence (if searching backward) or the\n\
+ end (if searching forward).\n\
+ Does not move the point.")
+ (string, pos, bound, n, re)
+ Lisp_Object string, pos, bound, n, re;
+ {
+ int p, nn, lim, r;
+
+ /* string */
+ CHECK_STRING (string, 0);
+
+ /* pos defaults to point */
+ if (NULL (pos))
+ p = point;
+ else
+ {
+ CHECK_NUMBER_COERCE_MARKER (pos, 1);
+ p = XINT (pos);
+ }
+
+ /* n defaults to 1 */
+ if (NULL (n))
+ nn = 1;
+ else
+ {
+ CHECK_NUMBER (n, 3);
+ nn = XINT (n);
+ }
+
+ /* bound defaults to end of buffer */
+ if (NULL (bound))
+ lim = nn > 0 ? NumCharacters + 1 : FirstCharacter;
+ else
+ {
+ CHECK_NUMBER_COERCE_MARKER (bound, 2);
+ lim = XINT (bound);
+ if (nn > 0 ? lim < point : lim > point)
+ error ("Invalid search bound (wrong side of point)");
+ if (lim > NumCharacters + 1)
+ lim = NumCharacters + 1;
+ if (lim < FirstCharacter)
+ lim = FirstCharacter;
+ }
+
+ /* re defaults to false */
+ r = !NULL (re);
+
+ /* call search_buffer */
+ return make_number (search_buffer (string, p, lim, nn, r,
+ !NULL (bf_cur->case_fold_search) ?
+ downcase_table :
+ 0));
+ }
+
DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 3, 0,
"Replace text matched by last search with NEWTEXT.\n\
If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\
***************
*** 1291,1296 ****
--- 1357,1363 ----
defsubr (&Sword_search_backward);
defsubr (&Sre_search_forward);
defsubr (&Sre_search_backward);
+ defsubr (&Ssearch_buffer);
defsubr (&Sreplace_match);
defsubr (&Smatch_beginning);
defsubr (&Smatch_end);
*** simple.el.orig Wed Oct 25 14:14:32 1989
--- simple.el Wed Oct 25 14:17:33 1989
***************
*** 246,257 ****
(1+ (count-lines 1 (point)))))))
(defun count-lines (start end)
! "Return number of newlines between START and END."
! (save-excursion
! (save-restriction
! (narrow-to-region start end)
! (goto-char (point-min))
! (- (buffer-size) (forward-line (buffer-size))))))
(defun what-cursor-position ()
"Print info on cursor position (on screen and within buffer)."
--- 246,256 ----
(1+ (count-lines 1 (point)))))))
(defun count-lines (start end)
! "Return number of newlines between START and END.
! If selective-display is non-nil, then ^M's count as newlines also."
! (+ (point-max)
! (search-buffer (if selective-display "[\n\C-m]" "\n")
! start end (point-max) selective-display)))
(defun what-cursor-position ()
"Print info on cursor position (on screen and within buffer)."
***************
*** 354,365 ****
(next-complex-command (- n)))
(defun goto-line (arg)
! "Goto line ARG, counting from line 1 at beginning of buffer."
(interactive "NGoto line: ")
(save-restriction
(widen)
(goto-char 1)
! (forward-line (1- arg))))
;Put this on C-x u, so we can force that rather than C-_ into startup msg
(fset 'advertised-undo 'undo)
--- 353,368 ----
(next-complex-command (- n)))
(defun goto-line (arg)
! "Goto line ARG, counting from line 1 at beginning of buffer.
! If selective-display is non-nil, then ^M's count as newlines also."
(interactive "NGoto line: ")
(save-restriction
(widen)
(goto-char 1)
! (re-search-forward (if selective-display "[\n\C-m]" "\n")
! nil
! 'end
! (1- arg))))
;Put this on C-x u, so we can force that rather than C-_ into startup msg
(fset 'advertised-undo 'undo)
Dale Worley Compass, Inc. worley@compass.com
--
"We'd better wake up and smell the goats or it will be burlap soup for all
of us!"
"Burlap soup?"
"No thanks, I had lunch on the way over."