Path: utzoo!utgpu!watmath!uunet!tut.cis.ohio-state.edu!EDDIE.MIT.EDU!compass!worley From: compass!worley@EDDIE.MIT.EDU (Dale Worley) Newsgroups: gnu.emacs Subject: Improvement to line counting functions Message-ID: <8910251828.AA01357@sn1987a.compass.com> Date: 25 Oct 89 18:28:32 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 166 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."