all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [PATCH] Make rectangle-select able to skip lines(empty one, for example)
@ 2023-01-30 13:47 Constantin Kulikov
  2023-01-30 14:36 ` Constantin Kulikov
  0 siblings, 1 reply; 6+ messages in thread
From: Constantin Kulikov @ 2023-01-30 13:47 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 1446 bytes --]

Code to try:

(with-eval-after-load "rect.el"
  (defvar *rectangle-skip-lines* nil
"If `t' -- skip empty lines, if `function' -- skip line if it returns `nil'.
The function gets all arguments of `apply-to-rectangle' as input.")
  (defun apply-on-rectangle (function start end &rest args)
"Call FUNCTION for each line of rectangle with corners at START, END.
FUNCTION is called with two arguments: the start and end columns of the
rectangle, plus ARGS extra arguments.  Point is at the beginning of line
when
the function is called.
Application of the FUNCTION is affected by the `*rectangle-skip-lines*'.
The final point after the last operation will be returned."
(save-excursion
 (let* ((cols (rectangle--pos-cols start end))
(startcol (car cols))
(endcol (cdr cols))
(startpt (progn (goto-char start) (line-beginning-position)))
(endpt (progn (goto-char end)
  (copy-marker (line-end-position))))
final-point)
;; Ensure the start column is the left one.
(if (< endcol startcol)
(let ((col startcol))
 (setq startcol endcol endcol col)))
;; Start looping over lines.
(goto-char startpt)
(while
(progn
 (when (cond
((null *rectangle-skip-lines*)
 t)
((functionp *rectangle-skip-lines*)
 (apply *rectangle-skip-lines* function start end args))
(t
 (/= (line-beginning-position) (line-end-position))))
(apply function startcol endcol args))
 (setq final-point (point))
 (and (zerop (forward-line 1)) (bolp)
  (<= (point) endpt))))
final-point))))

[-- Attachment #1.2: Type: text/html, Size: 1914 bytes --]

[-- Attachment #2: rect.el.patch --]
[-- Type: application/octet-stream, Size: 1449 bytes --]

--- rect.el	2023-01-30 14:18:22.542176710 +0300
+++ rect-patched.el	2023-01-30 15:44:14.953579566 +0300
@@ -143,12 +143,16 @@
   (rectangle--reset-point-crutches))
 
 ;;; Rectangle operations.
+(defvar *rectangle-skip-lines* nil
+  "If `t' -- skip empty lines, if `function' -- skip line if it returns `nil'.
+The function gets all arguments of `apply-to-rectangle' as input.")
 
 (defun apply-on-rectangle (function start end &rest args)
   "Call FUNCTION for each line of rectangle with corners at START, END.
 FUNCTION is called with two arguments: the start and end columns of the
 rectangle, plus ARGS extra arguments.  Point is at the beginning of line when
 the function is called.
+Application of the FUNCTION is affected by the `*rectangle-skip-lines*'.
 The final point after the last operation will be returned."
   (save-excursion
     (let* ((cols (rectangle--pos-cols start end))
@@ -166,7 +170,14 @@
       (goto-char startpt)
       (while
           (progn
-            (apply function startcol endcol args)
+            (when (cond
+				   ((null *rectangle-skip-lines*)
+					t)
+				   ((functionp *rectangle-skip-lines*)
+					(apply *rectangle-skip-lines* function start end args))
+				   (t
+					(/= (line-beginning-position) (line-end-position))))
+			  (apply function startcol endcol args))
             (setq final-point (point))
             (and (zerop (forward-line 1)) (bolp)
                  (<= (point) endpt))))

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Make rectangle-select able to skip lines(empty one, for example)
  2023-01-30 13:47 [PATCH] Make rectangle-select able to skip lines(empty one, for example) Constantin Kulikov
@ 2023-01-30 14:36 ` Constantin Kulikov
  2023-01-31 15:05   ` Constantin Kulikov
  0 siblings, 1 reply; 6+ messages in thread
From: Constantin Kulikov @ 2023-01-30 14:36 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 1614 bytes --]

Actually it must be named: "*Make `apply-on-rectangle' able to skip lines*".
Reattaching the patch as .txt


--- rect.el 2023-01-30 14:18:22.542176710 +0300
+++ rect-patched.el 2023-01-30 15:44:14.953579566 +0300
@@ -143,12 +143,16 @@
   (rectangle--reset-point-crutches))

 ;;; Rectangle operations.
+(defvar *rectangle-skip-lines* nil
+  "If `t' -- skip empty lines, if `function' -- skip line if it returns
`nil'.
+The function gets all arguments of `apply-to-rectangle' as input.")

 (defun apply-on-rectangle (function start end &rest args)
   "Call FUNCTION for each line of rectangle with corners at START, END.
 FUNCTION is called with two arguments: the start and end columns of the
 rectangle, plus ARGS extra arguments.  Point is at the beginning of line
when
 the function is called.
+Application of the FUNCTION is affected by the `*rectangle-skip-lines*'.
 The final point after the last operation will be returned."
   (save-excursion
     (let* ((cols (rectangle--pos-cols start end))
@@ -166,7 +170,14 @@
       (goto-char startpt)
       (while
           (progn
-            (apply function startcol endcol args)
+            (when (cond
+   ((null *rectangle-skip-lines*)
+ t)
+   ((functionp *rectangle-skip-lines*)
+ (apply *rectangle-skip-lines* function start end args))
+   (t
+ (/= (line-beginning-position) (line-end-position))))
+  (apply function startcol endcol args))
             (setq final-point (point))
             (and (zerop (forward-line 1)) (bolp)
                  (<= (point) endpt))))


On Mon, 30 Jan 2023 at 16:47, Constantin Kulikov <zxnotdead@gmail.com>
wrote:

>
>

[-- Attachment #1.2: Type: text/html, Size: 2323 bytes --]

[-- Attachment #2: rect.el.patch.txt --]
[-- Type: text/plain, Size: 1449 bytes --]

--- rect.el	2023-01-30 14:18:22.542176710 +0300
+++ rect-patched.el	2023-01-30 15:44:14.953579566 +0300
@@ -143,12 +143,16 @@
   (rectangle--reset-point-crutches))
 
 ;;; Rectangle operations.
+(defvar *rectangle-skip-lines* nil
+  "If `t' -- skip empty lines, if `function' -- skip line if it returns `nil'.
+The function gets all arguments of `apply-to-rectangle' as input.")
 
 (defun apply-on-rectangle (function start end &rest args)
   "Call FUNCTION for each line of rectangle with corners at START, END.
 FUNCTION is called with two arguments: the start and end columns of the
 rectangle, plus ARGS extra arguments.  Point is at the beginning of line when
 the function is called.
+Application of the FUNCTION is affected by the `*rectangle-skip-lines*'.
 The final point after the last operation will be returned."
   (save-excursion
     (let* ((cols (rectangle--pos-cols start end))
@@ -166,7 +170,14 @@
       (goto-char startpt)
       (while
           (progn
-            (apply function startcol endcol args)
+            (when (cond
+				   ((null *rectangle-skip-lines*)
+					t)
+				   ((functionp *rectangle-skip-lines*)
+					(apply *rectangle-skip-lines* function start end args))
+				   (t
+					(/= (line-beginning-position) (line-end-position))))
+			  (apply function startcol endcol args))
             (setq final-point (point))
             (and (zerop (forward-line 1)) (bolp)
                  (<= (point) endpt))))

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Make rectangle-select able to skip lines(empty one, for example)
  2023-01-30 14:36 ` Constantin Kulikov
@ 2023-01-31 15:05   ` Constantin Kulikov
  2023-01-31 16:18     ` [External] : " Drew Adams
  0 siblings, 1 reply; 6+ messages in thread
From: Constantin Kulikov @ 2023-01-31 15:05 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 3324 bytes --]

Treat lines with whitespaces only as 'empty'.

--- rect-orig.el 2023-01-31 17:25:08.498658466 +0300
+++ rect-patched.el 2023-01-31 17:30:02.163121185 +0300
@@ -144,11 +144,16 @@

 ;;; Rectangle operations.

+(defvar *rectangle-skip-lines* nil
+  "If `t' -- skip empty lines, if `function' -- skip line when it returns
`nil'.
+The function gets all arguments of `apply-on-rectangle' as input.")
+
 (defun apply-on-rectangle (function start end &rest args)
   "Call FUNCTION for each line of rectangle with corners at START, END.
 FUNCTION is called with two arguments: the start and end columns of the
 rectangle, plus ARGS extra arguments.  Point is at the beginning of line
when
 the function is called.
+Application of the FUNCTION is affected by the `*rectangle-skip-lines*'.
 The final point after the last operation will be returned."
   (save-excursion
     (let* ((cols (rectangle--pos-cols start end))
@@ -166,7 +171,14 @@
       (goto-char startpt)
       (while
           (progn
-            (apply function startcol endcol args)
+            (when (cond
+                   ((null *rectangle-skip-lines*)
+                    t)
+                   ((functionp *rectangle-skip-lines*)
+                    (apply *rectangle-skip-lines* function start end args))
+                   (t
+                    (not (string-match-p "\\`\\s-*$" (thing-at-point
'line)))))
+              (apply function startcol endcol args))
             (setq final-point (point))
             (and (zerop (forward-line 1)) (bolp)
                  (<= (point) endpt))))


------------------------------

(with-eval-after-load "rect.el"
  (defvar *rectangle-skip-lines* nil
"If `t' -- skip empty lines, if `function' -- skip line when it returns
`nil'.
The function gets all arguments of `apply-on-rectangle' as input.")
  (defun apply-on-rectangle (function start end &rest args)
"Call FUNCTION for each line of rectangle with corners at START, END.
FUNCTION is called with two arguments: the start and end columns of the
rectangle, plus ARGS extra arguments.  Point is at the beginning of line
when
the function is called.
Application of the FUNCTION is affected by the `*rectangle-skip-lines*'.
The final point after the last operation will be returned."
(save-excursion
 (let* ((cols (rectangle--pos-cols start end))
(startcol (car cols))
(endcol (cdr cols))
(startpt (progn (goto-char start) (line-beginning-position)))
(endpt (progn (goto-char end)
  (copy-marker (line-end-position))))
final-point)
;; Ensure the start column is the left one.
(if (< endcol startcol)
(let ((col startcol))
 (setq startcol endcol endcol col)))
;; Start looping over lines.
(goto-char startpt)
(while
(progn
 (when (cond
((null *rectangle-skip-lines*)
 t)
((functionp *rectangle-skip-lines*)
 (apply *rectangle-skip-lines* function start end args))
(t
 (not (string-match-p "\\`\\s-*$" (thing-at-point 'line)))))
(apply function startcol endcol args))
 (setq final-point (point))
 (and (zerop (forward-line 1)) (bolp)
  (<= (point) endpt))))
final-point))))


On Mon, 30 Jan 2023 at 17:36, Constantin Kulikov <zxnotdead@gmail.com>
wrote:

> Actually it must be named: "*Make `apply-on-rectangle' able to skip lines*
> ".
> Reattaching the patch as .txt
>
> On Mon, 30 Jan 2023 at 16:47, Constantin Kulikov <zxnotdead@gmail.com>
> wrote:
>
>>
>>

[-- Attachment #1.2: Type: text/html, Size: 4844 bytes --]

[-- Attachment #2: rect.el.patch.txt --]
[-- Type: text/plain, Size: 1517 bytes --]

--- rect-orig.el	2023-01-31 17:25:08.498658466 +0300
+++ rect-patched.el	2023-01-31 17:30:02.163121185 +0300
@@ -144,11 +144,16 @@
 
 ;;; Rectangle operations.
 
+(defvar *rectangle-skip-lines* nil
+  "If `t' -- skip empty lines, if `function' -- skip line when it returns `nil'.
+The function gets all arguments of `apply-on-rectangle' as input.")
+
 (defun apply-on-rectangle (function start end &rest args)
   "Call FUNCTION for each line of rectangle with corners at START, END.
 FUNCTION is called with two arguments: the start and end columns of the
 rectangle, plus ARGS extra arguments.  Point is at the beginning of line when
 the function is called.
+Application of the FUNCTION is affected by the `*rectangle-skip-lines*'.
 The final point after the last operation will be returned."
   (save-excursion
     (let* ((cols (rectangle--pos-cols start end))
@@ -166,7 +171,14 @@
       (goto-char startpt)
       (while
           (progn
-            (apply function startcol endcol args)
+            (when (cond
+                   ((null *rectangle-skip-lines*)
+                    t)
+                   ((functionp *rectangle-skip-lines*)
+                    (apply *rectangle-skip-lines* function start end args))
+                   (t
+                    (not (string-match-p "\\`\\s-*$" (thing-at-point 'line)))))
+              (apply function startcol endcol args))
             (setq final-point (point))
             (and (zerop (forward-line 1)) (bolp)
                  (<= (point) endpt))))

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [External] : Re: [PATCH] Make rectangle-select able to skip lines(empty one, for example)
  2023-01-31 15:05   ` Constantin Kulikov
@ 2023-01-31 16:18     ` Drew Adams
  2023-02-02 18:26       ` Constantin Kulikov
  0 siblings, 1 reply; 6+ messages in thread
From: Drew Adams @ 2023-01-31 16:18 UTC (permalink / raw)
  To: Constantin Kulikov, emacs-devel

> Treat lines with whitespaces only as 'empty'.
>
>(defvar *rectangle-skip-lines* nil
> "If `t' -- skip empty lines, if `function' -- skip line when it returns `nil'.
>The function gets all arguments of `apply-on-rectangle' as input.")

My opinion doesn't matter, but in case it helps:

1. Lose the *...* earmuffs.  Elisp doesn't
embrace that CL convention for defvars.

2. The var's doc should say what it means by
"skip".  Apparently it means (only) that
function `apply-on-rectangle' doesn't apply
its FUNCTION arg to empty lines.  I think it's
important to say that the var affects (only)
that function's behavior.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [External] : Re: [PATCH] Make rectangle-select able to skip lines(empty one, for example)
  2023-01-31 16:18     ` [External] : " Drew Adams
@ 2023-02-02 18:26       ` Constantin Kulikov
  2023-02-02 19:53         ` Drew Adams
  0 siblings, 1 reply; 6+ messages in thread
From: Constantin Kulikov @ 2023-02-02 18:26 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 2880 bytes --]

> 1. Lose the *...* earmuffs.  Elisp doesn't embrace that CL convention for
defvars.

I wonder, is it because Emacs had only dynamic binding? Maybe now the
"*..*" can be helpful to distinguish dynamic vars from lexical.

> 2. The var's doc should say what it means by "skip".  Apparently it means
(only) that function `apply-on-rectangle' doesn't apply
its FUNCTION arg to empty lines.  I think it's important to say that the
var affects (only) that function's behavior.

I think the application of FUNCTION is the main part of
`apply-on-rectangle', so it is more or less obvious.
And you can easily see the effect in GUI, when using `rectangle-mark-mode'
(C-x SPC).

I'm not quite sure how to name the var.


*What it does:*

For example you have a buffer "env.sh" with content:




*"FOO=1BAR=2"*

Now if you do
`M-<'          beginning-of-buffer
`C-x SPC'      rectangle-mark-mode
`C-n'          next-line
`C-n'          next-line
`C-t'          string-rectangle
`export RET'

With standard rect.el you will get:




*"export FOO=1export export BAR=2"*

With patched version and `rectangle-select-skip-line'(new name of var) set
to `t':




*"export FOO=1export BAR=2"*

*New version of patch:*

--- rect-orig.el 2023-01-31 17:25:08.498658466 +0300
+++ rect-patched.el 2023-02-02 20:21:11.041198925 +0300
@@ -144,11 +144,18 @@

 ;;; Rectangle operations.

+(defvar rectangle-select-skip-line nil
+  "Control the `apply-on-rectangle' execution.
+`nil' -- apply action to selected lines, `t' -- skip empty lines,
+`function' -- skip line if it return non-`nil'.
+The function get all arguments of `apply-on-rectangle' as input.")
+
 (defun apply-on-rectangle (function start end &rest args)
   "Call FUNCTION for each line of rectangle with corners at START, END.
 FUNCTION is called with two arguments: the start and end columns of the
 rectangle, plus ARGS extra arguments.  Point is at the beginning of line
when
 the function is called.
+The `rectangle-select-skip-line' variable allow to skip lines.
 The final point after the last operation will be returned."
   (save-excursion
     (let* ((cols (rectangle--pos-cols start end))
@@ -166,7 +173,14 @@
       (goto-char startpt)
       (while
           (progn
-            (apply function startcol endcol args)
+            (when (cond
+                   ((null rectangle-select-skip-line)
+                    t)
+                   ((functionp rectangle-select-skip-line)
+                    (apply rectangle-select-skip-line function start end
args))
+                   (t
+                    (not (string-match-p "\\`\\s-*$" (thing-at-point
'line)))))
+              (apply function startcol endcol args))
             (setq final-point (point))
             (and (zerop (forward-line 1)) (bolp)
                  (<= (point) endpt))))


On Tue, 31 Jan 2023 at 19:18, Drew Adams <drew.adams@oracle.com> wrote:

>
>

[-- Attachment #1.2: Type: text/html, Size: 4141 bytes --]

[-- Attachment #2: rect.el.patch.txt --]
[-- Type: text/plain, Size: 1604 bytes --]

--- rect-orig.el	2023-01-31 17:25:08.498658466 +0300
+++ rect-patched.el	2023-02-02 20:21:11.041198925 +0300
@@ -144,11 +144,18 @@
 
 ;;; Rectangle operations.
 
+(defvar rectangle-select-skip-line nil
+  "Control the `apply-on-rectangle' execution.
+`nil' -- apply action to selected lines, `t' -- skip empty lines,
+`function' -- skip line if it return non-`nil'.
+The function get all arguments of `apply-on-rectangle' as input.")
+
 (defun apply-on-rectangle (function start end &rest args)
   "Call FUNCTION for each line of rectangle with corners at START, END.
 FUNCTION is called with two arguments: the start and end columns of the
 rectangle, plus ARGS extra arguments.  Point is at the beginning of line when
 the function is called.
+The `rectangle-select-skip-line' variable allow to skip lines.
 The final point after the last operation will be returned."
   (save-excursion
     (let* ((cols (rectangle--pos-cols start end))
@@ -166,7 +173,14 @@
       (goto-char startpt)
       (while
           (progn
-            (apply function startcol endcol args)
+            (when (cond
+                   ((null rectangle-select-skip-line)
+                    t)
+                   ((functionp rectangle-select-skip-line)
+                    (apply rectangle-select-skip-line function start end args))
+                   (t
+                    (not (string-match-p "\\`\\s-*$" (thing-at-point 'line)))))
+              (apply function startcol endcol args))
             (setq final-point (point))
             (and (zerop (forward-line 1)) (bolp)
                  (<= (point) endpt))))

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [External] : Re: [PATCH] Make rectangle-select able to skip lines(empty one, for example)
  2023-02-02 18:26       ` Constantin Kulikov
@ 2023-02-02 19:53         ` Drew Adams
  0 siblings, 0 replies; 6+ messages in thread
From: Drew Adams @ 2023-02-02 19:53 UTC (permalink / raw)
  To: Constantin Kulikov, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1002 bytes --]

below

> 1. Lose the *...* earmuffs.  Elisp doesn't embrace that CL convention for defvars.

I wonder, is it because Emacs had only dynamic binding? Maybe now the "*..*" can be helpful to distinguish dynamic vars from lexical.

The question is for others. I'm just pointing out the current (and longstanding) convention (lack of that particular convention. (I'm guessing "that ship has sailed".)

> 2. The var's doc should say what it means by "skip".  Apparently it means (only) that function `apply-on-rectangle' doesn't apply its FUNCTION arg to empty lines.  I think it's important to say that the var affects (only) that function's behavior.

I think the application of FUNCTION is the main part of `apply-on-rectangle', so it is more or less obvious.
And you can easily see the effect in GUI, when using `rectangle-mark-mode' (C-x SPC).

I disagree that it's obvious what "skip" means.

I'm not quite sure how to name the var.

What it does:...

The description is good. Thx.

[-- Attachment #2: Type: text/html, Size: 4770 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-02-02 19:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-30 13:47 [PATCH] Make rectangle-select able to skip lines(empty one, for example) Constantin Kulikov
2023-01-30 14:36 ` Constantin Kulikov
2023-01-31 15:05   ` Constantin Kulikov
2023-01-31 16:18     ` [External] : " Drew Adams
2023-02-02 18:26       ` Constantin Kulikov
2023-02-02 19:53         ` Drew Adams

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.