* Re: Proposed for ELPA: speedrect
2024-12-03 16:28 Proposed for ELPA: speedrect JD Smith
@ 2024-12-03 20:05 ` Philip Kaludercic
2024-12-03 20:50 ` JD Smith
0 siblings, 1 reply; 3+ messages in thread
From: Philip Kaludercic @ 2024-12-03 20:05 UTC (permalink / raw)
To: JD Smith; +Cc: emacs-devel
[-- 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
^ permalink raw reply related [flat|nested] 3+ messages in thread