all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Proposal: emacsclient --readonly
@ 2013-03-14  2:23 michael
  2013-03-14  2:45 ` W. Greenhouse
  2013-03-14  3:31 ` Stefan Monnier
  0 siblings, 2 replies; 13+ messages in thread
From: michael @ 2013-03-14  2:23 UTC (permalink / raw)
  To: emacs-devel

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

As distraction to our toddler temper-tantrum, I'd like to propose a
new feature for emacsclient.

I use emacsclient to open files frequently and I generally immediately
do M-x view-mode once the frame pops up.  I'd like to be able to open
the file directly in view-mode when I invoke emacsclient.

I'd be interested in any suggestions people have on how to accomplish
this using emacsclient currently.  In the absence of any ideas, I'd like
to propose the folowing patch which adds a `--readonly,-r' option to
emacsclient (and server.el) (I had originally called it --view-mode,-v but
getopt_long_only complained that it was ambiguous if abbreviated.)

I'm eager to hear any suggestions people might have to do this without
changing emacsclient.  Or maybe this is a reason to add a more generic
feature to emacsclient to enable/disable modes after a file is opened.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: emacsclient --readonly feature --]
[-- Type: text/x-diff, Size: 6848 bytes --]

*** trunk/lib-src/emacsclient.c	2013-03-13 19:48:00.017919000 -0400
--- my-work/lib-src/emacsclient.c	2013-03-13 19:48:16.237220000 -0400
***************
*** 129,134 ****
--- 129,137 ----
  /* Nonzero means don't wait for a response from Emacs.  --no-wait.  */
  int nowait = 0;
  
+ /* Nonzero means file should be readonly and placed in view-mode.  --readonly.  */
+ int readonly = 0;
+ 
  /* Nonzero means don't print messages for successful operations.  --quiet. */
  int quiet = 0;
  
***************
*** 173,178 ****
--- 176,182 ----
  struct option longopts[] =
  {
    { "no-wait",	no_argument,	   NULL, 'n' },
+   { "readonly",	no_argument,	   NULL, 'r' },
    { "quiet",	no_argument,	   NULL, 'q' },
    { "eval",	no_argument,	   NULL, 'e' },
    { "help",	no_argument,	   NULL, 'H' },
***************
*** 519,524 ****
--- 523,532 ----
  	  nowait = 1;
  	  break;
  
+ 	case 'r':
+ 	  readonly = 1;
+ 	  break;
+ 
  	case 'e':
  	  eval = 1;
  	  break;
***************
*** 644,649 ****
--- 652,658 ----
  			Set the parameters of a new frame\n\
  -e, --eval    		Evaluate the FILE arguments as ELisp expressions\n\
  -n, --no-wait		Don't wait for the server to return\n\
+ -r, --readonly		Make the buffer readonly and enable view-mode\n\
  -q, --quiet		Don't display messages on success\n\
  -d DISPLAY, --display=DISPLAY\n\
  			Visit the file in the given display\n\
***************
*** 1604,1609 ****
--- 1613,1621 ----
    if (nowait)
      send_to_emacs (emacs_socket, "-nowait ");
  
+   if (readonly)
+     send_to_emacs (emacs_socket, "-readonly ");
+ 
    if (current_frame)
      send_to_emacs (emacs_socket, "-current-frame ");
  
*** trunk/lisp/server.el	2013-03-02 22:36:33.309144000 -0500
--- my-work/lisp/server.el	2013-03-06 23:58:19.157146157 -0500
***************
*** 1050,1055 ****
--- 1050,1056 ----
  				    (or file-name-coding-system
  					default-file-name-coding-system)))
  		nowait     ; t if emacsclient does not want to wait for us.
+                 readonly   ; t to view files in read-only/view-mode
  		frame      ; Frame opened for the client (if any).
  		display    ; Open frame on this display.
  		parent-id  ; Window ID for XEmbed
***************
*** 1075,1080 ****
--- 1076,1084 ----
                  ;; -nowait:  Emacsclient won't wait for a result.
                  (`"-nowait" (setq nowait t))
  
+                 ;; -readonly:  place files in view-mode
+                 (`"-readonly" (setq readonly t))
+ 
                  ;; -current-frame:  Don't create frames.
                  (`"-current-frame" (setq use-current-frame t))
  
***************
*** 1233,1239 ****
                   (let ((default-directory
                           (if (and dir (file-directory-p dir))
                               dir default-directory)))
!                    (server-execute proc files nowait commands
                                     dontkill frame tty-name)))))
  
              (when (or frame files)
--- 1237,1243 ----
                   (let ((default-directory
                           (if (and dir (file-directory-p dir))
                               dir default-directory)))
!                    (server-execute proc files nowait readonly commands
                                     dontkill frame tty-name)))))
  
              (when (or frame files)
***************
*** 1243,1249 ****
      ;; condition-case
      (error (server-return-error proc err))))
  
! (defun server-execute (proc files nowait commands dontkill frame tty-name)
    ;; This is run from timers and process-filters, i.e. "asynchronously".
    ;; But w.r.t the user, this is not really asynchronous since the timer
    ;; is run after 0s and the process-filter is run in response to the
--- 1247,1253 ----
      ;; condition-case
      (error (server-return-error proc err))))
  
! (defun server-execute (proc files nowait readonly commands dontkill frame tty-name)
    ;; This is run from timers and process-filters, i.e. "asynchronously".
    ;; But w.r.t the user, this is not really asynchronous since the timer
    ;; is run after 0s and the process-filter is run in response to the
***************
*** 1253,1259 ****
    ;; including code that needs to wait.
    (with-local-quit
      (condition-case err
!         (let ((buffers (server-visit-files files proc nowait)))
            (mapc 'funcall (nreverse commands))
  
  	  ;; If we were told only to open a new client, obey
--- 1257,1263 ----
    ;; including code that needs to wait.
    (with-local-quit
      (condition-case err
!         (let ((buffers (server-visit-files files proc nowait readonly)))
            (mapc 'funcall (nreverse commands))
  
  	  ;; If we were told only to open a new client, obey
***************
*** 1319,1331 ****
        (when (> column-number 0)
          (move-to-column (1- column-number))))))
  
! (defun server-visit-files (files proc &optional nowait)
    "Find FILES and return a list of buffers created.
  FILES is an alist whose elements are (FILENAME . FILEPOS)
  where FILEPOS can be nil or a pair (LINENUMBER . COLUMNNUMBER).
  PROC is the client that requested this operation.
  NOWAIT non-nil means this client is not waiting for the results,
! so don't mark these buffers specially, just visit them normally."
    ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
    (let ((last-nonmenu-event t) client-record)
      ;; Restore the current buffer afterward, but not using save-excursion,
--- 1323,1337 ----
        (when (> column-number 0)
          (move-to-column (1- column-number))))))
  
! (defun server-visit-files (files proc &optional nowait readonly)
    "Find FILES and return a list of buffers created.
  FILES is an alist whose elements are (FILENAME . FILEPOS)
  where FILEPOS can be nil or a pair (LINENUMBER . COLUMNNUMBER).
  PROC is the client that requested this operation.
  NOWAIT non-nil means this client is not waiting for the results,
! so don't mark these buffers specially, just visit them normally.
! READONLY non-nil means place the file in `view-mode'; quiting
! the file will kill the buffer."
    ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
    (let ((last-nonmenu-event t) client-record)
      ;; Restore the current buffer afterward, but not using save-excursion,
***************
*** 1363,1368 ****
--- 1369,1379 ----
            (run-hooks 'server-visit-hook)
  	  ;; hooks may be specific to current buffer:
  	  (run-hooks 'post-command-hook))
+         (when readonly
+           ;; enable view mode and view-quit will mark the buffer as done
+           (view-mode +1)
+           (unless nowait
+             (setq view-exit-action 'server-buffer-done)))
  	(unless nowait
  	  ;; When the buffer is killed, inform the clients.
  	  (add-hook 'kill-buffer-hook 'server-kill-buffer nil t)

[-- Attachment #3: Type: text/plain, Size: 71 bytes --]


--
Michael R. Mauger  -  FSF Member #4247  -  Emacs sql.el Maintainer

^ permalink raw reply	[flat|nested] 13+ messages in thread
[parent not found: <87zjxtq304.fsf@michael-laptop.hsd1.ma.comcast.net>]
* Re: Proposal: emacsclient --readonly
@ 2013-09-27 18:22 Rüdiger Sonderfeld
  0 siblings, 0 replies; 13+ messages in thread
From: Rüdiger Sonderfeld @ 2013-09-27 18:22 UTC (permalink / raw)
  To: monnier; +Cc: emacs-devel

Hello,
what happened to this patch?  It would be very useful to me right now.

There should probably be a way to add functions to `commands' (in server-
process-filter) though.  With this patch it could be done by adding an "--
eval" statement to the args.  But there should probably be a clean way.

I'm currently attempting to write an info(1) like program which loads the info 
page in the running Emacs session.  I need this to support the "doc" comment 
in `inferior-octave'.  With this patch it could be done without a lot of 
hacks.

Regards,
Rüdiger

> === modified file 'lisp/server.el'
> --- lisp/server.el      2013-02-13 04:31:09 +0000
> +++ lisp/server.el      2013-03-25 13:07:44 +0000
> @@ -909,6 +909,12 @@
> 
>      (process-put proc 'continuation nil)
>      (if continuation (ignore-errors (funcall continuation)))))
> 
> +(defvar server-custom-option-function #'identity
> +  "Function to process additional emacsclient arguments.
> +The function is called with a single argument (a list of args received
> +from emacsclient) and returns the list of args left to process.
> +The easiest way to modify this variable is through `add-function'.")
> +
> 
>  (cl-defun server-process-filter (proc string)
>  
>    "Process a request from the server to edit some files.
>  
>  PROC is the server process.  STRING consists of a sequence of
> 
> @@ -1067,7 +1076,8 @@
> 
>             (setq string (substring string (match-end 0)))
>             (setq args-left
>             
>                   (mapcar 'server-unquote-arg (split-string request " " t)))
> 
> -           (while args-left
> +           (while (setq arg-left (funcall server-custom-option-function
> +                                           args-left))
> 
>                (pcase (pop args-left)
>                
>                  ;; -version CLIENT-VERSION: obsolete at birth.
>                  (`"-version" (pop args-left))



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-09-27 18:22 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-14  2:23 Proposal: emacsclient --readonly michael
2013-03-14  2:45 ` W. Greenhouse
2013-03-14  3:31 ` Stefan Monnier
2013-03-24  3:45   ` Michael Mauger
     [not found] <87zjxtq304.fsf@michael-laptop.hsd1.ma.comcast.net>
     [not found] ` <jwv38vlpnpl.fsf-monnier+emacs@gnu.org>
2013-03-24 16:22   ` Michael Mauger
2013-03-25 13:15     ` Stefan Monnier
2013-03-26  2:56       ` Michael Mauger
2013-03-26 13:10         ` Stefan Monnier
2013-03-27  2:02           ` Michael Mauger
2013-03-27  2:33             ` Stefan Monnier
2013-03-27 13:47               ` Michael Mauger
2013-03-30 23:03                 ` Michael Mauger
  -- strict thread matches above, loose matches on Subject: below --
2013-09-27 18:22 Rüdiger Sonderfeld

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.