-(defun kill-rectangle (start end)
- "Delete rectangle with corners at point and mark; save as last killed one.
-Calling from program, supply two args START and END, buffer positions.
-But in programs you might prefer to use `delete-extract-rectangle'."
- (interactive "r")
- (if buffer-read-only
- (progn
- (setq killed-rectangle (extract-rectangle start end))
- (barf-if-buffer-read-only)))
- (setq killed-rectangle (delete-extract-rectangle start end)))
+(defun extract-rectangle (start end)
+ "Return the contents of the rectangle with corners at START and END,
+as a list of strings, one for each line of the rectangle."
+ (let ((lines (list nil)))
+ (apply-on-rectangle 'extract-rectangle-line start end lines)
+ (nreverse (cdr lines))))
+
+;; ### NOTE: this is actually the only function that needs to do complicated
+;; stuff like what's happening in `operate-on-rectangle', because the buffer
+;; might be read-only. --dv
+(defun extract-rectangle-line (startcol endcol lines)
+ (let (start end begextra endextra line)
+ (move-to-column startcol)
+ (setq start (point)
+ begextra (- (current-column) startcol))
+ (move-to-column endcol)
+ (setq end (point)
+ endextra (- endcol (current-column)))
+ (setq line (buffer-substring start (point)))
+ (if (< begextra 0)
+ (setq endextra (+ endextra begextra)
+ begextra 0))
+ (if (< endextra 0)
+ (setq endextra 0))
+ (goto-char start)
+ (while (search-forward "\t" end t)
+ (let ((width (- (current-column)
+ (save-excursion (forward-char -1)
+ (current-column)))))
+ (setq line (concat (substring line 0 (- (point) end 1))
+ (spaces-string width)
+ (substring line (+ (length line)
+ (- (point) end)))))))
+ (if (or (> begextra 0) (> endextra 0))
+ (setq line (concat (spaces-string begextra)
+ line
+ (spaces-string endextra))))
+ (setcdr lines (cons line (cdr lines)))))