I am currently dealing with a problem, where I have to read a zipped file line by line, and further on process each line and do something with it.
I managed to read from stdin using the following code:
(defun process ()
(princ (split-sequence:split-sequence #\Space (read-line))))
(defun main (args)
(process))
*this will be a command line tool
Where I ran it as:
cat file.txt | ./executable
this works fine, but it prints only the first line. I assume I must insert some form of loop in the first part, yet I am not sure how this is to be done.
Thank you for any help!
I solved this using:
(loop for line = (read-line) ; stream, no error, :eof value
until (eq line :eof)
do (princ line))
Related
I've got the following problem in my Emacs (i am a complete newby and way far from LISP programming): When i open a .R file, no ESS process is starting. This is a problem because i want to configure TAB-completion and see R Documentation in scripts.
This is the Error message:"No ESS process associated with current buffer
"
This is only the case in .R files. When starting inferior ESS i dont have this problem. (hope i got this right: M-x R starts a process und Emacs and is therefore called inferior?)
My .emacs is cofigured like this:
(require 'auto-complete)
(require 'auto-complete-config)
(require 'ess-stata-mode)
(require 'ess-eldoc)
(add-hook 'inferior-ess-mode-hook 'ess-use-eldoc)
(autoload 'R-mode "ess-site.el" "" t)
(add-to-list 'auto-mode-alist '("\\.R\\'" . R-mode))
Those two lines above should start ESS in script, shouldn't they?
(global-auto-complete-mode t)
(setq ess-tab-complete-in-script t)
(setq ess-use-auto-complete 't)
(setq ess-use-eldoc 't)
(setq ess-use-company 't)
And I included ElDoc and AC to get Autocompletion.
I want to get to see the Documentation of R in Emacs.
I'd really appreciate your help. What did I miss?
Greetings and Thanks in advance
I want to have the ability to execute statements on R's REPL with the option to pipe it to a buffer so I can quickly refer back to it later.
To run a shell command and output to *shell command buffer* I can use M-! as per this question. What would the equivalent be for R's REPL without resorting to write.csv()?
You can use ess-command from ess-inf to redirect the output to another buffer. An example could look like the following,
(defun redirect-ess-output (command &optional buffer process)
(interactive (list (read-from-minibuffer "Command: ")))
(let ((buff (get-buffer-create (or buffer "*r-output*")))
;; 'ess-get-process' defaults to process local to current
;; buffer, so to call from anywhere default to "R"
(proc (ess-get-process (or process "R"))))
;; send a trailing newline to process
(unless (string-match-p "\n$" command)
(setq command (concat command "\n")))
(ess-command command buff 'sleep nil nil proc)
(with-current-buffer buff
;; process stuff
(pop-to-buffer buff))))
When using ESS[R] in inferior mode I can retrieve the most recent command output using C-c C-p which moves the cursor to the previous command output. Alternatively I can use C-up which essentially copies the most recently entered command from the inferior process (similar to how readline works). I prefer the C-up approach but unfortunately it does not retrieve commands that were entered from a script using any of the ess-eval commads. Is there to get the functionality of C-up for commands entered in both inferior mode and by ess-eval?
Your solution works fine for single line commands, but needs a small tweak to handle multi-line statements:
(defun ess-readline ()
"Move to previous command entered from script *or* R-process and copy
to prompt for execution or editing"
(interactive)
;; See how many times function was called
(if (eq last-command 'ess-readline)
(setq ess-readline-count (1+ ess-readline-count))
(setq ess-readline-count 1))
;; Move to prompt and delete current input
(comint-goto-process-mark)
(end-of-buffer nil) ;; tweak here
(comint-kill-input)
;; Copy n'th command in history where n = ess-readline-count
(comint-previous-prompt ess-readline-count)
(comint-copy-old-input)
;; Below is needed to update counter for sequential calls
(setq this-command 'ess-readline)
)
(global-set-key (kbd "\C-cp") 'ess-readline)
This enables you to move up through the previous commands; the following function enables you to move back down again, so you can go up and down to find the command you're after:
(defun ess-readnextline ()
"Move to next command after the one currently copied to prompt and copy
to prompt for execution or editing"
(interactive)
;; Move to prompt and delete current input
(comint-goto-process-mark)
(end-of-buffer nil)
(comint-kill-input)
;; Copy (n - 1)'th command in history where n = ess-readline-count
(setq ess-readline-count (max 0 (1- ess-readline-count)))
(when (> ess-readline-count 0)
(comint-previous-prompt ess-readline-count)
(comint-copy-old-input))
;; Update counter for sequential calls
(setq this-command 'ess-readline)
)
(global-set-key (kbd "\C-cn") 'ess-readnextline)
It doesn't seem that there is any built in function to do this so I wrote the function below. Essentially this function automates the process of using the keystokes C-c C-p to move the cursor to a previous command in the R-process buffer followed by C-c RET to copy that command to the prompt for editing
(defun ess-readline ()
"Move to previous command entered from script *or* R-process and copy
to prompt for execution or editing"
(interactive)
;; See how many times function was called
(if (eq last-command 'ess-readline)
(setq ess-readline-count (1+ ess-readline-count))
(setq ess-readline-count 1))
;; Move to end of buffer and delete current input
(end-of-buffer nil)
(comint-kill-input)
;; Copy n'th command in history where n = ess-readline-count
(comint-previous-prompt ess-readline-count)
(comint-copy-old-input)
;; Below is needed to update counter for sequential calls
(setq this-command 'ess-readline)
)
(global-set-key (kbd "\C-cp") 'ess-readline)
Common Lisp's multiline comments make it easier to include multiline shebangs:
#!/bin/bash
#|
exec clisp -q -q $0 $0 ${1+"$#"}
exit
|#
;;; Usage: ./scriptname.lisp
(defun main (args)
(let ((program (car args)))
(format t "Program: ~a~%" program)
(quit)))
Without this syntax, only very simple shebangs can be used. Is there a pound-based multiline comment for Smalltalk that would facilitate multiline shebangs?
It doesn't NEED to be multi-line; as long as bash can see "into" the Smalltalk comment, you should be okay. I'd be more worried about Smalltalk seeing past the #!
How about something based on:
"exec" "/usr/bin/gst" "--foo" "$0" "--bar" "$#"
There's no need for exit unless you expect the exec ever to fail. Make sure your Smalltalk is where you expect it to be! If you do want the safety valve:
"exec" ...
"exit"
Having to double-quote arguments can get in the way, of course. Double-quoting shell operators breaks their specialness, for example.
"echo" "hello" ">" "/dev/null"
just prints "hello > /dev/null"
Right now, I have F5 set to start gdb in emacs for me:
(global-set-key [f5] 'gdb)
This switches to the mini-buffer, which I then type a path to an executable... I'd like to find a way to bypass this path typing...
I wrote an executable that looks at the Makefile, parses it and figures out the full path of the executable and prints it to standard out... Is it possible to call this from my .emacs... And then somehow pass the output to the gdb command?
(defun gdb-getpath ()
"Figures out the path to executable and launches gdb."
(interactive)
(let ((path (shell-command-to-string "/path/to/your/executable")))
(gdb (concat "gdb " path))
))
(global-set-key [f5] 'gdb-getpath)