From: David Vanderschel Date: Wed Jul 26, 2000 11:31pm Subject: gnuserv: Various Tips for Fully Exploiting this Functionality I recently installed gnuserv. It will enable you realize numerous useful functions, but I was surprised that the documentation for using it effectively was so wanting. I eventually figured out how to make myself reasonably happy, but it was a bit of a struggle. Since I can see from some messages on the list that other folks are not completely clear on how to fully exploit this functionality, I will attempt to share some of what I have learned here. To keep things simpler, I am not normally going to belabor alternative ways of accomplishing similar results. If you are knowledgeable enough to know another way you prefer, then, by all means, do it your way. There are many viable alternatives; and if something I have done is significantly more cumbersome than need be, please clue me in. All of my experience is based on running this stuff under Windows 98. This note is long enough that I imagine there will be some bugs and some things which do not carry directly over to NT. There are also some open issues to which I have called attention. So let me know, and I will fix this note in hopes that some variation on it can be used to augment the current documentation. ** Installation ** ------------ Use the following URL to download the gnuserv package: http://www.gnu.org/software/emacs/windows/ntemacs/contrib/gnuserv-2.1p1.zip Put the .EXE files from the gnuserv package in your emacs bin directory. Put gnuserv.elc in your load-path. (Eg., put gnuserv.el in some lisp directory already in your path and byte-compile it.) Put the (parts you want of the) following elisp code in your emacs initialization (or arrange to load it somehow): ______________________________________________________________________ (defvar dv-initial-frame (car (frame-list)) "Holds initial frame.") (defun dv-focus-frame (frame) "pop to top and give focus" ;; Code 'borrowed' from frame.el. ;; (Meaning I don't understand it. But it beats all I tried. :) (make-frame-visible frame) (raise-frame frame) (select-frame frame) (w32-focus-frame frame)) (defun dv-focus-initial-frame () "Make the initial frame visible" (dv-focus-frame dv-initial-frame)) (defvar dv-mail-frames () "Frames created by dv-do-mailto") (defun dv-do-mailto (arg) "For handling mailto URLs via gnudoit" (dv-focus-frame (make-frame)) (message-mail (substring arg 7)) (delete-other-windows) (setq dv-mail-frames (cons (selected-frame) dv-mail-frames))) (defun dv-close-client-frame () "Close frame, kill client buffer." (interactive) (if (or (not (member (selected-frame) dv-mail-frames)) (and (> (length (buffer-name)) 4) (equal (substring (buffer-name) 0 5) "*mail") (not (buffer-modified-p)))) (kill-buffer (current-buffer))) (setq dv-mail-frames (delete (selected-frame) dv-mail-frames)) (if (equal (selected-frame) dv-initial-frame) (iconify-frame) (delete-frame))) (global-set-key [\M-f4] 'dv-close-client-frame) (defun dv-paste-to-temp () "Load clipboard in a temp buffer" (dv-focus-frame (make-frame)) (switch-to-buffer (generate-new-buffer "temp")) (clipboard-yank)) (require 'gnuserv) (gnuserv-start) ______________________________________________________________________ The ntemacs Web page says, "Jerrad Pierce belg4mit@m... has packaged together a PIF file and batch file for associating Emacs with file-types via gnuserv." As far as I am concerned, none of that stuff should be used. It serves no useful purpose that I can determine, and it definitely slows things down. In particular, it is gnuclient.exe itself which should be associated with files, not assoc.bat. The only apparent 'feature' of assoc.bat is that it will start emacs if it is not already running (as inferred by the fact that gnuclient exits with an error). This is not only unnecessary, but it is also confusing, as gnuclient or gnudoit will itself invoke runemacs when no instance of emacs (with gnuserv) is already running. (It is conceivable that Pierce had earlier versions of the client programs which did not know how to start emacs or that he failed to realize the capability was in there because he had a configuration in which gnuclient could not find runemacs. For the latter, it suffices for both of them to be in the same directory or for runemacs and emacs to be in your path.) In my AUTOEXEC.BAT, I have defined an environment variable, EMACS_BIN, like so: SET EMACS_BIN=d:\emacs\emacs-20.7\bin Don't copy that, as your configuration is almost certainly different. In the command examples, I will always write "%EMACS_BIN%" to refer to that part of the path. You may want to define EMACS_BIN in your environment also. However, it is necessary to substitute the actual path in most cases, and (for a small efficiency) it is probably just as well to substitute the actual path in all cases. So you may regard occurrences of %EMACS_BIN% as a reminder to substitute what makes sense for your configuration. Note that I am not assuming that EMACS_BIN is in your path. Indeed, it is not in mine. I recommend that you download and install the X-Setup freeware utility from Xteq Systems: http://www.xteq.com/products/xset/index.html X-Setup is like TweakUI on steroids. (One big advantage of it is that it includes more documentation about the meanings of various registry keys and the implications of changing them.) Whenever possible, I would rather tell you how to modify your Registry via X-Setup than suggest that you edit the Registry directly and then have to give the standard warnings which usually accompany such suggestions. X-Setup claims to support Windows NT and 2000 as well. ** File Associations ** ----------------- Go to Folder Options. (Start -> Settings, or on the View or Tools pulldown menus in Windows Explorer) On the "File Types" tab, select the file type you want to associate with emacs. An obvious example is "Text Document" which is associated with Notepad by default. Click "Edit". Select "Open". Click "Edit". Enter the following command: %EMACS_BIN%\gnuclient.exe -q -F "%1" You must substitute the full path. The environment variable does not work here. Similarly for other types you want to open in emacs. In X-Setup, under Appearance -> Explorer -> Files -> Unknown File Command, you can put the same command (with full path). With this is place, you will no longer get the dialogue box which asks which program you want open the file with. All unknown types will be opened in emacs. (If there remain exceptions for you, there is still the "Open with ..." option on the context menu for the file.) If you are feeling adventurous, search your Registry for entries in which "notepad.exe" appears in the key's data field. In the "open" cases, if the situation is one which you experience, you can substitute gnuclient.exe as above. Unfortunately, attempting this myself, I cannot find one which IE uses for View -> Source. So, if anyone knows this, please clue me in. (For IE to use Notepad in this context is especially obnoxious, since many HTML files (like that for the ntemacs Web page) are too big for Notepad.) ** Explorer Context Menus ** ---------------------- Pressing Shift-F10 or the APPLICATION key (adjacent to right Ctrl on Windows keyboards) for a selected file or folder or right clicking will pop up a context menu including a variety of operations which may be performed on the object. You can add emacs options for files and folders using X-Setup. I added an "emacs dired" item to the context menu for folders in Explorer. This makes it easy to swing into emacs for browsing if you happened to have started out with some Explorer variation (like Find or a shortcut to a folder). Similarly, in the context menu for files, I added "Open in emacs". The place to do this in X-Setup is under Appearance -> Explorer -> Context Menu. The associated commands both look like the following: %EMACS_BIN%\gnuclient.exe -q -F "%1" Again, you must spell out the whole path. In the name of the command, put the ampersand character, "&", before the character you want to use as a keyboard shortcut for the command. In my case, I used the "i" in "dired" and the "i" in "in". It is not very mnemonic, but at least it is the same key in either context and it does not conflict with any of the other keyboard shortcuts on those context menus in my setup. (Interesting symmetry regarding swinging into dired mode from Explorer: You can do the converse by invoking the following dired-execute-file command on a directory in dired. ;; dired stuff to open files a la Windows from Howard Melman ;; (defun dired-execute-file (&optional arg) (interactive "P") (mapcar #'(lambda (file) (w32-shell-execute "open" (convert-standard-filename file))) (dired-get-marked-files nil arg))) I have it bound (locally in dired) to "X". It is useful as well for starting executables or otherwise opening files in accordance with Windows file type associations.) ** "Show emacs" Desktop Shortcut and Hot Key ** ----------------------------------------- One thing I wanted from gnuserv is a way to bring up an emacs window (frame) using a hot key. I refer to the first frame in which emacs starts as the "initial frame" and any others which get spawned as "subordinate frames". I have a shortcut named "Show emacs" on the desktop with the following command: %EMACS_BIN%\gnudoit.exe -q (dv-focus-initial-frame) It is set to run minimized. Double-clicking or otherwise 'opening' the shortcut will cause emacs' initial frame to come up. In the shortcut, I defined Ctrl-Alt-e as a shortcut key for showing emacs. (As far as I can tell, the Windows shortcut has to be on the desktop or Windows won't pick up on the associated shortcut key.) If no instance of emacs (with gnuserv) was already running, the call to gnudoit will cause runemacs to be invoked first. Note that defining the Windows shortcut key makes whatever you use (Ctrl-Alt-e in this case for me) unavailable in emacs. However, all functions bound in emacs to M-C-key combinations can also be invoked via "esc C-key", and that continues to work. For anyone who does not wish to use up Ctrl-Alt-key combinations for Windows shortcut keys (in general - not just for emacs-related shortcuts) and who has a Windows-compliant keyboard, there is a good alternative using the Winkey freeware utility instead of MicroSoft's (apparently lame) shortcut keys. See http://www.copernic.com/winkey/ In Winkey, command parameters (like "-q (dv-focus-initial-frame)" above) are entered in a separate field from that which specifies the path to the executable. Relative to emacs and compared to the MS-Windows shortcut keys, I think Winkey is a big win because it allows you to define Windows-key shortcuts none of which will run afoul of classic emacs key bindings (many of which already use C-M-key's). I have Windows-z 'bound' to the same gnudoit command as above. (Somewhat natural: Ctrl-z - iconify; Windows-z - deiconify.) It typically pops up emacs in a small fraction of a second, while Ctrl-Alt-e typically takes a full second on my system (350MHz AMD K6-2 with 128MB); so the Winkey approach to associating hot keys also gives better performance. (When I tried a batch file (somewhat similar to Pierce's) for popping up emacs, it tended to take about 3 seconds, which is enough to make me impatient.) ** Drag and Drop Shortcut ** ---------------------- I have another shortcut, named simply "emacs". with the following command: %EMACS_BIN%\gnuclientw.exe -F "%1" Note the "w". (For some reason which I do not understand in this drag and drop case, the -q flag to gnuclient is not sufficient to prevent the resulting buffer from 'believing' that there is a client waiting on it. Looking at the code, I see no difference between gnuclientw and gnuclient invoked with the -q flag. Yet "gnuclientw" works while "gnuclient -q" does not. So this is a mystery. I have to suspect that those two .EXE's in the gnuserv package were not linked the same way.) I have set this shortcut also to run minimized. It needs no shortcut key. I put this shortcut on the Quick Launch Bar. Though I generally prefer to use the context menus, this shortcut is sometimes handy for drag and drop. I did not even bother to put such a shortcut on my desktop since I find one there to be relatively useless for drag and drop, as it is most likely to be covered up by some window. I am not a big fan of "drag and drop" anyway. But do note that, somewhat more usefully, if you have an emacs frame open, you can drop a file or folder directly on the frame and emacs will open it. Clicking this shortcut on the Quick Launch Bar will cause a new emacs frame to pop up visiting a new file named %1. This is not too useful, so I recommend to use this shortcut only to open files or directories via drag and drop. (At one point I had a batch file which could recognize the absence of a file argument and, in such a case, behave like the "Show emacs" shortcut instead. However, because of the performance consideration, I decided that this bit of automation was not worth it, especially since my habit is almost always to use a hot key for showing emacs anyway.) As I mentioned, I am not a big fan of "drag and drop". However, the way MS has implemented Copy and Paste for file and folder objects in Explorer is actually quite nice (in general, but not a big deal for emacs). In our context, you can Copy a file or folder, get the context menu for the "emacs" shortcut (eg., right-click) and select Paste. The right thing happens. ** Clipboard Viewing Hot Key ** ------------------------- To get a quick way to load the current content of the Windows clipboard into an emacs buffer, put the command %EMACS_BIN%\gnudoit.exe -q (dv-paste-to-temp) in a desktop shortcut with a shortcut key or associate the command with a Windows-key using Winkey. I regard this one as just a simple example of the sort of thing you might like to create for yourself and attach to a hot key. (Eg., I have created a complex one which I use to reply in emacs to email received in Outlook Express. By Copying to the clipboard the content of OE's message composition window and invoking my special function with gnudoit, I automatically prepare a reply in message-mail with appropriate Subject: and To: headers and quoting the body the way I like to do it. This one is sufficiently specialized to my personal tastes that I am not including it in these tips; but, if you are interested and prepared to customize the code to your own tastes, you are welcome to ask.) ** Icons ** ----- If you create any of the above-suggested desktop shortcuts, you will want to associate a suitable icon. You will find an assortment of them for emacs in emacs' \etc\icons\ directory. ** Handling IE mailto: URLs ** ------------------------ The ntemacs Web page suggests the following Registry tweak to configure things so that clicking on a mailto: link in Internet Explorer will put you in emacs for preparing the message: Key: HKEY_CLASSES_ROOT\mailto\shell\open\command\(Default) Value: gnudoit -q (message-mail (substring \"%1\" 7)) I have 'improved' that, and I suggest the following: Value: %EMACS_BIN%\gnudoit.exe -q "(dv-do-mailto \"%1\")" This behaves more like the other file associations, popping up a new frame for the message. As with the direct message-mail approach, my trivial dv-do-mailto does not support anything besides a simple To: header. In particular, it cannot handle specifications for the subject header or content for the message body. The w3 package includes code to fully support these URLs. If you have installed it, you can substitute the two lines (url-mailto arg) (not-modified) for the line in dv-do-mailto which currently says (message-mail (substring arg 7)) Even if you have not installed w3 but do still care about the full support for mailto: URLs, you can get the url.el and url-mail.el modules from the w3 distribution and load them. (Here is a trick for IE users which might make you wish you had the full support. Put the following anchor tag in an HTML document: Send Location While viewing the page, right click the "Send Location" 'link' and click "Add to Favorites ...". (Yes, it is safe. :) With it added, you can use this 'favorite' to send an email message containing the URL of the page you are viewing to someone who might be interested. This trick works whether or not you have redirected mailto: URLs to emacs.) For those who do not care for my dv-close-client-frame (See below.) and who do not care about supporting anything but the To: header but who do want the message-mail window to come up in a separate frame, you can blow off my dv-do-mailto and just use message-mail-other-frame as the lisp function for gnudoit to call instead of message-mail. ** Using emacs as File Editor for Other Applications ** ------------------------------------------------- Some applications allow you to specify the editor of your choice for viewing, creating, or editing text files they use. You can use gnuclient in this context as well. In such cases, you should typically not use the -q switch on the gnuclient command: %EMACS_BIN%\gnuclient.exe -F "%1" This will allow the client application to know when you have finished with the file. Ie., after you give a command to go edit a file over in emacs, the application can automatically resume its operation when you kill the resulting buffer. (The gnuclient task does not terminate until the buffer is killed.) The dv-close-client-frame function uses kill-buffer which checks for the existence of a client waiting on the buffer and 'notifies' it when there is one. You still need to save the buffer explicitly. ** Closing Subordinate Frames ** -------------------------- When I spawn a subordinate frame using gnuclient or gnudoit, the resulting frame and buffer are usually of only temporary interest to me. Thus when I finish, I want to delete the window, the buffer, and the frame all in one easy operation. For me, the natural key for this is Alt-F4, since that is how I close lots of other things which I can pop up in Windows. I created a function, dv-close-client-frame, to do this and I bound it to M-f4. It will not save the file the current buffer is visiting, but you will get a warning if the buffer is modified. If you should hit Alt-F4 when the initial frame has the focus, it just iconifies it, still killing the current buffer. (More details below.) (To give me a clue about which emacs frame is the initial frame, I specified a different value for height in initial-frame-alist from what I specify in default-frame-alist. I have a smaller default size for my subordinate emacs frames.) dv-close-client-frame is designed to behave somewhat differently on frames created by dv-do-mailto. In such cases, if the current buffer is not a mail buffer or is modified, no buffer will be killed. OTOH, if the current buffer is a mail buffer and it is not marked as modified, then dv-close-client-frame will still kill the buffer. This is intended to cover the case in which you change your mind about sending the message. However, it will also kill the mail buffer if you use message-send (C-c C-s) instead of message-send-and-exit (C-c C-c), which buries the buffer after sending. (They both clear the "modified" indication after successfully sending the buffer.) So the behaviour is rather different depending on whether you use message-send or message-send-and-exit. I prefer the latter because the default behaviour for message-mail is to keep a (configurable) number of mail buffers around; but they do start disappearing anyway (FIFO) when you exceed the limit. Invoked on a frame not created by dv-do-mailto, dv-close-client-frame will always attempt to kill the current buffer. This presumes that the current buffer is the one for which the frame was created; so please note that dv-close-client-frame is not completely robust if the buffer you are visiting when you invoke it is not the one for which the frame was initially created. If the buffer is modified and visiting a file, you do still get the usual warning about a modified buffer. If you don't want to kill the buffer, then you can just invoke delete-frame (C-x 5 0). (Note that if you delete subordinate frames created by dv-mail-to by means other than dv-close-client-frame, then the dead frames will accumulate in the dv-mail-frames list. I do not regard this as a serious problem; but I cannot figure out how to fix it without advising delete-frame or actually looking for dead frames in the list, both of which I am reluctant to do. As an alternative to the list, I also considered adding another 'property' to the frame configuration object; but, since that is not officially documented, this approach seems risky. Why is there no delete-frame-hook?) ** DOS-Box Problem ** --------------- For reasons I do not understand, the DOS window associated with a gnuclient or gnudoit invocation sometimes persists on my system, though it is supposed to close when the task terminates. (If a DOS window persists inappropriately for you, just hit Ctrl-c when that window has focus.) Furthermore, the DOS boxes sometimes run focussed instead of minimized. This can be a more serious problem, as it appears that emacs has difficulty when it comes to automatically wresting focus from a DOS window, though it sometimes succeeds anyway. When these problems are occurring, the occurrences are sporadic and I see no particular pattern to either the focussed or non-closing behaviours. More mysteries. If anyone knows how to prevent these strangenesses, please let me know. Neither problem seems to occur early after I reboot, and they don't seem to occur when I have only a few tasks running. I suspect there is some resource I need more of, but I don't what it is. If there is a place for setting the defaults for such DOS boxes similar to the settings you can make on a PIF object, I'd like to know about it. Good luck, David V. ------------------------------------------------------------ The following is from "Guy-Armand Kamendje" This short HOW-TO should help you setting up gnuserv with XEmacs 21.4 under win2k. I'am not sure that this will work with other version of XEmacs and/or other operating systems since I have not tested it. If you are successfull with other versions of XEmacs or others Operating systems, please let me know it. 1) grab the gnuserv package of Fabrice Popineau from ftp://ftp.dante.de/pub/fptex/xemacs/ . Only the file gnuclientw.zip is required 2) unzip the file and add the directory in which you have unziped the file to your PATH variable 3) put the following lines in your init file (require 'gnuserv) (gnuserv-start) (setq gnuserv-frame (selected-frame)) 4) When clicking a file in your Windows Explorer, gnuclient can open this file in a XEmacs Frame provided that this file type was previously associated to gnuclient. In order to do this, right click on the file, on the pop-up memu, select properties. On the tab General, select change to change the application this type of file should be opened with in the future. Select Others... to browse to the directory where you have previously unziped the file. Select gnuclient.exe and confirm your choice. That all you have to do Now, when cklicking on files of a type that you have previously assoiciated to gnuclient, these files will be opened in the same XEmacs frame, provided that an XEmacs frame was previously open before you started clicking. By the way, thanks to Fabrice Popineau for the usefull hints. sent any comment to this file to gkamendje@iaik.at