unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Ivan Sokolov <ivan-p-sokolov@ya.ru>
To: 64531@debbugs.gnu.org
Cc: Eli Zaretskii <eliz@gnu.org>, Dmitry Gutov <dgutov@yandex.ru>
Subject: bug#64531: [PATCH v3] Add new commands for copying VC filenames
Date: Mon, 04 Sep 2023 23:08:02 +0300	[thread overview]
Message-ID: <87a5u1em71.fsf@ya.ru> (raw)
In-Reply-To: <87bkgmq1ra.fsf@ya.ru>

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

Hi, Eli and Dmitry!

I tried to write documentation for the previous version of the command
and came to the conclusion that I crammed too much functionality into
it.  So I divided the DWIM command into command for copying name at
point (bound to w) and command for copying marked files (bound to * w).

I also added new command for copying VC related filenames from
everywhere.  An appropriate binding would be C-x v w, but I am not sure
if I should use a top-level binding for such an insignificant command.

Quoting and prefix arguments now copy `dired-copy-filename-as-kill'.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: [PATCH] Add new commands for copying VC filenames --]
[-- Type: text/x-patch, Size: 7558 bytes --]

From 0baa37ff90fb58e43240586a401a6145da78b3f5 Mon Sep 17 00:00:00 2001
From: Ivan Sokolov <ivan-p-sokolov@ya.ru>
Date: Mon, 4 Sep 2023 22:33:32 +0300
Subject: [PATCH] Add new commands for copying VC filenames

---
 doc/emacs/maintaining.texi | 13 ++++++++++++
 etc/NEWS                   |  7 +++++++
 lisp/vc/vc-dir.el          | 20 +++++++++++++++++-
 lisp/vc/vc.el              | 43 +++++++++++++++++++++++++++++++-------
 4 files changed, 75 insertions(+), 8 deletions(-)

diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 2dad70d3d13..8e7e2365f0a 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1388,6 +1388,13 @@ You can use this command to mark files that are in one of registered
 states, including edited, added or removed.
 (@code{vc-dir-mark-registered-files}).
 
+@findex vc-dir-copy-marked-files-as-kill
+@item * w
+This command copy names of marked files into the kill ring.  If prefix
+argument is 0 names are absolute, with other prefix arguments names
+are relative to the VC root directory.  Without prefix names are
+relative to the VC buffer directory.
+
 @item G
 Add the file under point to the list of files that the VC should
 ignore (@code{vc-dir-ignore}).  For instance, if the VC is Git, it
@@ -1407,6 +1414,12 @@ point is on a directory entry, unmark all files in that directory tree
 (@code{vc-dir-unmark-all-files}).  With a prefix argument, unmark all
 files and directories.
 
+@item w
+Copy the name of the file at point into the kill ring.  If prefix
+argument is 0 name is absolute, with other prefix arguments name is
+relative to the VC root directory.  Without prefix name is relative to
+the VC buffer directory.
+
 @item x
 Hide files with @samp{up-to-date} or @samp{ignored} status
 (@code{vc-dir-hide-up-to-date}).  With a prefix argument, hide items
diff --git a/etc/NEWS b/etc/NEWS
index c97df11042d..77192b23cb7 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -262,6 +262,13 @@ This is a string or a list of strings that specifies the Git log
 switches for shortlogs, such as the one produced by 'C-x v L'.
 'vc-git-log-switches' is no longer used for shortlogs.
 
+*** New commands for copying names of Version Controlled files
+Commands 'vc-dir-copy-filename-as-kill' and
+'vc-dir-copy-marked-files-as-kill' work like
+'dired-copy-filename-as-kill' but in VC-dir buffer.  Command
+'vc-copy-filename-as-kill' copies name of the interactively chosen
+file.
+
 ** Diff Mode
 
 +++
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index 53d58870b32..3a4b8dbd18d 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -353,6 +353,7 @@ See `run-hooks'."
     (define-key map (kbd "M-s a C-s")   #'vc-dir-isearch)
     (define-key map (kbd "M-s a M-C-s") #'vc-dir-isearch-regexp)
     (define-key map "G" #'vc-dir-ignore)
+    (define-key map "w" #'vc-dir-copy-filename-as-kill)
 
     (let ((branch-map (make-sparse-keymap)))
       (define-key map "b" branch-map)
@@ -367,7 +368,8 @@ See `run-hooks'."
     (let ((mark-map (make-sparse-keymap)))
       (define-key map "*" mark-map)
       (define-key mark-map "%" #'vc-dir-mark-by-regexp)
-      (define-key mark-map "r" #'vc-dir-mark-registered-files))
+      (define-key mark-map "r" #'vc-dir-mark-registered-files)
+      (define-key mark-map "w" #'vc-dir-copy-marked-files-as-kill))
 
     ;; Hook up the menu.
     (define-key map [menu-bar vc-dir-mode]
@@ -930,6 +932,22 @@ system."
   (interactive)
   (view-file (vc-dir-current-file)))
 
+(defun vc-dir-copy-filename-as-kill ()
+  "In VC-dir buffer copy name of the file at point into the kill ring.
+With a zero prefix arg, use the absolute file name.
+With \\[universal-argument], use the file name relative to `vc-root-dir'."
+  (interactive)
+  (vc--copy-filenames-as-kill (list (vc-dir-current-file))))
+
+(defun vc-dir-copy-marked-files-as-kill ()
+  "In VC-dir buffer copy names of the marked files into the kill ring.
+With a zero prefix arg, use the absolute file names.
+With \\[universal-argument], use the file names relative to `vc-root-dir'."
+  (interactive)
+  (if-let* ((files (vc-dir-marked-files)))
+      (vc--copy-filenames-as-kill files t)
+    (message "No marked files")))
+
 (defun vc-dir-isearch ()
   "Search for a string through all marked buffers using Isearch."
   (interactive)
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index be7fa46c28e..9e352cfc467 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1205,6 +1205,13 @@ BEWARE: this function may change the current buffer."
      (completing-read prompt (mapcar #'symbol-name backends)
                       nil 'require-match nil nil default))))
 
+(defun vc-read-file (prompt)
+  "Read file name, prompting with PROMPT.
+Default is the current file if it is under version control."
+  (read-file-name prompt nil (when (vc-backend buffer-file-name)
+                               buffer-file-name)
+                  t))
+
 ;; Here's the major entry point.
 
 ;;;###autoload
@@ -3261,10 +3268,7 @@ backend to NEW-BACKEND, and unregister FILE from the current backend.
   "Delete file and mark it as such in the version control system.
 If called interactively, read FILE, defaulting to the current
 buffer's file name if it's under version control."
-  (interactive (list (read-file-name "VC delete file: " nil
-                                     (when (vc-backend buffer-file-name)
-                                       buffer-file-name)
-                                     t)))
+  (interactive (list (vc-read-file "VC delete file: ")))
   (setq file (expand-file-name file))
   (let ((buf (get-file-buffer file))
         (backend (vc-backend file)))
@@ -3305,9 +3309,7 @@ buffer's file name if it's under version control."
   "Rename file OLD to NEW in both work area and repository.
 If called interactively, read OLD and NEW, defaulting OLD to the
 current buffer's file name if it's under version control."
-  (interactive (list (read-file-name "VC rename file: " nil
-                                     (when (vc-backend buffer-file-name)
-                                       buffer-file-name) t)
+  (interactive (list (vc-read-file "VC rename file: ")
                      (read-file-name "Rename to: ")))
   ;; in CL I would have said (setq new (merge-pathnames new old))
   (let ((old-base (file-name-nondirectory old)))
@@ -3340,6 +3342,33 @@ current buffer's file name if it's under version control."
 	(vc-mode-line new (vc-backend new))
 	(set-buffer-modified-p nil)))))
 
+(defun vc--copy-as-kill (str)
+  (if (eq last-command 'kill-region)
+      (kill-append str nil)
+    (kill-new str))
+  (message "%s" str))
+
+(defun vc--copy-filenames-as-kill (files &optional quote)
+  (vc--copy-as-kill
+   (mapconcat
+    (lambda (file)
+      (cond ((eq current-prefix-arg 0)
+             (setq file (expand-file-name file)))
+            ((consp current-prefix-arg)
+             (setq file (file-relative-name file (vc-root-dir)))))
+      (if (and quote (string-match-p "[\s\"']" file))
+          (format "%S" file)
+        file))
+    files " ")))
+
+;;;###autoload
+(defun vc-copy-filename-as-kill (file)
+  "Copy name of the FILE into the kill ring.
+With a zero prefix arg, use the absolute file name.
+With \\[universal-argument], use the file name relative to `vc-root-dir'."
+  (interactive (list (vc-read-file "VC copy filename as kill: ")))
+  (vc--copy-filenames-as-kill (list file)))
+
 ;;;###autoload
 (defun vc-update-change-log (&rest args)
   "Find change log file and add entries from recent version control logs.
-- 
2.41.0


  parent reply	other threads:[~2023-09-04 20:08 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-08  7:51 bug#64531: [PATCH] Add new command vc-dir-copy-filename-as-kill Ivan Sokolov
2023-07-08  9:25 ` Eli Zaretskii
2023-08-08 13:44   ` bug#64531: [PATCH v2] " Ivan Sokolov
2023-08-08 13:56     ` Eli Zaretskii
2023-08-19  8:06     ` Eli Zaretskii
2023-08-19 23:12       ` Ivan Sokolov
2023-08-20  6:20         ` Eli Zaretskii
2023-08-19 23:33       ` Dmitry Gutov
2023-08-20  6:26         ` Eli Zaretskii
2023-08-20 10:26           ` Dmitry Gutov
2023-09-04 20:08 ` Ivan Sokolov [this message]
2023-09-05 11:01   ` bug#64531: [PATCH v3] Add new commands for copying VC filenames Eli Zaretskii
2023-10-19 23:39     ` Dmitry Gutov

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=87a5u1em71.fsf@ya.ru \
    --to=ivan-p-sokolov@ya.ru \
    --cc=64531@debbugs.gnu.org \
    --cc=dgutov@yandex.ru \
    --cc=eliz@gnu.org \
    /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).