Created
October 5, 2010 23:32
-
-
Save anonymous/612541 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; | |
;I added the component: | |
; (inferior-ess-search-list-command . "search()\n") | |
;to S+3-customize-alist and R-customize-alist, and then I redefined the | |
;ess-create-temp-buffer function as follows: | |
(defun ess-create-temp-buffer (name) | |
"Create an empty buffer called NAME." | |
(let ((buff (get-buffer-create name)) | |
(elca (eval ess-local-customize-alist))) | |
(save-excursion | |
(set-buffer buff) | |
(erase-buffer) | |
(ess-setq-vars-local elca buff)) | |
buff)) | |
;;These two steps seem to insure that the temporary buffer in which the | |
;;search results appear has the correct version of the local variables. | |
;;I am not that well acquainted with the ess code and don't know whether | |
;;this is a good fundamental way of fixing the problem, or even whether | |
;;or not this breaks some other feature of ess-mode that I never use. | |
;;Thanks for listening. | |
;;Ed K. | |
;;-- | |
;;Ed Kademan 508.651.3700 | |
;;PHZ Capital Partners 508.653.1745 (fax) | |
;;321 Commonwealth Road <kademan@phz.com> | |
;;Wayland, MA 01778 | |
(defun ess-display-temp-buffer (buff) | |
"Display the buffer BUFF using `temp-buffer-show-function' and respecting | |
`ess-display-buffer-reuse-frames'." | |
(let ((display-buffer-reuse-frames ess-display-buffer-reuse-frames)) | |
(funcall (or temp-buffer-show-function 'display-buffer) buff))) | |
;;*;; Error messages | |
(defun ess-error (msg) | |
"Something bad has happened. | |
Display the S buffer, and cause an error displaying MSG." | |
(display-buffer (process-buffer (get-ess-process ess-current-process-name))) | |
(error msg)) | |
; Provide package | |
(provide 'ess-inf) | |
; Local variables section | |
;;; This file is automatically placed in Outline minor mode. | |
;;; The file is structured as follows: | |
;;; Chapters: ^L ; | |
;;; Sections: ;;*;; | |
;;; Subsections: ;;;*;;; | |
;;; Components: defuns, defvars, defconsts | |
;;; Random code beginning with a ;;;;* comment | |
;;; Local variables: | |
;;; mode: emacs-lisp | |
;;; outline-minor-mode: nil | |
;;; mode: outline-minor | |
;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*" | |
;;; End: | |
;;; ess-inf.el ends here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; linefeeder.el --- send input to subprocesses in a comint buffer line by line | |
;; Copyright (C) 2010 Lars Schmidt-Thieme <schmidt-thieme@ismll.de> | |
;; This file is free software; you can redistribute it and/or modify | |
;; it under the terms of the GNU General Public License as published by | |
;; the Free Software Foundation; either version 2, or (at your option) | |
;; any later version. | |
;; This file is distributed in the hope that it will be useful, | |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
;; GNU General Public License for more details. | |
;; You should have received a copy of the GNU General Public License | |
;; along with GNU Emacs; see the file COPYING. If not, write to | |
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
;;; Commentary: | |
;; Provides an extension to comint mode that sends input to the process | |
;; line by line (instead of everything at once). This has two benefits: | |
;; 1. output is immediately below the corresponding input in the | |
;; comint buffer, | |
;; 2. the process can be interrupted by calling `comint-interrupt-subjob' | |
;; even if there is a lot of input still pending. | |
;; | |
;; Enable by call `linefeeder-enable' in the comint buffer. | |
;; To send some input to the process from outside the comint buffer, | |
;; call `linefeeder-send-string' (with the comint buffer as the current | |
;; buffer). | |
;; | |
;; Linefeeder requires that the program running in the process issues | |
;; prompts after each line of input, as e.g., done by R. | |
;;; Code: | |
(require 'comint) | |
(defvar linefeeder-pending-input-buffer nil | |
" Buffer containing the pending input.") | |
(defvar linefeeder-still-processing-input nil | |
" t if linefeeder still is processing input, i.e., | |
if there is no new prompt since sending last line.") | |
(defvar linefeeder-stored-incomplete-input | |
" Contains incomplete input by the user before sending linewise input started.") | |
(defun linefeeder-enable () (interactive) | |
" Setup comint mode to send input to the process line by line." | |
;; a. make variables local | |
(make-local-variable 'linefeeder-pending-input-buffer) | |
(make-local-variable 'linefeeder-still-processing-input) | |
(make-local-variable 'linefeeder-stored-incomplete-input) | |
(make-local-variable 'comint-pre-interrupt-hooks) | |
(make-local-variable 'comint-post-interrupt-hooks) | |
;; b. setup local variables: output filter loop. | |
(setq linefeeder-pending-input-buffer (generate-new-buffer (generate-new-buffer-name "*pending output*"))) | |
(setq linefeeder-still-processing-input nil) | |
(setq linefeeder-stored-incomplete-input nil) | |
(add-hook 'comint-output-filter-functions 'linefeeder-prompt-detector) | |
;; c. setup hooks for comint-interrupt-subjob | |
(add-hook 'comint-pre-interrupt-hooks 'linefeeder-delete-pending-input) | |
(add-hook 'comint-post-interrupt-hooks 'linefeeder-next-line) | |
) | |
(defun linefeeder-send-string (string) | |
" Send a string to the input of the process (line by line)" | |
;; a. store all unsent user input | |
(setq linefeeder-stored-incomplete-input | |
(delete-and-extract-region | |
(or (marker-position comint-accum-marker) | |
(process-mark (get-buffer-process (current-buffer)))) | |
(point-max))) | |
;; b. append string to pending input buffer | |
(with-current-buffer linefeeder-pending-input-buffer | |
(insert string)) | |
;; c. and start to process pending input | |
(linefeeder-evtl-send-next-input-line)) | |
;; evtl. send next line of input | |
(defun linefeeder-evtl-send-next-input-line () | |
;; if the process is not already processing input and if there is still pending input | |
(if (not linefeeder-still-processing-input) | |
(if (> (buffer-size linefeeder-pending-input-buffer) 0) | |
(progn | |
;; a. let everybody know that the process will process input shortly | |
(setq linefeeder-still-processing-input t) | |
;; b. get next line from pending input: | |
(with-current-buffer linefeeder-pending-input-buffer | |
(goto-char (point-min)) | |
(move-end-of-line 1) | |
(setq line (delete-and-extract-region 1 (point))) | |
(if (< (point) (point-max)) | |
(delete-char 1)) | |
) | |
;; c. insert next input line into process buffer and send it | |
;; (comint-send-string sprocess line) | |
(comint-goto-process-mark) | |
(insert line) | |
(comint-send-input) | |
) | |
;; in the end: evtl. restore initially removed unsent user input. | |
(if (> (length linefeeder-stored-incomplete-input) 0) | |
(progn | |
(goto-char (process-mark (get-buffer-process (current-buffer)))) | |
(insert linefeeder-stored-incomplete-input) | |
(setq linefeeder-stored-incomplete-input nil))) | |
))) | |
(defun linefeeder-delete-pending-input () (interactive) | |
" Delete all pending input." | |
(with-current-buffer linefeeder-pending-input-buffer | |
(erase-buffer))) | |
;; signal that a line of input has been processed and goto next line." | |
(defun linefeeder-next-line () | |
(setq linefeeder-still-processing-input nil) | |
(linefeeder-evtl-send-next-input-line) | |
) | |
;; output filter that detects prompts: | |
(defun linefeeder-prompt-detector (string) | |
(if (string-match comint-prompt-regexp string) | |
(linefeeder-next-line) | |
)) | |
(defun linefeeder-interrupt-subjob () (interactive) | |
" Interrupt process and discard all pending input." | |
(linefeeder-delete-pending-input) | |
(comint-interrupt-subjob) | |
(linefeeder-next-line) | |
) | |
;; ---------------------------------------------------------------------- | |
;; added a hook to comint-interrupt-subjob | |
(defvar comint-pre-interrupt-hooks nil | |
"Functions to call before subjob is interrupted. | |
These functions get no arguments. | |
You can use `add-hook' to add functions to this list | |
either globally or locally.") | |
(defvar comint-post-interrupt-hooks nil | |
"Functions to call after subjob has been interrupted. | |
These functions get no arguments. | |
You can use `add-hook' to add functions to this list | |
either globally or locally.") | |
(defun comint-interrupt-subjob () | |
"Interrupt the current subjob. | |
This command also kills the pending input | |
between the process mark and point. | |
It runs `comint-pre-interrupt-hooks' before the interruption and | |
`comint-post-interrupt-hooks' after the interruption." | |
(interactive) | |
(comint-skip-input) | |
(run-hook-with-args 'comint-pre-interrupt-hooks) | |
(interrupt-process nil comint-ptyp) | |
(run-hook-with-args 'comint-post-interrupt-hooks) | |
;; (process-send-string nil "\n") | |
) | |
(provide 'linefeeder) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment