Vim has makeprg variable. This variable takes program name which will be executed if :make is entered. Is there something similar in emacs?
Thanks.
The variable compile-command specifies the compiler program, which you can customize as needed. Here's the manual page for M-x compile and family.
I'm not aware of a make command in Emacs, but there is compile:
Compile the program including the current buffer. Default: run `make'.
Runs COMMAND, a shell command, in a separate process asynchronously
with output going to the buffer `*compilation*'.
The command that gets run by compile is defined by the variable compile-command, which can be set like this:
(setq compile-command "some command")
compile-command's default value is "make -k ".
Related
I would like to create a script that simply cleans up the whitespace and tabs on several files in a folder for me. I have created a bash file with among other things:
emacsclient -t -e '(progn (prelude-cleanup-buffer-or-region) (save-buffer-kill-terminal))' $FILE
Now this doesn't seem to work as it interprets ALL the file arguments as functions to be run (so $FILE is executed as a function). (P.S. prelude-cleanup-buffer-or-region is from here)
Now what I really want appears to be --batch described here (since I don't actually want to display anything on the screen) but this isn't one of the options of emacsclient. The reason I want to use emacsclient rather than just using emacs --batch is that I have a lot of startup files so want all of this to stay loaded otherwise my script would take too long.
Does anyone have any advice on how to go about this?
Thanks in advance.
emacsclient -e means evaluate lisp forms, do not edit files
from the man page
-e, --eval
do not visit files but instead evaluate the arguments as Emacs
Lisp expressions.
I guess you could add a (find-file "file") to your list of forms to execute
I just tried this snippet -
/opt/local/bin/emacsclient -e '(progn (find-file "./tmpfoo")
(end-of-buffer) (insert "ffff") (save-buffer))'
and it edits the file silently like you'd expect.
you could use shell globbing and a script to expand an argument filename into the list of forms.
do not run with the -t switch either, -e doesn't expect to have a persistent editor window, and you don't need the kill-terminal. The client will just run your elisp and exit.
I think I would probably write a lisp function that took a filename argument, that I loaded into emacs at startup time, and then just call that with a filename via emacsclient,
e.g. FILENAME="somefile"; emacsclient -e "(now-do-my-thing $FILENAME)"
The shell command
emacsclient -n -e '(make-remember-frame)'
works.
But the applescript
do shell script "emacsclient -n -e '(make-remember-frame)'"
just returns
emacsclient: can't find socket; have you started the server?
To start the server in Emacs, type \"M-x server-start\".
emacsclient: No socket or alternate editor. Please use:
--socket-name
--server-file (or environment variable EMACS_SERVER_FILE)
--alternate-editor (or environment variable ALTERNATE_EDITOR)
I rarely use this, but it has worked successfully in the past for various purposes. Perhaps you can modify it to suit your needs. The init.el or .emacs file must have (server-start) inside in order to make everything work. I have lots of stuff that loads when Emacs is activated for the first time, so I need a 5 second delay before emacsclient is called -- you can adjust the delay downward if your Emacs loads faster. If Emacs is already running, there is no need for a delay. You can comment out the verbal messages generated by say -- I used them this morning to test the conditions and make a minor adjustment to the script. The script contains a command-line example on line 4, which calls two Emacs functions. Of course, the path to your Emacs and emacsclient will need to be adjusted to wherever you have installed them on your computer.
# `(server-start)` must be inside `init.el` or `.emacs` file.
# This script can be used in the terimal: osascript path-to-script arguments
# Terminal Example:
# osascript /Users/HOME/.0.data/.0.emacs/.emacsclient.applescript "-e '(progn (dired \"/Applications\") (message \"Hello-World\!\"))'"
on run argv
set arg to item 1 of argv
set emacs to application "Emacs"
set appIsRunning to emacs is running
if appIsRunning then
say "Emacs is already running."
do shell script "/Users/HOME/.0.data/.0.emacs/Emacs_06_01_2014.app/Contents/MacOS/bin/emacsclient " & arg
else
tell application "/Users/HOME/.0.data/.0.emacs/Emacs_06_01_2014.app/Contents/MacOS/Emacs" to activate
say "Please wait five seconds for Emacs to load."
delay 5
do shell script "/Users/HOME/.0.data/.0.emacs/Emacs_06_01_2014.app/Contents/MacOS/bin/emacsclient " & arg
end if
end run
I have a project that uses a bash script to invoke cmake and make. I have successfully used this script from Emacs by using M-x compile, followed by typing:
cd ../..; ./build.sh
in the minibuffer. (The project organization is top/src/various_source_folders and build.sh is in top/.)
I am trying to define a directory variable to specify the default command to use for compile. I have tried the following (both with single or double quotes around the compile command) in .dir-locals.el:
((c++-mode
(compile-command 'cd ../..\; ./build.sh')))
Which gives no errors, but M-x compile still defaults to make -k.
((c++-mode
(set-variable 'compile-command' "cd ../../\; ./build.sh")))
Which gives a warning about unsafe variables. Even if I choose apply, compile still defaults to make -k
Simply using M-x eval-buffer with the second line ((set variable...) in *scratch* correctly sets the compile command.
Is there a different way I can/should be doing this?
Found an answer here.
Two periods and some parenthesis were missing from the syntax:
((c++-mode
. ((compile-command . "cd ../../\; ./build.sh"))))
I'm trying to get set up with SLIME on a Windows 7 box, but running M-x slime gives me the error
Spawning child process: invalid argument
I have inferior-lisp-program set to "C:\\Program Files\\ccl\\wx86cl.exe" (which is factually correct, and running (comint-run inferior-lisp-program) gives me a working CCL prompt), and the slime directory added to my 'load-path.
What am I doing wrong?
EDIT: Tried loading up the same environment through the Windows edition of lispbox, and it runs SLIME fine. I'd prefer not to use that one because it packages an older Emacs, CCL and SLIME than I want.
The message you received means that there's a high chance that there was a syntax problem with the command given to shell. This would be caused by having characters in the file name, which can be interpreted as doing something special. So, it looks like Emacs was trying to call C:\\Program "program" with an argument Files\\ccl\\wx86cl.exe.
There are several ways to address the error:
There has to be an escaping function, something like:
(shell-quote-argument "C:\\Program Files\\ccl\\wx86cl.exe")
But since you cannot affect how the file name is passed to the function which creates the process, this isn't going to work.
You can move the program you want to call to a directory with "safe" name.
You can move the executable to be on the system path (%PATH% variable in Windows) - through changing environment variables and appending the directory with the executable to it.
One more option is to add the directory with the executable to exec-path variable in Emacs. This variable holds a list of all directories looked up for programs to run, if you just call a program by name, rather then by full path. This also (at least for me) makes my .emacs file easier to port between different systems.
I'm trying to compile u-boot via Emacs' compilation mode, and it looks like Emacs doesn't know how to find bash environment variables. Even though I set them, and can compile via Emacs shell emulation, compilation mode still tries to compile as if they aren't there.
What do I need to do to make it more environment conscious?
You can try adding something like to your .emacs:
(let ((path (shell-command-to-string ". ~/.bashrc; echo -n $PATH")))
(setenv "PATH" path)
(setq exec-path
(append
(split-string-and-unquote path ":")
exec-path)))
Depending on whether you've set the env variables in .bash_profile or .bashrc you might need to slightly adjust this snippet. The example is for the PATH variable, which is a bit more special (since you have to set exec-path in Emacs as well), but can be extended to work for arbitrary variables - you could have a list of variables that have to be read from .bashrc and set into Emacs.
I'm not sure whether you're using OS X or GNU/Linux. Starting Emacs from the GUI's menu-bar in Linux will typically result in an Emacs that does not have the same PATH as one launched from the command line. This problem dates back to the first xdm Xsession scripts, and while they are fairly easy to fix (basically use an Xsessionwrapper script that does exec $SHELL -c Xsession so the shell gets run before running the user's Xsession), nobody has bother to do so in a very long time (and I doubt that anyone will). As far as I know the problem is present even into moder xdm descendants such as kdm and gdm.
On OS X the handling of the env variables is another problem entirely and to get your ENV variables you typically have to run Emacs from the command line like this /Applications/Emacs.app/Contents/MacOS/Emacs or play with ~/.MacOSX/environment.plist. The code snippet I've provided should cover you in both cases though.
Update
Recently this process was made easier by the exec-path-from-shell extension. It sets the emacs $PATH in more or less the same manner, but using an extension is generally preferable to hacking the solution yourself.
This is where the environment variables of the process that started emacs are:
— Command: getenv var
This function returns the value of the
environment variable var, as a string. var should be a string. If var
is undefined in the environment, getenv returns nil. It returns ‘""’
if var is set but null. Within Emacs, a list of environment variables
and their values is kept in the variable process-environment.
(getenv "USER")
⇒ "lewis"
— Variable: process-environment
This variable is a list of strings,
each describing one environment variable. The functions getenv and
setenv work by means of this variable.
process-environment
⇒ ("PATH=/usr/local/bin:/usr/bin:/bin"
"USER=lewis"
"TERM=xterm"
"SHELL=/bin/bash"
"HOME=/home/lewis"
...)
You seem to be assuming that emacs was started from a bash session. However, often processes under X are started from an sh session, which would not read the environment variables you had set in your ~/.bashrc script. One simple way to circumvent this is to change your ~/.xinitrc file to use bash instead of sh (it could be as simple as adding #!/bin/bash at the top of the file).
Source: gnu.org
It doesn't strictly answer your question, but you can always pass environment variables on the make command-line. For example : M-xcompileRETmake -k CXXFLAGS='-Wall'RET