I'm experimenting with script-fu, trying to teach myself how to use it. I have the following basic script, which I thought would create, then display, a new image:
(define (script-fu-test)
(let*
(
(image (car (gimp-image-new 10 10 RGB)))
)
(gimp-display-new image)
(gimp-context-pop)
)
)
I'm calling the script like so:
./gimp-2.8 -i -b '(script-fu-test)'
and it's failing, like so:
batch command experienced an execution error:
Error: ( : 32662) Procedure execution of gimp-display-new failed
anyone have a hint about what i might be messing up here?
I'm running this on a Mac OS X (ie /Applications/Gimp.app/Contents/MacOS/gimp-2.8)
When I try to use a simplified version of your code, I get the following results:
$ gimp -b '(gimp-display-new (car (gimp-image-new 10 10 RGB)))'
batch command executed successfully
$ gimp -i -b '(gimp-display-new (car (gimp-image-new 10 10 RGB)))'
batch command experienced an execution error
Note that in the first case there's no -i, so the user interface is a available. In the second case, there's a -i, so there's no user interface. You can't use gimp-display-new without an interface. That you can't use gimp-display-new in no-interface mode is also mentioned in:
RE: Script can't connect to Perl Server on the gimp-perl mailing list
Make sure you start up gimp in batch mode with this line:
gimp --no-interface --batch '(extension-perl-server 1 0 0)' &
But it also means you can't do gimp-display-new, which is extremely
useful for debugging. I use interactive gimp when writing new image
generation code, and then --no-interface during production.
The "Linux LaTeX-PDF HOW-TO" by Udo Schuermann, which says:
Note, the "1" as the first argument in the commands refers to the fact that this script is to run in non-interactive mode. I've commented out the (gimp-display-new img) command; if you ran this in interactive mode it would not just prompt you for various parameters but would also produce an image window to show you the result. But we definitely do not want to bother with visible stuff and interactive operations in this project. Onwards we go:"
Related
I'm trying to make my first steps with Gimp batch processing, but I'm stuck at the very beginning. I'm getting this error:
z80crews-iMac:~ z80crew$ /Applications/GIMP-2.10.app/Contents/MacOS/gimp -i -b '(do-it "france.png" "spain.png")' -b '(gimp-quit 0)'
batch command experienced an execution error:
Error: eval: unbound variable: do-it
do-it is the name of my function to execute. This function is defined in a file that's stored in ~/.gimp-2.10/scripts.
z80crews-iMac:~ z80crew$ cat ~/.gimp-2.10/scripts/gimp-combine-images.scm
(define (do-it fname-one fname-two)
)
z80crews-iMac:~ z80crew$ /Applications/GIMP-2.10.app/Contents/MacOS/gimp -v
GNU Image Manipulation Program Version 2.10.12
Additional info: Defining do-it right on the command line works:
z80crews-iMac:~ z80crew$ /Applications/GIMP-2.10.app/Contents/MacOS/gimp -i -b '((define (do-it fname-one fname-two)) (do-it "france.bigcities.png" "france.cities.png")' -b '(gimp-quit 0)'
batch command executed successfully
Other things I tried:
I tried to pass the script as an argument to gimp.
I opened the Gimp application and stored my script fu script in the directories that are shown in Preferences > Folders > Scripts.
I'm obviously missing something easy, but I can't find out what it is.
It seems this is the way to go:
I opened the Gimp application and stored my script fu script in the directories that are shown in Preferences > Folders > Scripts.
This time I launched and closed GIMP (the application with the GUI) after having put my script in /Users/USERNAME/Application Support/GIMP/2.10/scripts. This was the first path that GIMP lists in Preferences > Folders > Scripts.
To start my Emacs Lisp script from shell, I use this command:
emacs --script my-script.el -f my-function
In my script I save 3 buffers to 3 files.
And it's working OK. But when script is running on the shell it prints the text:
Using vacuous schema
Saving file "some-file-to-save"
Wrote "some-file-to-save"
This text prints 3 times. How I can suppress this text?
I don't know offhand how to fix it "properly" in ELisp, but an easy solution would be to just discard output:
emacs --script my-script.el -f my-function > /dev/null
This tells the shell to send all of stdout to /dev/null (which discards all data written to it). Obviously this requires a) an operating system that has /dev/null (i.e. most Unices, including macOS) and b) a shell that doesn't suck (i.e. not cmd.exe).
Identify the function calls that dumps these messages in your script.
Assuming that the first message comes from the function save-buffer which calls the function message (files.el), just override the behavior of message by replacing, in your script, the invocation of save-buffer (or whoever is called) by:
(cl-letf (((symbol-function 'message) #'ignore))
(save-buffer))
Your need to add
(require 'cl-lib)
on top of your script if not already there.
I'm running the output of an application in an emacs buffer using shell-command.
(shell-command "verbose-app &" "*verbose-app*")
The problem is this command is extremely verbose. So much so, that it sometimes takes several seconds for the emacs buffer to catch up. It lags by several seconds with the actual output.
Is there any way I can speed up the output scrolling by disabling something? Like regex-matching or syntax highlighting?
For future reference:
The verbose app is adb logcat. I changed my existing function:
(defun adb-logcat ()
(interactive)
(shell-command "adb logcat -v threadtime&" "*adb-logcat*")
(pop-to-buffer "*adb-logcat*")
(buffer-disable-undo))
To the following:
(defun adb-logcat ()
(interactive)
(start-process "*adb-logcat*" "*adb-logcat*" "/bin/sh" "-c" "adb logcat -v threadtime")
(pop-to-buffer "*adb-logcat*")
(buffer-disable-undo))
It scrolls way faster now. Yay!
Like the documentation says, shell-command runs the command in an inferior shell, implying shell-mode. If you just want the output and none of the features, running the command with start-process may be closer to what you want.
(start-process "*verbose-app*" "*verbose-app*"
"/bin/sh" "-c" "verbose-app")
Wrapping this into a function should not be too hard. You might want to look at how shell-command implements async commands; for example, it will ask whether it should terminate an existing process if you attempt to create one when another already exists. http://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/simple.el#n2447 might be a good starting point. (In case the link goes bad, this is a link to inside defun shell-command, pointing to a a comment about handling the ampersand. If it's there, the command will be run asynchronously.)
If the command is that verbose, is there any use in capturing the full output in real time? Maybe you could run verbose-app > app.log in the background and then run something like while true; do tail -n50 app.log; sleep 1; done within emacs to keep updating the buffer to view the last few lines of the log file. Later when you want the full output you can open the log file in emacs.
Emacs obviously can handle multiple asynchronous sub-processes, otherwise a multi-language programming environment like org-babel, to give an example, wouldn't be possible.
However, when I'm in Dired and start an asynchronous shell command to view a pdf file (& evince), and then try to do the same on a second pdf file, I get the following message:
"A command is running - kill it? Yes or No?"
Is there a way to run several asynchronous shell commands in parallel, when in Dired?
When you use dired-do-async-shell-command Emacs create a *Async Shell Command* buffer. If you want another async command you need to rename this buffer, for example using M-x rename-uniquely
you could try to change the comportment of dired-do-async-shell-command by advising it:
(defadvice shell-command (after shell-in-new-buffer (command &optional output-buffer error-buffer))
(when (get-buffer "*Async Shell Command*")
(with-current-buffer "*Async Shell Command*"
(rename-uniquely))))
(ad-activate 'shell-command)
note that I really advice the shell-command Emacs command because it's called by dired.
I don't think it's possible with dired-do-async-shell-command, but if you just want to open some file is certain external application I suggest using OpenWith, which allows any number of external processes running.
I've just setup the following which erases the current definition of dired-run-shell-command to pass a dedicated buffer name to shell-command:
(defun dired-run-shell-command (command)
(let ((handler
(find-file-name-handler (directory-file-name default-directory)
'shell-command)))
(if handler (apply handler 'shell-command (list command))
(shell-command command
(generate-new-buffer-name
(concat "*Shell Command Output: '" command "'*")))))
;; Return nil for sake of nconc in dired-bunch-files.
nil)
I want to type something like 'scheme file.scm' and have it interpret the file, and then take me back to my shell, rather than loading it in the REPL.
edit: I tried scheme < test.scm and it still uses the REPL, the only difference is that scheme exits when the stream ends.
scheme < file.scm should work (as long as you don't specify --interactive and stdin is not a terminal, scheme works non-interactively).
To run a scheme program using MIT Scheme:
scheme --quiet < program.scm
The --quiet option ensures that the output from your program is the only thing that is displayed (i.e. you won't see the REPL, as per your requirements).
Caveat: This will not work if your program prompts the user for input using the input procedures (e.g. read, read-char, read-line, etc.). This is because of the shell input redirection (<) (See: relevant question). Unfortunately, there is currently no proper way of executing an MIT Scheme script from the command line when input procedures are used. The best option is probably mit-scheme --quiet --load 'myscript', but you'd have to manually exit MIT Scheme when the script finishes. Relevant mailing list thread: [MIT-Scheme-devel] How to run a script and exit?
EDIT: Due to the possibility that you may mistype < as >, resulting in the overwrite of your source code, I would suggest encapsulating the above command within a shell script or a shell function. For example:
runscheme () {
scheme --quiet < "$1"
}
Then you can run runscheme program.scm without fear that your source code will be overwritten. (Special thanks to Paul Rooney for bringing this potential mistake to my attention).
References
scheme --help:
--batch-mode, --quiet, --silent
Suppresses the startup report of versions and copyrights, and the
valediction.
This command line option seems to have been mistakenly ommitted from the list of command line options in the documentation, but I think this is a legimate command line option because scheme --help shows it, and because --batch-mode is used in other parts of the reference manual (e.g. here).
I think what you want is SCM. You can execute a .scm script like this:
$ scm -f foo.scm arg1 arg2 arg3
See http://people.csail.mit.edu/jaffer/scm_3.html#SEC28 for more details.
The SCM homepage: http://people.csail.mit.edu/jaffer/SCM
checked chez --help, and then I found this(let's say that I'm using chez scheme):
chez --script ./temp.scm
Also, --verbose is very useful:
chez --verbose --script ./temp.scm