X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/b6bd159922608fa474026837771d63bf7eadcf97..1dba6978b8c3ee884576f5c45884fd3cf7257c60:/lisp/server.el diff --git a/lisp/server.el b/lisp/server.el index 63d46a365c..34ac5d7ba2 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1,6 +1,6 @@ ;;; server.el --- Lisp code for GNU Emacs running as server process -*- lexical-binding: t -*- -;; Copyright (C) 1986-1987, 1992, 1994-2011 Free Software Foundation, Inc. +;; Copyright (C) 1986-1987, 1992, 1994-2012 Free Software Foundation, Inc. ;; Author: William Sommerfeld ;; Maintainer: FSF @@ -126,6 +126,8 @@ port number." (defcustom server-auth-dir (locate-user-emacs-file "server/") "Directory for server authentication files. +We only use this if `server-use-tcp' is non-nil. +Otherwise we use `server-socket-dir'. NOTE: On FAT32 filesystems, directories are not secure; files can be read and modified by any user or process. @@ -307,11 +309,13 @@ Updates `server-clients'." (setq server-clients (delq proc server-clients)) - ;; Delete the client's tty. - (let ((terminal (process-get proc 'terminal))) - ;; Only delete the terminal if it is non-nil. - (when (and terminal (eq (terminal-live-p terminal) t)) - (delete-terminal terminal))) + ;; Delete the client's tty, except on Windows (both GUI and console), + ;; where there's only one terminal and does not make sense to delete it. + (unless (eq system-type 'windows-nt) + (let ((terminal (process-get proc 'terminal))) + ;; Only delete the terminal if it is non-nil. + (when (and terminal (eq (terminal-live-p terminal) t)) + (delete-terminal terminal)))) ;; Delete the client's process. (if (eq (process-status proc) 'open) @@ -395,16 +399,19 @@ If CLIENT is non-nil, add a description of it to the logged message." ;; visible. If not (which can happen if the user's customizations call ;; pop-to-buffer etc.), delete it to avoid preserving the connection after ;; the last real frame is deleted. - (if (and (eq (frame-first-window frame) - (next-window (frame-first-window frame) 'nomini)) - (eq (window-buffer (frame-first-window frame)) - (frame-parameter frame 'server-dummy-buffer))) - ;; The temp frame still only shows one buffer, and that is the - ;; internal temp buffer. - (delete-frame frame) - (set-frame-parameter frame 'visibility t)) - (kill-buffer (frame-parameter frame 'server-dummy-buffer)) - (set-frame-parameter frame 'server-dummy-buffer nil))) + + ;; Rewritten to avoid inadvertently killing the current buffer after + ;; `delete-frame' removed FRAME (Bug#10729). + (let ((buffer (frame-parameter frame 'server-dummy-buffer))) + (if (and (one-window-p 'nomini frame) + (eq (window-buffer (frame-first-window frame)) buffer)) + ;; The temp frame still only shows one buffer, and that is the + ;; internal temp buffer. + (delete-frame frame) + (set-frame-parameter frame 'visibility t) + (set-frame-parameter frame 'server-dummy-buffer nil)) + (when (buffer-live-p buffer) + (kill-buffer buffer))))) (defun server-handle-delete-frame (frame) "Delete the client connection when the emacsclient frame is deleted. @@ -669,9 +676,13 @@ Return values: ;;;###autoload (define-minor-mode server-mode "Toggle Server mode. -With ARG, turn Server mode on if ARG is positive, off otherwise. +With a prefix argument ARG, enable Server mode if ARG is +positive, and disable it otherwise. If called from Lisp, enable +Server mode if ARG is omitted or nil. + Server mode runs a process that accepts commands from the -`emacsclient' program. See `server-start' and Info node `Emacs server'." +`emacsclient' program. See Info node `Emacs server' and +`server-start' for details." :global t :group 'server :version "22.1" @@ -681,7 +692,14 @@ Server mode runs a process that accepts commands from the (defun server-eval-and-print (expr proc) "Eval EXPR and send the result back to client PROC." - (let ((v (eval (car (read-from-string expr))))) + ;; While we're running asynchronously (from a process filter), it is likely + ;; that the emacsclient command was run in response to a user + ;; action, so the user probably knows that Emacs is processing this + ;; emacsclient request, so if we get a C-g it's likely that the user + ;; intended it to interrupt us rather than interrupt whatever Emacs + ;; was doing before it started handling the process filter. + ;; Hence `with-local-quit' (bug#6585). + (let ((v (with-local-quit (eval (car (read-from-string expr)))))) (when proc (with-temp-buffer (let ((standard-output (current-buffer))) @@ -1024,7 +1042,11 @@ The following commands are accepted by the client: (setq tty-name (pop args-left) tty-type (pop args-left) dontkill (or dontkill - (not use-current-frame)))) + (not use-current-frame))) + ;; On Windows, emacsclient always asks for a tty frame. + ;; If running a GUI server, force the frame type to GUI. + (when (eq window-system 'w32) + (push "-window-system" args-left))) ;; -position LINE[:COLUMN]: Set point to the given ;; position in the next file. @@ -1508,7 +1530,14 @@ only these files will be asked to be saved." nil) (defun server-eval-at (server form) - "Eval FORM on Emacs Server SERVER." + "Contact the Emacs server named SERVER and evaluate FORM there. +Returns the result of the evaluation, or signals an error if it +cannot contact the specified server. For example: + \(server-eval-at \"server\" '(emacs-pid)) +returns the process ID of the Emacs instance running \"server\". +This function requires the use of TCP sockets. " + (or server-use-tcp + (error "This function requires TCP sockets")) (let ((auth-file (expand-file-name server server-auth-dir)) (coding-system-for-read 'binary) (coding-system-for-write 'binary)