From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Philip Kaludercic Newsgroups: gmane.emacs.devel Subject: Re: Proposed for ELPA: speedrect Date: Tue, 03 Dec 2024 20:05:07 +0000 Message-ID: <87y10wjzws.fsf@posteo.net> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="3250"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel To: JD Smith Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Dec 03 21:06:08 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tIZ9r-0000fg-Py for ged-emacs-devel@m.gmane-mx.org; Tue, 03 Dec 2024 21:06:07 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tIZ95-0004WF-CP; Tue, 03 Dec 2024 15:05:19 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tIZ93-0004VA-9q for emacs-devel@gnu.org; Tue, 03 Dec 2024 15:05:17 -0500 Original-Received: from mout02.posteo.de ([185.67.36.66]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tIZ8y-0002Un-22 for emacs-devel@gnu.org; Tue, 03 Dec 2024 15:05:16 -0500 Original-Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 5E6C2240101 for ; Tue, 3 Dec 2024 21:05:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1733256308; bh=6opOtPJwE/5LCwCRfR/vLX/uw1pC8FuUrc8HFHRsTNg=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:From; b=Hu26td4jumKq9TMffl5uRLerc6dDCtJzF9ibwmyiMaIO26Jsh21LBndmDV+w3yH8Q mK0g6+fzS70BseAfh0TNuwozC5Cpd3Zk34y67GoXgw+T+1dyGV5a6Ak5tyejrOgEp4 AG7mk6mgvzTVDQBVFY6+wGODyJYmI6RJeUK1sAQH3f4fzvMxFbqCn1Y3/3QL7rkFgp znRkbzTQRdxyXlUqk+P2Hzu0/8GiUAH1oYnUEW1HG4F4S7h8BN1cVKO0f54EaAEPYa 5+T+tXU4VBi1CnIcos+xsyoKbsiswvkda5jwG9dZSmx3EaMWMwgu3s4n6TV3Dzh0wC AvxvLd11s/Zog== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4Y2s835WHcz6twf; Tue, 3 Dec 2024 21:05:07 +0100 (CET) In-Reply-To: (JD Smith's message of "Tue, 3 Dec 2024 11:28:48 -0500") Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=philipk@posteo.net; url="https://keys.openpgp.org/vks/v1/by-email/philipk@posteo.net"; preference=signencrypt Received-SPF: pass client-ip=185.67.36.66; envelope-from=philipk@posteo.net; helo=mout02.posteo.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:326003 Archived-At: --=-=-= Content-Type: text/plain JD Smith writes: > I propose adding the simple package 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: --=-=-= Content-Type: text/plain Content-Disposition: inline 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 @@ -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 --=-=-=--