emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

`move-end-of-line' in `rectangular region': `goto-longest-line'


From: Garreau\, Alexandre
Subject: `move-end-of-line' in `rectangular region': `goto-longest-line'
Date: Tue, 30 Oct 2018 06:16:11 +0100
User-agent: Gnus (5.13), GNU Emacs 25.1.1 (i686-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-09-15, modified by Debian

On 2018-10-30 at 06:07, Garreau, Alexandre wrote:
> Try copying that (without “> ” prefixes) with rectangular selection:
>> a
>> aaa
>> aaaaaaaaaaaaaaaaaaaaaaa
>> aaa
>> a

(This is a followup because initially I wanted to talk about this in my
other mail, and subject are near.)

Something I wished existed out of the box with rectangular-selection, is
C-e (`move-end-of-line') going not at the end of the current line, but
at “max pos” horizontally, that is, on the current line, n chars away
where n is the number of chars of the longest line in (I guess,
non-rectangular) region.  As C-e is often used, I wished its first call
went at the end-of-line, and only a second times it will go at a such
position.

I thought Drew Adams’ `goto-longest-line', strangely not added in
misc.el, 9 years ago, might do:

;---------------8<-----------------------
(defun goto-longest-line (beg end)
  "Go to the first of the longest lines in the region or buffer.
If the region is active, it is checked.
If not, the buffer (or its restriction) is checked.

Returns a list of three elements:

 (LINE LINE-LENGTH OTHER-LINES LINES-CHECKED)

LINE is the first of the longest lines measured.
LINE-LENGTH is the length of LINE.
OTHER-LINES is a list of other lines checked that are as long as LINE.
LINES-CHECKED is the number of lines measured.

Interactively, a message displays this information.

If there is only one line in the active region, then the region is
deactivated after this command, and the message mentions only LINE and
LINE-LENGTH.  

If this command is repeated, it checks for the longest line after the
cursor.  That is *not* necessarily the longest line other than the
current line.  That longest line could be before or after the current
line:
> To search only from the current line forward, not throughout the
> buffer, you can use `C-SPC' to set the mark, then use this
> \(repeatedly)."
>   (interactive
>    (if (or (not mark-active) (null (mark)))
>        (list (point-min) (point-max))
>      (if (< (point) (mark))
>          (list (point) (mark))
>        (list (mark) (point)))))
>   (when (and (not mark-active) (= beg end))
>     (error "The buffer is empty"))
>   (when (and mark-active (> (point) (mark))) (exchange-point-and-mark))
>   (when (< end beg) (setq end (prog1 beg (setq beg end))))
>   (when (eq this-command last-command)
>     (forward-line 1) (setq beg (point)))
>   (goto-char beg)
>   (when (eobp) (error "End of buffer"))
>   (cond ((<= end (save-excursion
>                    (goto-char beg) (forward-line 1) (point)))
>          (beginning-of-line)
>          (when (require 'hl-line nil t)
>            (let ((hl-line-mode t)) (hl-line-highlight))
>            (add-hook 'pre-command-hook #'hl-line-unhighlight nil t))
>          (let ((lineno (line-number-at-pos))
>                (chars (save-excursion (end-of-line) (current-column))))
>            (message "Only line %d: %d chars" lineno chars)
>            (let ((visible-bell t)) (ding))
>            (setq mark-active nil)
>            (list lineno chars nil 1)))
>         (t
>          (let* ((start-line (line-number-at-pos))
>                 (max-width 0)
>                 (line start-line)
>                 long-lines col)
>            (when (eobp) (error "End of buffer"))
>            (while (and (not (eobp)) (< (point) end))
>              (end-of-line)
>              (setq col (current-column))
>              (when (>= col max-width)
>                (if (= col max-width)
>                    (setq long-lines (cons line long-lines))
>                  (setq long-lines (list line)))
>                (setq max-width col))
>              (forward-line 1)
>              (setq line (1+ line)))
>            (setq long-lines (nreverse long-lines))
>            (let ((lines long-lines))
>              (while (and lines (> start-line (car lines))) (pop lines))
>              (goto-char (point-min))
>              (when (car lines) (forward-line (1- (car lines)))))
>            (when (require 'hl-line nil t)
>              (let ((hl-line-mode t)) (hl-line-highlight))
>              (add-hook 'pre-command-hook #'hl-line-unhighlight nil t))
>            (when (interactive-p)
>              (let ((others (cdr long-lines)))
>                (message
>                 "Line %d: %d chars%s (%d lines measured)"
>                 (car long-lines) max-width
>                 (concat
>                  (and others
>                       (format ", Others: {%s}"
>                               (mapconcat
>                                (lambda (line) (format "%d" line))
>                                (cdr long-lines) ", "))))
>                 (- line start-line))))
>            (list (car long-lines) max-width (cdr long-lines)
>                  (- line start-line))))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]