From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Toru TSUNEYOSHI" Newsgroups: gmane.emacs.devel Subject: Re: patch about moving file (or directory) to the Recycle Bin on Windows NT series Date: Wed, 28 May 2008 02:11:21 +0900 Message-ID: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0045_01C8C068.1F570EB0" X-Trace: ger.gmane.org 1211908350 22912 80.91.229.12 (27 May 2008 17:12:30 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 27 May 2008 17:12:30 +0000 (UTC) To: Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue May 27 19:13:01 2008 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1K12in-0001LU-2x for ged-emacs-devel@m.gmane.org; Tue, 27 May 2008 19:12:25 +0200 Original-Received: from localhost ([127.0.0.1]:33266 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K12i1-0008Ht-Fi for ged-emacs-devel@m.gmane.org; Tue, 27 May 2008 13:11:37 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K12hw-0008Ho-JD for emacs-devel@gnu.org; Tue, 27 May 2008 13:11:32 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K12hu-0008HF-3H for emacs-devel@gnu.org; Tue, 27 May 2008 13:11:31 -0400 Original-Received: from [199.232.76.173] (port=57832 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K12ht-0008HC-Th for emacs-devel@gnu.org; Tue, 27 May 2008 13:11:29 -0400 Original-Received: from bay0-omc1-s13.bay0.hotmail.com ([65.54.246.85]:48396) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1K12ht-00026x-GP for emacs-devel@gnu.org; Tue, 27 May 2008 13:11:29 -0400 Original-Received: from hotmail.com ([207.46.10.18]) by bay0-omc1-s13.bay0.hotmail.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 27 May 2008 10:11:26 -0700 Original-Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC; Tue, 27 May 2008 10:11:26 -0700 Original-Received: from 124.155.30.210 by BAY121-DAV8.phx.gbl with DAV; Tue, 27 May 2008 17:11:23 +0000 X-Originating-IP: [124.155.30.210] X-Originating-Email: [t_tuneyosi@hotmail.com] X-Sender: t_tuneyosi@hotmail.com X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1914 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1914 X-OriginalArrivalTime: 27 May 2008 17:11:26.0590 (UTC) FILETIME=[B27839E0:01C8C01C] X-detected-kernel: by monty-python.gnu.org: Windows 2000 SP4, XP SP1+ X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:97813 Archived-At: This is a multi-part message in MIME format. ------=_NextPart_000_0045_01C8C068.1F570EB0 Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit Thanks for your helping, Jason and Stefan. I fixed a patch according to it. (I read archives on http://lists.gnu.org/archive/html/emacs-devel/.) (I write again.) step to enable move-file-to-trash: cd src patch -i patch__enable_delete_to_trash.diff make all install Run emacs (load-file "move-file-to-trash.el") (setq delete-by-moving-to-trash t) ------=_NextPart_000_0045_01C8C068.1F570EB0 Content-Type: application/octet-stream; name="move-file-to-trash.el" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="move-file-to-trash.el" ;; moved to C source code ;; ;; (defvar delete-by-moving-to-trash nil ;; "Non nil means redirect to `move-file-to-trash' ;; by `delete-file' or `delete-directory'") (or (functionp 'orig-backup-extract-version) (fset 'orig-backup-extract-version (symbol-function 'backup-extract-version))) ;; Note: The following function can deal with directory properly. (defun backup-extract-version (fn) "Given the name of a numeric backup file, return the backup number. Uses the free variable `backup-extract-version-start', whose value should be the index in the name where the version number begins." (if (and (string-match "[0-9]+~/?$" fn backup-extract-version-start) (= (match-beginning 0) backup-extract-version-start)) (string-to-int (substring fn backup-extract-version-start -1)) 0)) (defvar trash-directory "~/.Trash" "Trash directory to move file (or directory) by `move-file-to-trash', when system-specific move-file-to-trash doesn't exist. If set \".Trash\", always move to the directory under default-directory. See also `delete-by-moving-to-trash'.") (defun move-file-to-trash (filename) "Move file (or directory) named FILENAME. Usually this function is called by `delete-file' or `delete-directory', so must return nil if succeed." (interactive "fMove file to trash: ") (cond ((fboundp 'system-move-file-to-trash) (system-move-file-to-trash filename)) (t (let* ((trash-dir (expand-file-name trash-directory)) (fn (directory-file-name (expand-file-name filename))) (fn-nondir (file-name-nondirectory fn)) (new-fn (expand-file-name fn-nondir trash-dir))) (or (file-directory-p trash-dir) (make-directory trash-dir t)) (and (file-exists-p new-fn) ;; make new-fn unique. ;; example: "~/.Trash/abc.txt" -> "~/.Trash/abc.txt.~1~" (let ((version-control t)) (setq new-fn (car (find-backup-file-name new-fn))))) ;; stop processing if fn is same or parent directory of trash-dir. (and (string-match fn trash-dir) (error (message "filename `%s' is same or parent directory of trash-directory." filename))) (rename-file fn new-fn))))) ------=_NextPart_000_0045_01C8C068.1F570EB0 Content-Type: application/octet-stream; name="patch__enable_delete_to_trash.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="patch__enable_delete_to_trash.diff" --- src/emacs.c.orig 2008-01-10 21:16:14.000000000 +0900=0A= +++ src/emacs.c 2008-05-26 23:33:50.355468800 +0900=0A= @@ -1588,6 +1588,7 @@=0A= syms_of_vmsproc ();=0A= #endif /* VMS */=0A= #ifdef WINDOWSNT=0A= + syms_of_w32 ();=0A= syms_of_ntproc ();=0A= #endif /* WINDOWSNT */=0A= syms_of_window ();=0A= --- src/fileio.c.orig 2008-03-11 10:56:52.000000000 +0900=0A= +++ src/fileio.c 2008-05-26 23:33:50.385512000 +0900=0A= @@ -231,6 +231,13 @@=0A= int write_region_inhibit_fsync;=0A= #endif=0A= =0A= +/* Nonzero means call move-file-to-trash in Fdelete_file or=0A= + Fdelete_directory. */=0A= +int delete_by_moving_to_trash;=0A= +=0A= +/* Lisp functions for move file to trash */=0A= +Lisp_Object Qmove_file_to_trash;=0A= +=0A= extern Lisp_Object Vuser_login_name;=0A= =0A= #ifdef WINDOWSNT=0A= @@ -2669,6 +2676,9 @@=0A= if (!NILP (handler))=0A= return call2 (handler, Qdelete_directory, directory);=0A= =0A= + if (delete_by_moving_to_trash)=0A= + return call1 (Qmove_file_to_trash, directory);=0A= +=0A= encoded_dir =3D ENCODE_FILE (directory);=0A= =0A= dir =3D SDATA (encoded_dir);=0A= @@ -2702,6 +2712,9 @@=0A= if (!NILP (handler))=0A= return call2 (handler, Qdelete_file, filename);=0A= =0A= + if (delete_by_moving_to_trash)=0A= + return call1 (Qmove_file_to_trash, filename);=0A= +=0A= encoded_file =3D ENCODE_FILE (filename);=0A= =0A= if (0 > unlink (SDATA (encoded_file)))=0A= @@ -6757,6 +6770,13 @@=0A= write_region_inhibit_fsync =3D 0;=0A= #endif=0A= =0A= + DEFVAR_BOOL ("delete-by-moving-to-trash", &delete_by_moving_to_trash,=0A= + doc: /* Non-nil means redirect to `move-file-to-trash'=0A= +by `delete-file' or `delete-directory'. */);=0A= + delete_by_moving_to_trash =3D 0;=0A= + Qmove_file_to_trash =3D intern ("move-file-to-trash");=0A= + staticpro (&Qmove_file_to_trash);=0A= +=0A= defsubr (&Sfind_file_name_handler);=0A= defsubr (&Sfile_name_directory);=0A= defsubr (&Sfile_name_nondirectory);=0A= --- src/lisp.h.orig 2008-01-10 21:16:15.000000000 +0900=0A= +++ src/lisp.h 2008-05-26 23:33:50.415555200 +0900=0A= @@ -2898,6 +2898,8 @@=0A= extern void init_fileio_once P_ ((void));=0A= extern Lisp_Object make_temp_name P_ ((Lisp_Object, int));=0A= EXFUN (Fmake_symbolic_link, 3);=0A= +extern Lisp_Object Qdelete_directory;=0A= +extern Lisp_Object Qdelete_file;=0A= =0A= /* Defined in abbrev.c */=0A= =0A= --- src/w32.c.orig 2008-02-23 22:49:09.000000000 +0900=0A= +++ src/w32.c 2008-05-28 01:14:30.334352800 +0900=0A= @@ -75,6 +75,11 @@=0A= #include =0A= #include =0A= =0A= +#include =0A= +#ifndef FOF_NO_CONNECTED_ELEMENTS=0A= +#define FOF_NO_CONNECTED_ELEMENTS 0x2000=0A= +#endif /* FOF_NO_CONNECTED_ELEMENTS */=0A= +=0A= #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */=0A= #include =0A= #undef socket=0A= @@ -96,6 +101,8 @@=0A= #undef sendto=0A= #endif=0A= =0A= +#include "charset.h"=0A= +#include "coding.h"=0A= #include "w32.h"=0A= #include "ndir.h"=0A= #include "w32heap.h"=0A= @@ -104,6 +111,7 @@=0A= typedef HRESULT (WINAPI * ShGetFolderPath_fn)=0A= (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);=0A= =0A= +void syms_of_w32 ();=0A= void globals_of_w32 ();=0A= =0A= extern Lisp_Object Vw32_downcase_file_names;=0A= @@ -2256,6 +2264,65 @@=0A= return _unlink (path);=0A= }=0A= =0A= +/* deverted from delete-file in fileio.c */=0A= +DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,=0A= + Ssystem_move_file_to_trash, 1, 1, "fMove file to trash: ",=0A= + doc: /* Move file (or direcotry) named FILENAME. */)=0A= + (filename)=0A= + Lisp_Object filename;=0A= +{=0A= + Lisp_Object handler;=0A= + Lisp_Object encoded_file;=0A= + Lisp_Object operation;=0A= +=0A= + operation =3D Qdelete_file;=0A= + if (!NILP (Ffile_directory_p (filename))=0A= + && NILP (Ffile_symlink_p (filename)))=0A= + {=0A= + operation =3D Qdelete_directory;=0A= + filename =3D Fdirectory_file_name (filename, Qnil);=0A= + }=0A= + filename =3D Fexpand_file_name (filename, Qnil);=0A= +=0A= + handler =3D Ffind_file_name_handler (filename, operation);=0A= + if (!NILP (handler))=0A= + return call2 (handler, operation, filename);=0A= +=0A= + encoded_file =3D ENCODE_FILE (filename);=0A= +=0A= + {=0A= + const char * path;=0A= + SHFILEOPSTRUCT file_op;=0A= + /* +1 means space for NULL character representing the end of the=0A= + final name to indicate the pFrom member of struct SHFILEOPSTRUCT = */=0A= + char tmp_path[MAX_PATH + 1];=0A= +=0A= + path =3D map_w32_filename (SDATA (encoded_file), NULL);=0A= +=0A= + /* On Unix, unlink works without write permission. */=0A= + _chmod (path, 0666);=0A= +=0A= + memset (tmp_path, 0, sizeof (tmp_path));=0A= + strcpy (tmp_path, path);=0A= +=0A= + memset (&file_op, 0, sizeof (file_op));=0A= + file_op.hwnd =3D HWND_DESKTOP;=0A= + file_op.wFunc =3D FO_DELETE;=0A= + file_op.pFrom =3D tmp_path;=0A= + file_op.pTo =3D NULL;=0A= + file_op.fFlags =3D FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO=0A= + | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;=0A= + file_op.fAnyOperationsAborted =3D FALSE;=0A= + file_op.hNameMappings =3D NULL;=0A= + file_op.lpszProgressTitle =3D NULL;=0A= +=0A= + if (SHFileOperation (&file_op) !=3D 0)=0A= + report_file_error ("Removing old name", list1 (filename));=0A= + }=0A= +=0A= + return Qnil;=0A= +}=0A= +=0A= static FILETIME utc_base_ft;=0A= static long double utc_base;=0A= static int init =3D 0;=0A= @@ -4140,6 +4207,12 @@=0A= return FALSE;=0A= }=0A= =0A= +void=0A= +syms_of_w32 ()=0A= +{=0A= + defsubr (&Ssystem_move_file_to_trash);=0A= +}=0A= +=0A= /*=0A= globals_of_w32 is used to initialize those global variables that=0A= must always be initialized on startup even when the global variable=0A= --- src/w32.h.orig 2008-01-10 21:16:16.000000000 +0900=0A= +++ src/w32.h 2008-05-26 23:33:50.485656000 +0900=0A= @@ -129,6 +129,7 @@=0A= =0A= extern void init_ntproc (void);=0A= extern void term_ntproc (void);=0A= +extern void syms_of_w32 (void);=0A= extern void globals_of_w32 (void);=0A= extern void syms_of_w32term (void);=0A= extern void syms_of_w32fns (void);=0A= ------=_NextPart_000_0045_01C8C068.1F570EB0--