home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / functions / next-screen-line.el < prev    next >
Encoding:
Text File  |  1993-05-04  |  6.8 KB  |  187 lines

  1. ;;; next-screen-line.el --- A next-line that moves by screen lines.
  2. ;; Copyright (c) 1992 by Govind N. Kamat <kamat@ece.UC.EDU>
  3. ;; May be copied, modified and distributed under the
  4. ;; GNU Emacs General Public License.
  5. ;;
  6. ;; Author: Govind N. Kamat <kamat@ece.UC.EDU>
  7. ;; Version: 2.1
  8. ;; Keywords: next-line wrap line movement scrolling
  9. ;;
  10. ;;; Commentary:
  11. ;; Often having to edit files with more than 80 columns, I prefer that 
  12. ;; next-line and previous-line not jump over wrapped continuation 
  13. ;; lines.  Here is a drop-in replacement for next-line-internal that 
  14. ;; moves the cursor by screen lines rather than newline-separated 
  15. ;; lines.  This is especially handy while editing binary files.  The 
  16. ;; functions `beginning-of-line' and `end-of-line', bound to C-a and 
  17. ;; C-e respectively, are also redefined to behave similarly.
  18. ;;
  19. ;; Nothing is different when these functions are called 
  20. ;; non-interactively, so other packages should not be affected. 
  21. ;; During interactive use, the old behavior can be had by setting the 
  22. ;; variable `next-line-move-newlines' to true. 
  23. ;;
  24. ;; Another feature of this package is that if scroll-step is set to 1, 
  25. ;; it avoids point being centered in the window.  By default, merely 
  26. ;; setting this variable does not suffice, as can be seen when 
  27. ;; attempting to scroll rapidly with C-n, and also with wrapped lines. 
  28. ;;
  29. ;;; Installation:
  30. ;; Put this in a file named "next-screen-line.el" in the load-path of 
  31. ;; your Emacs.  Byte-compile it with M-x byte-compile-file.  Put the 
  32. ;; following line in your .emacs file:
  33. ;;
  34. ;;   (require 'next-screen-line)
  35. ;;
  36. ;; LCD Archive Entry:
  37. ;; next-screen-line|Govind N. Kamat|kamat@ece.UC.EDU|
  38. ;; A next-line that moves by screen lines.|
  39. ;; 4-Apr-1993|2.1|~/functions/next-screen-line.el.Z|
  40.  
  41. (provide 'next-screen-line)
  42.  
  43. (defvar next-line-move-newlines nil
  44.   "*Make next-line and previous-line move by newline-separated lines instead of
  45. screen lines.")
  46.  
  47. (defun next-line (arg)
  48.   "Move cursor vertically down ARG lines.
  49. If there is no character in the target line exactly under the current column,
  50. the cursor is positioned after the character in that line which spans this
  51. column, or at the end of the line if it is not long enough.
  52. If there is no line in the buffer after this one,
  53. a newline character is inserted to create a line
  54. and the cursor moves to that line.
  55.  
  56. The command \\[set-goal-column] can be used to create
  57. a semipermanent goal column to which this command always moves.
  58. Then it does not try to move vertically.
  59.  
  60. If you are thinking of using this in a Lisp program, consider
  61. using `forward-line' instead.  It is usually easier to use
  62. and more reliable (no dependence on goal column, etc.).
  63.  
  64. If `next-line-move-newlines' is nil, moves by screen lines instead of
  65. newline-separated ones."
  66.   (interactive "p")
  67.   (if (= arg 1)
  68.       (let ((opoint (point)))
  69.     (next-line-internal arg)
  70.     (if (= opoint (point))
  71.         (progn (end-of-line) (insert ?\n))))
  72.     (next-line-internal arg))
  73.   (and (= scroll-step 1)
  74.        (> arg 0)
  75.        (or (pos-visible-in-window-p) (recenter -1)))
  76.   nil)
  77.  
  78. (defun previous-line (arg)
  79.   "Move cursor vertically up ARG lines.
  80. If there is no character in the target line exactly over the current column,
  81. the cursor is positioned after the character in that line which spans this
  82. column, or at the end of the line if it is not long enough.
  83.  
  84. The command \\[set-goal-column] can be used to create
  85. a semipermanent goal column to which this command always moves.
  86. Then it does not try to move vertically.
  87.  
  88. If you are thinking of using this in a Lisp program, consider using
  89. `forward-line' with negative argument instead..  It is usually easier
  90. to use and more reliable (no dependence on goal column, etc.).
  91.  
  92. If `next-line-move-newlines' is nil, moves by screen lines instead of
  93. newline-separated ones."
  94.   (interactive "p")
  95.   (next-line-internal (- arg))
  96.   (and (= scroll-step 1)
  97.        (> arg 0)
  98.        (or (pos-visible-in-window-p) (recenter 0)))
  99.   nil)
  100.  
  101. (defun next-line-internal (arg)
  102.   (if (not (memq last-command '(next-line previous-line)))
  103.       (setq temporary-goal-column
  104.         (if (and track-eol (eolp))
  105.         t
  106.           (current-column))
  107.         next-line-internal-flag nil))
  108.   (let* ((w (1- (window-width)))
  109.      (g (or goal-column temporary-goal-column))
  110.      (pos (if (eq g t) w (% g w)))
  111.      c)
  112.     (and (= pos 0)
  113.      (> g 0)
  114.      (or (and (> (current-column) 0)
  115.           (= (or (char-after (point)) 10) 10))
  116.          (>= (or goal-column 0) w))
  117.      (setq next-line-internal-flag t))
  118.     (if (or next-line-move-newlines
  119.         ;; maintain compatibility when not interactive
  120.         (not (memq this-command '(next-line previous-line))))
  121.     (if (not (integerp selective-display))
  122.         (forward-line arg)
  123.       (while (> arg 0)
  124.         (end-of-line)
  125.         (vertical-motion 1)
  126.         (setq arg (1- arg)))
  127.       (while (< arg 0)
  128.         (beginning-of-line)
  129.         (vertical-motion -1)
  130.         (setq arg (1+ arg))))
  131.       (vertical-motion arg)
  132.       (and (eobp) (vertical-motion 0)))
  133.     (cond
  134.      ((eq g t) (end-of-line))
  135.      ((or next-line-move-newlines
  136.       truncate-lines
  137.       (> (window-hscroll) 0)
  138.       (and (< w (1- (screen-width))) truncate-partial-width-windows))
  139.       (move-to-column g))
  140.      (t (setq g (point) c (current-column))
  141.     (setq c (* w (/ c w)))
  142.     (move-to-column (+ (if next-line-internal-flag w pos) c))
  143.     (and (/= g (save-excursion (vertical-motion 0) (point)))
  144.          (forward-char -1))))))
  145.  
  146. (fset 'line-move 'next-line-internal)    ; for version 18.55
  147.  
  148. (and (subrp (symbol-function 'beginning-of-line))
  149.      (fset 'real-beginning-of-line (symbol-function 'beginning-of-line)))
  150. (and (subrp (symbol-function 'end-of-line))
  151.      (fset 'real-end-of-line (symbol-function 'end-of-line)))
  152.  
  153. ;; Thanks to Dan LaLiberte for suggesting the following.
  154.  
  155. (defun beginning-of-line (&optional arg)
  156.   "Move point to beginning of current line.
  157. With argument ARG not nil or 1, move forward ARG - 1 lines first.
  158. If scan reaches end of buffer, stop there without error.
  159. If `next-line-move-newlines' is nil, moves by screen lines instead of
  160. newline-separated ones."
  161.   (interactive "p")
  162.   (if (or (interactive-p) executing-kbd-macro)
  163.       (let ((this-command 'next-line)
  164.         (goal-column 0)
  165.         next-line-internal-flag)
  166.     (next-line-internal (1- arg)))
  167.     (real-beginning-of-line arg)))
  168.  
  169. (defun end-of-line (&optional arg)
  170.   "Move point to end of current line.
  171. With argument ARG not nil or 1, move forward ARG - 1 lines first.
  172. If scan reaches end of buffer, stop there without error.
  173. If `next-line-move-newlines' is nil, moves by screen lines instead of
  174. newline-separated ones."
  175.   (interactive "p")
  176.   (if (and (or (interactive-p) executing-kbd-macro)
  177.        (not (or next-line-move-newlines
  178.             truncate-lines
  179.             (> (window-hscroll) 0)
  180.             (and (< (window-width) (screen-width))
  181.              truncate-partial-width-windows))))
  182.       (let ((this-command 'next-line)
  183.         (goal-column (1- (window-width)))
  184.         next-line-internal-flag)
  185.     (next-line-internal (1- arg)))
  186.     (real-end-of-line arg)))
  187.