unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Philip Kaludercic <philipk@posteo.net>
To: JD Smith <jdtsmith@gmail.com>
Cc: emacs-devel <emacs-devel@gnu.org>
Subject: Re: Proposed for ELPA: speedrect
Date: Tue, 03 Dec 2024 20:05:07 +0000	[thread overview]
Message-ID: <87y10wjzws.fsf@posteo.net> (raw)
In-Reply-To: <FE8D9EE7-A090-4DCA-9673-B1180166861A@gmail.com> (JD Smith's message of "Tue, 3 Dec 2024 11:28:48 -0500")

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

JD Smith <jdtsmith@gmail.com> writes:

> I propose adding the simple package speedrect
> <https://github.com/jdtsmith/speedrect> to ELPA.  Speedrect is a modal
> interface that comes alive when rectangle-mark-mode is active.  It
> provides easy access to enhanced rectangle functionality.  Beyond all
> the normal (and a few hidden) rectangle functions, some additional
> speedrect capabilities of note include:
>
> - auto-restarting (so you can easily chain multiple rectangle actions)
> - autosave and restore of the last rectangle
> - rectangular text wrapping
> - robust integration with calc
> - quick placement of multiple-cursors

It looks good, I just have a few comments and suggestions you might be
interested in considering:


[-- Attachment #2: Type: text/plain, Size: 8704 bytes --]

diff --git a/speedrect.el b/speedrect.el
index 10f45a3..b1f34bc 100644
--- a/speedrect.el
+++ b/speedrect.el
@@ -1,4 +1,5 @@
 ;;; speedrect.el ---  Fast modal rectangle commands -*- lexical-binding: t -*-
+
 ;; Copyright (C) 2023-2024  Free Software Foundation, Inc.
 
 ;; Author: JD Smith <jdtsmith+elpa@gmail.com>
@@ -34,13 +35,16 @@
 (require 'calc)
 (require 'subr-x)
 (require 'compat)
-(eval-when-compile (require 'cl-lib))
+(require 'cl-lib)
+
+(defgroup speedrect ()
+  "Fast modal rectangle commands."
+  :group 'rectangle)
 
 ;;;; Customization
 (defcustom speedrect-continue t
   "Stay in speedrect until quit."
-  :type 'boolean
-  :group 'rectangle)
+  :type 'boolean)
 
 (defun speedrect-linecol ()
   "Return line and column as list."
@@ -49,7 +53,7 @@
 ;;;; Variables
 (defvar-local speedrect-last nil
   "Last rectangle position.
-Stored as (point-line point-col mark-line mark-col)")
+Stored as (POINT-LINE POINT-COL MARK-LINE MARK-COL), where ....")
 
 (defun speedrect-recall-last ()
   "Restore last saved rectangle position."
@@ -60,9 +64,9 @@ Stored as (point-line point-col mark-line mark-col)")
      (goto-char point)
      (setf (window-parameter nil 'rectangle--point-crutches) point-crutches)
      (setq-local rectangle--mark-crutches mark-crutches)
-     (if (called-interactively-p 'interactive)
-	 (message "Restored last rectangle %d %d"
-		  (marker-position point) (marker-position mark))))
+     (when (called-interactively-p 'interactive)
+       (message "Restored last rectangle %d %d"
+		(marker-position point) (marker-position mark))))
     (_ (message "No stored rectangle position"))))
 
 (defun speedrect-stash ()
@@ -76,8 +80,8 @@ Stored as (point-line point-col mark-line mark-col)")
 	(setq pm (cons (point-marker) (copy-marker (mark-marker)))))
       (setq speedrect-last
 	    (list pm
-	     (window-parameter nil 'rectangle--point-crutches)
-	     rectangle--mark-crutches)))))
+		  (window-parameter nil 'rectangle--point-crutches)
+		  rectangle--mark-crutches)))))
 
 (defun speedrect-restart ()
   "Start a new rectangle, setting mark at the current position."
@@ -204,7 +208,7 @@ and `d n' with a prefix arg changes the displayed precision.  A
 minimum of one padding space is preserved on each side of the
 inserted text."
   (interactive "r")
-  (if-let ((rectangle-mark-mode)
+  (if-let* ((rectangle-mark-mode)
 	   (buf (get-buffer "*Calculator*")))
       (let* ((lines (with-current-buffer buf
 		      (string-lines
@@ -224,7 +228,7 @@ inserted text."
 	       (wdth (length (car lines))) ; note: last line may differ
 	       (low (max 0 (1- (car lr))))
 	       (high (min 0 (- (1- (cdr lr)))))
-	       (lst (last lines)))
+	       (lst (last lines)))	;unused?
 	  (apply-on-rectangle 'speedrect--replace-with-rect
 			      start end lines wdth low high)))
     (user-error "Calc rectangle yank not possible here")))
@@ -248,10 +252,7 @@ inserted text."
 (defun speedrect-copy-rectangle-as-text ()
   "Copy the current rectangle to the kill ring as normal text."
   (interactive)
-  (let ((rect (apply #'extract-rectangle
-		     (if (< (point) (mark))
-			 (list (point) (mark))
-		       (list (mark) (point))))))
+  (let ((rect (extract-rectangle (region-beginning) (region-end))))
     (kill-new (string-join rect "\n"))
     (message "Copied rectangle as %d lines" (length rect))))
 
@@ -297,47 +298,45 @@ inserted text."
   "Documentation window for speedrect."
   (interactive)
   (with-help-window "SpeedRect Command Key Help"
-    (dolist
-	(l '("SpeedRect Rectangle Mark Mode Commands\n"
-	     "============================================================================\n\n"
-	     "Insertion:\n\n"
-	     "  [o] open      open rectangle with tabs/spaces, shifting text right\n"
-	     "  [t] string    replace rectangle with string\n\n"
-	     "Killing:\n\n"
-	     "  [k] kill      kill and save rectangle for yanking\n"
-	     "  [d] delete    kill rectangle without saving\n"
-	     "  [SPC] del-ws  delete all whitespace, starting from left column\n"
-	     "  [c] clear     clear rectangle area by overwriting with spaces\n"
-	     "  [r] rest      delete the rest of the columns, keeping the marked rectangle\n\n"
-	     "Copy/Yank:\n\n"
-	     "  [w] copy      copy rectangle for future rectangle yanking\n"
-	     "  [W] copy      copy rectangle to kill ring as normal text\n"
-	     "  [y] yank      yank rectangle, inserting at point\n\n"
-	     "Shift Rectangle (can use numeric prefixes):\n\n"
-	     "  [S-left]      move the rectangle left\n"
-	     "  [S-right]     move the rectangle right\n"
-	     "  [S-up]        move the rectangle up\n"
-	     "  [S-down]      move the rectangle down\n"
-	     "  [M-S-left]    move the rectangle left 5 columns\n"
-	     "  [M-S-right]   move the rectangle right 5 columns\n"
-	     "  [M-S-up]      move the rectangle up 5 lines\n"
-	     "  [M-S-down]    move the rectangle down 5 lines\n\n"
-	     "Change Rectangle:\n\n"
-	     "  [x] corners   move point around corners of the rectangle\n"
-	     "  [n] new       start a new rectangle from this location\n"
-	     "  [l] last      restore the last used rectangle, if possible\n\n"
-	     "Numerical:\n\n"
-	     "  [N] numbers   fill the rectangle with numbers (prefix to set start)\n"
-	     "  [#] grab      grab the rectangle as a matrix in calc\n"
-	     "  [_] across    sum across rows and grab result in calc as a vector\n"
-	     "  [:] down      sum down the columns and grab result in calc\n"
-	     "  [m] yank-mat  yank matrix from top of calc stack, overwriting selected rect\n\n"
-	     "Etc:\n\n"
-	     "  [f] fill      fill text within rectangle (prefix to prompt fill width)\n"
-	     "  [M] multiple-cursors  add cursors at current column\n"
-	     "  [?] help      view this Help buffer\n"
-	     "  [q] quit      exit rectangle-mark-mode"))
-      (princ l))))
+    (princ "SpeedRect Rectangle Mark Mode Commands
+============================================================================\n
+Insertion:
+  [o] open      open rectangle with tabs/spaces, shifting text right
+  [t] string    replace rectangle with string\n
+Killing:\n
+  [k] kill      kill and save rectangle for yanking
+  [d] delete    kill rectangle without saving
+  [SPC] del-ws  delete all whitespace, starting from left column
+  [c] clear     clear rectangle area by overwriting with spaces
+  [r] rest      delete the rest of the columns, keeping the marked rectangle\n
+Copy/Yank:\n
+  [w] copy      copy rectangle for future rectangle yanking
+  [W] copy      copy rectangle to kill ring as normal text
+  [y] yank      yank rectangle, inserting at point\n
+Shift Rectangle (can use numeric prefixes):\n
+  [S-left]      move the rectangle left
+  [S-right]     move the rectangle right
+  [S-up]        move the rectangle up
+  [S-down]      move the rectangle down
+  [M-S-left]    move the rectangle left 5 columns
+  [M-S-right]   move the rectangle right 5 columns
+  [M-S-up]      move the rectangle up 5 lines
+  [M-S-down]    move the rectangle down 5 lines\n
+Change Rectangle:\n
+  [x] corners   move point around corners of the rectangle
+  [n] new       start a new rectangle from this location
+  [l] last      restore the last used rectangle, if possible\n
+Numerical:\n
+  [N] numbers   fill the rectangle with numbers (prefix to set start)
+  [#] grab      grab the rectangle as a matrix in calc
+  [_] across    sum across rows and grab result in calc as a vector
+  [:] down      sum down the columns and grab result in calc
+  [m] yank-mat  yank matrix from top of calc stack, overwriting selected rect\n
+Etc:\n
+  [f] fill      fill text within rectangle (prefix to prompt fill width)
+  [M] multiple-cursors  add cursors at current column
+  [?] help      view this Help buffer
+  [q] quit      exit rectangle-mark-mode")))
 
 ;;;; Bindings and mode
 (defun speedrect-quit ()
@@ -345,8 +344,7 @@ inserted text."
   (interactive)
   (deactivate-mark))
 
-(defun speedrect--wrap-command
-     (command &optional after)
+(defun speedrect--wrap-command (command &optional after)
   "Wrap an interactive COMMAND to store rect and (posibly) reenter.
 Many/most rectangle commands deactivate mark and exit
 `rectangle-mark-mode'.  This stashes the rectangle before such
@@ -425,7 +423,12 @@ prior to deactivating mark."
 	       ""))))
 
 ;;; autoload
-(add-hook 'rectangle-mark-mode-hook #'speedrect-hook)
+(define-minor-mode speedrect-mode
+  "Enable rectangular modal editing."
+  :global t
+  (if speedrect-mode
+      (add-hook 'rectangle-mark-mode-hook #'speedrect-hook)
+    (remove-hook 'rectangle-mark-mode-hook #'speedrect-hook)))
 
 (provide 'speedrect)
 ;;; speedrect.el ends here

  reply	other threads:[~2024-12-03 20:05 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-03 16:28 Proposed for ELPA: speedrect JD Smith
2024-12-03 20:05 ` Philip Kaludercic [this message]
2024-12-03 20:50   ` JD Smith
2024-12-06 11:10     ` Philip Kaludercic
2024-12-06 11:53       ` JD Smith
2024-12-08 12:25         ` Philip Kaludercic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y10wjzws.fsf@posteo.net \
    --to=philipk@posteo.net \
    --cc=emacs-devel@gnu.org \
    --cc=jdtsmith@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).