Thursday, April 26, 2007

Map on lines in Emacs


;;;--------------------------------------------------------------------
(defun u:map-lines (beg end func)

"Call given FUNC in the form (LAMBDA (LBEG LEND LSTR LCOUNT)...)
for every line in the region. By default just print them."

(interactive "r\nXMap Function ((LAMBDA (LSTR LBEG LEND LCOUNT) ...)): ")

(let ((count 1)
(inhibit-field-text-motion t))

(when (stringp func)
(setq func (car (read (eval (concat "(" func ")"))))))

(unless func
(setq func #'(lambda (s b e c) (princ (format "%4d:%s" c s)))))

(save-excursion
(save-match-data
(goto-char beg)

(let (lbeg
lend
lstr
(delta (- (point-max) end)))

(while (< (point) (- (point-max) delta))

(setq lbeg (line-beginning-position 1))
(setq lend (line-beginning-position 2))
(setq lstr (buffer-substring-no-properties lbeg lend))

(funcall func lstr lbeg lend count)

(goto-char lbeg) ; line can be changed
(forward-line 1)

(incf count)))))))


;;--------------------------------------------------------------------
(defun u:remove-duplicates (beg end)
(interactive "r")

(let (prev-line)
(u:map-lines beg end
#'(lambda (line b e)

(when (and prev-line
(string= prev-line line))

(delete-region b e))

(setq prev-line line)))))


;;--------------------------------------------------------------------
(defun u:num-lines (beg end start-num)
(interactive "r\np")

(when (not start-num) (setq start-num 0))
(u:map-lines beg
end
#'(lambda (s b e n)
(delete-region b e)
(insert (format "%d: %s" (+ n start-num -1) s)) )))

No comments: