Annotation of 43BSD/contrib/emacs/lisp/rect.el, revision 1.1.1.1

1.1       root        1: ;; Rectangle functions for GNU Emacs.
                      2: ;; Copyright (C) 1985 Richard M. Stallman.
                      3: 
                      4: ;; This file is part of GNU Emacs.
                      5: 
                      6: ;; GNU Emacs is distributed in the hope that it will be useful,
                      7: ;; but WITHOUT ANY WARRANTY.  No author or distributor
                      8: ;; accepts responsibility to anyone for the consequences of using it
                      9: ;; or for whether it serves any particular purpose or works at all,
                     10: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
                     11: ;; License for full details.
                     12: 
                     13: ;; Everyone is granted permission to copy, modify and redistribute
                     14: ;; GNU Emacs, but only under the conditions described in the
                     15: ;; GNU Emacs General Public License.   A copy of this license is
                     16: ;; supposed to have been given to you along with GNU Emacs so you
                     17: ;; can know your rights and responsibilities.  It should be in a
                     18: ;; file named COPYING.  Among other things, the copyright notice
                     19: ;; and this notice must be preserved on all copies.
                     20: 
                     21: 
                     22: (defun operate-on-rectangle (function start end coerce-tabs)
                     23:   "Call FUNCTION for each line of rectangle with corners at START, END.
                     24: If COERCE-TABS is non-nil, convert multi-column characters
                     25: that span the starting or ending columns on any line
                     26: to multiple spaces before calling FUNCTION.
                     27: FUNCTION is called with three arguments:
                     28:  position of start of segment of this line within the rectangle,
                     29:  number of columns that belong to rectangle but are before that position,
                     30:  number of columns that belong to rectangle but are after point.
                     31: Point is at the end of the segment of this line within the rectangle."
                     32:   (let (startcol startlinepos endcol endlinepos)
                     33:     (save-excursion
                     34:      (goto-char start)
                     35:      (setq startcol (current-column))
                     36:      (beginning-of-line)
                     37:      (setq startlinepos (point)))
                     38:     (save-excursion
                     39:      (goto-char end)
                     40:      (setq endcol (current-column))
                     41:      (forward-line 1)
                     42:      (setq endlinepos (point-marker)))
                     43:     (if (< endcol startcol)
                     44:        (let ((tem startcol))
                     45:          (setq startcol endcol endcol tem)))
                     46:     (if (/= endcol startcol)
                     47:        (save-excursion
                     48:         (goto-char startlinepos)
                     49:         (while (< (point) endlinepos)
                     50:           (let (startpos begextra endextra)
                     51:             (move-to-column startcol)
                     52:             (and coerce-tabs
                     53:                  (> (current-column) startcol)
                     54:                  (rectangle-coerce-tab startcol))
                     55:             (setq begextra (- (current-column) startcol))
                     56:             (setq startpos (point))
                     57:             (move-to-column endcol)
                     58:             (if (> (current-column) endcol)
                     59:                 (if coerce-tabs
                     60:                     (rectangle-coerce-tab endcol)
                     61:                   (forward-char -1)))
                     62:             (setq endextra (- endcol (current-column)))
                     63:             (if (< begextra 0)
                     64:                 (setq endextra (+ endextra begextra)
                     65:                       begextra 0))
                     66:             (funcall function startpos begextra endextra))
                     67:           (forward-line 1))))
                     68:     (- endcol startcol)))
                     69: 
                     70: (defun delete-rectangle-line (startdelpos ignore ignore)
                     71:   (delete-region startdelpos (point)))
                     72: 
                     73: (defun delete-extract-rectangle-line (startdelpos begextra endextra)
                     74:   (save-excursion
                     75:    (extract-rectangle-line startdelpos begextra endextra))
                     76:   (delete-region startdelpos (point)))
                     77: 
                     78: (defun extract-rectangle-line (startdelpos begextra endextra)
                     79:   (let ((line (buffer-substring startdelpos (point)))
                     80:        (end (point)))
                     81:     (goto-char startdelpos)
                     82:     (while (search-forward "\t" end t)
                     83:       (let ((width (- (current-column)
                     84:                      (save-excursion (forward-char -1)
                     85:                                      (current-column)))))
                     86:        (setq line (concat (substring line 0 (- (point) end 1))
                     87:                           (spaces-string width)
                     88:                           (substring line (+ (length line) (- (point) end)))))))
                     89:     (if (or (> begextra 0) (> endextra 0))
                     90:        (setq line (concat (spaces-string begextra)
                     91:                           line
                     92:                           (spaces-string endextra))))
                     93:     (setq lines (cons line lines))))
                     94: 
                     95: (defconst spaces-strings
                     96:   '["" " " "  " "   " "    " "     " "      " "       " "        "])
                     97: 
                     98: (defun spaces-string (n)
                     99:   (if (<= n 8) (aref spaces-strings n)
                    100:     (let ((val ""))
                    101:       (while (> n 8)
                    102:        (setq val (concat "        " val)
                    103:              n (- n 8)))
                    104:       (concat val (aref spaces-strings n)))))
                    105:     
                    106: (defun delete-rectangle (start end)
                    107:   "Delete (don't save) text in rectangle with point and mark as corners.
                    108: The same range of columns is deleted in each line
                    109: starting with the line where the region begins
                    110: and ending with the line where the region ends."
                    111:   (interactive "r")
                    112:   (operate-on-rectangle 'delete-rectangle-line start end t))
                    113: 
                    114: (defun delete-extract-rectangle (start end)
                    115:   "Return and delete contents of rectangle with corners at START and END.
                    116: Value is list of strings, one for each line of the rectangle."
                    117:   (let (lines)
                    118:     (operate-on-rectangle 'delete-extract-rectangle-line
                    119:                          start end t)
                    120:     (nreverse lines)))
                    121: 
                    122: (defun extract-rectangle (start end)
                    123:   "Return contents of rectangle with corners at START and END.
                    124: Value is list of strings, one for each line of the rectangle."
                    125:   (let (lines)
                    126:     (operate-on-rectangle 'extract-rectangle-line start end nil)
                    127:     (nreverse lines)))
                    128: 
                    129: (defvar killed-rectangle nil
                    130:   "Rectangle for yank-rectangle to insert.")
                    131: 
                    132: (defun kill-rectangle (start end)
                    133:   "Delete rectangle with corners at point and mark; save as last killed one.
                    134: Calling from program, supply two args START and END, buffer positions.
                    135: But in programs you might prefer to use delete-extract-rectangle."
                    136:   (interactive "r")
                    137:   (setq killed-rectangle (delete-extract-rectangle start end)))
                    138: 
                    139: (defun yank-rectangle ()
                    140:   "Yank the last killed rectangle with upper left corner at point."
                    141:   (interactive)
                    142:   (insert-rectangle killed-rectangle))
                    143: 
                    144: (defun insert-rectangle (rectangle)
                    145:   "Insert text of RECTANGLE with upper left corner at point.
                    146: RECTANGLE's first line is inserted at point,
                    147: its second line is inserted at a point vertically under point, etc.
                    148: RECTANGLE should be a list of strings."
                    149:   (let ((lines rectangle)
                    150:        (insertcolumn (current-column))
                    151:        (first t))
                    152:     (while lines
                    153:       (or first
                    154:          (progn
                    155:           (forward-line 1)
                    156:           (or (bolp) (insert ?\n))
                    157:           (move-to-column insertcolumn)
                    158:           (if (> (current-column) insertcolumn)
                    159:               (rectangle-coerce-tab insertcolumn))
                    160:           (if (< (current-column) insertcolumn)
                    161:               (indent-to insertcolumn))))
                    162:       (setq first nil)
                    163:       (insert (car lines))
                    164:       (setq lines (cdr lines)))))
                    165: 
                    166: (defun open-rectangle (start end)
                    167:   "Blank out rectangle with corners at point and mark, shifting text right.
                    168: The text previously in the region is not overwritten by the blanks,
                    169: but insted winds up to the right of the rectangle."
                    170:   (interactive "r")
                    171:   (operate-on-rectangle 'open-rectangle-line start end nil))
                    172: 
                    173: (defun open-rectangle-line (startpos begextra endextra)
                    174:   (let ((column (+ (current-column) begextra endextra)))
                    175:     (goto-char startpos)
                    176:     (let ((ocol (current-column)))
                    177:       (skip-chars-forward " \t")
                    178:       (setq column (+ column (- (current-column) ocol))))
                    179:     (delete-region (point)
                    180:                    (progn (skip-chars-backward " \t")
                    181:                          (point)))
                    182:     (indent-to column)))
                    183: 
                    184: (defun clear-rectangle (start end)
                    185:   "Blank out rectangle with corners at point and mark.
                    186: The text previously in the region is overwritten by the blanks."
                    187:   (interactive "r")
                    188:   (operate-on-rectangle 'clear-rectangle-line start end t))
                    189: 
                    190: (defun clear-rectangle-line (startpos begextra endextra)
                    191:   (skip-chars-forward " \t")
                    192:   (let ((column (+ (current-column) endextra)))
                    193:     (delete-region (point)
                    194:                    (progn (goto-char startpos)
                    195:                          (skip-chars-backward " \t")
                    196:                          (point)))
                    197:     (indent-to column)))
                    198: 
                    199: (defun rectangle-coerce-tab (column)
                    200:   (let ((aftercol (current-column))
                    201:        (indent-tabs-mode nil))
                    202:     (delete-char -1)
                    203:     (indent-to aftercol)
                    204:     (backward-char (- aftercol column))))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.