resume.el 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. ;;; resume.el --- process command line args from within a suspended Emacs job
  2. ;; Copyright (C) 1992, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: Joe Wells <jbw@bucsf.bu.edu>
  4. ;; Adapted-By: ESR
  5. ;; Keywords: processes
  6. ;; Obsolete-since: 23.1
  7. ;; This file is part of GNU Emacs.
  8. ;; GNU Emacs is free software: you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation, either version 3 of the License, or
  11. ;; (at your option) any later version.
  12. ;; GNU Emacs is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;; GNU General Public License for more details.
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  18. ;;; Commentary:
  19. ;; The purpose of this library is to handle command line arguments
  20. ;; when you resume an existing Emacs job.
  21. ;; In order to use it, you must put this code in your .emacs file.
  22. ;; (add-hook 'suspend-hook 'resume-suspend-hook)
  23. ;; (add-hook 'suspend-resume-hook 'resume-process-args)
  24. ;; You can't get the benefit of this library by using the `emacs' command,
  25. ;; since that always starts a new Emacs job. Instead you must use a
  26. ;; command called `edit' which knows how to resume an existing Emacs job
  27. ;; if you have one, or start a new Emacs job if you don't have one.
  28. ;; To define the `edit' command, run the script etc/emacs.csh (if you use CSH),
  29. ;; or etc/emacs.bash if you use BASH. You would normally do this in your
  30. ;; login script.
  31. ;; Stephan Gildea suggested bug fix (gildea@bbn.com).
  32. ;; Ideas from Michael DeCorte and other people.
  33. ;;; Code:
  34. (defvar resume-emacs-args-file (expand-file-name "~/.emacs_args")
  35. "This file is where arguments are placed for a suspended Emacs job.")
  36. (defvar resume-emacs-args-buffer " *Command Line Args*"
  37. "Buffer that is used by `resume-process-args'.")
  38. (defun resume-process-args ()
  39. "Handler for command line args given when Emacs is resumed."
  40. (let ((start-buffer (current-buffer))
  41. (args-buffer (get-buffer-create resume-emacs-args-buffer))
  42. length args
  43. (command-line-default-directory default-directory))
  44. (unwind-protect
  45. (progn
  46. (set-buffer args-buffer)
  47. (erase-buffer)
  48. ;; get the contents of resume-emacs-args-file
  49. (condition-case ()
  50. (let ((result (insert-file-contents resume-emacs-args-file)))
  51. (setq length (car (cdr result))))
  52. ;; the file doesn't exist, ergo no arguments
  53. (file-error
  54. (erase-buffer)
  55. (setq length 0)))
  56. (if (<= length 0)
  57. (setq args nil)
  58. ;; get the arguments from the buffer
  59. (goto-char (point-min))
  60. (while (not (eobp))
  61. (skip-chars-forward " \t\n")
  62. (let ((begin (point)))
  63. (skip-chars-forward "^ \t\n")
  64. (setq args (cons (buffer-substring begin (point)) args)))
  65. (skip-chars-forward " \t\n"))
  66. ;; arguments are now in reverse order
  67. (setq args (nreverse args))
  68. ;; make sure they're not read again
  69. (erase-buffer))
  70. (resume-write-buffer-to-file (current-buffer) resume-emacs-args-file)
  71. ;; if nothing was in buffer, args will be null
  72. (or (null args)
  73. (setq command-line-default-directory
  74. (file-name-as-directory (car args))
  75. args (cdr args)))
  76. ;; actually process the arguments
  77. (command-line-1 args))
  78. ;; If the command line args don't result in a find-file, the
  79. ;; buffer will be left in args-buffer. So we change back to the
  80. ;; original buffer. The reason I don't just use
  81. ;; (let ((default-directory foo))
  82. ;; (command-line-1 args))
  83. ;; in the context of the original buffer is because let does not
  84. ;; work properly with buffer-local variables.
  85. (if (eq (current-buffer) args-buffer)
  86. (set-buffer start-buffer)))))
  87. ;;;###autoload
  88. (defun resume-suspend-hook ()
  89. "Clear out the file used for transmitting args when Emacs resumes."
  90. (with-current-buffer (get-buffer-create resume-emacs-args-buffer)
  91. (erase-buffer)
  92. (resume-write-buffer-to-file (current-buffer) resume-emacs-args-file)))
  93. (defun resume-write-buffer-to-file (buffer file)
  94. "Writes the contents of BUFFER into FILE, if permissions allow."
  95. (if (not (file-writable-p file))
  96. (error "No permission to write file %s" file))
  97. (with-current-buffer buffer
  98. (clear-visited-file-modtime)
  99. (save-restriction
  100. (widen)
  101. (write-region (point-min) (point-max) file nil 'quiet))
  102. (set-buffer-modified-p nil)))
  103. (provide 'resume)
  104. ;;; resume.el ends here