I want to open a cmd.exe window with the project root directory as it's current directory.
Here is my elisp code:
(defun open-cmd-and-cd-to-project-root()
(interactive)
(projectile-mode t)
(cd (projectile-get-project-root))
(shell))
It opens a cmd shell in an Emacs buffer . But I want it opens a new native cmd.exe window running in Windows rather than a buffer running in Emacs. How can I do that?
Do this:
(let ((proc (start-process "cmd" nil "cmd.exe" "/C" "start" "cmd.exe")))
(set-process-query-on-exit-flag proc nil))
The set-process-query-on-exit-flag to nil is so it won't bother on closing emacs (we can't kill it anyway).
Depending on the system configuration, the start command will spin up a native terminal or explorer window.
I believe the choice is down to whether you allow multiple instances of the explorer shell (the file browser), but some other config might be involved (Local Group Policy, etc.)
M-! start
Your confusion stems from the fact that M-! creates an ad-hoc shell for executing commands by the default processor (cmd.exe, or rather cmdproxy.exe in this case), so starting a shell from a shell will not yield a separate terminal window.
start is a cmd.exe builtin, which opens a new shell window (again, subject to system configuration, as well as arguments passed to it).
Related
Invoking 'shell' by M-x shell,
and plan to start a tmux session
it report errors
$ tmux
open terminal failed: terminal does not support clear
What's the problem?
If invoking `ansi-term', the operations of yanking and pasting are invalid.
So, shell perform better than ansi-term in routines.
How could activate tmux within a shell
tmux needs a real terminal, and shell doesn't provide that (as implied by the error you get). So you need to use term with tmux.
Or you can use built in functionality of Emacs to have features of tmux. E.g. C-x 2 and C-x 3 will split the frame into windows so you can have multiple terminals in a frame (an Emacs frame is what most applications would call a window). Start an emacs server and emacsclient to have sessions that you can connect to and keep running after you close the frame.
Copy (M-w) and paste (S-<insert>) should work by default. If you want to play with bindings, the key map is called term-raw-map and the commands are kill-ring-save and term-paste.
Also learn the difference between term-line-mode (C-c C-j) and term-char-mode (C-c C-k). Briefly, line mode behaves more like shell, and char mode behaves more like a real terminal, with most Emacs keybindings unavailable. I personally keep term buffers in char mode almost always and add some keybindings to term-raw-map so I can run certain Emacs commands.
Inspired by Git as when you type "git commit", it opens an Emacs or Vim session for you. I'm writing an Erlang escript, and I want it to open an Emacs session at the end of the execution of the escript. I've tried
os:cmd("emacs -nw file.txt")
but it doesn't seem to work. Evaluating the above command within the Erlang shell yields
"emacs: standard input is not a tty\n"
One way to do this is to keep an Emacs running with server mode (put (server-mode) in your ~/.emacs), and call emacsclient instead of emacs from Erlang. That will open the file in the existing Emacs session. emacsclient exits and returns control to your Erlang program once you hit C-x # in Emacs.
I want to write an emacs function that does the following -
1) Start a new shell named "abc".
2) Change the dir "/opt/abc"
3) In the dir run a shell command "python abc.py"
I have written the following function -
(defun abc-server ()
(interactive)
(shell-command "cd /opt/abc/")
(shell-command "python abc.py"))
The problem with the above -
1) It doesnt start a new shell
2) It doesnt change the dir.
3) When the cmd executes, it opens a browser window, which completely blocks any usage of emacs.
From shell-command's docstring (C-h f shell-command):
If COMMAND ends in ampersand, execute it asynchronously.
The output appears in the buffer `Async Shell Command'.
That buffer is in shell mode.
Also, combine it all into one command line. shell-command makes a new shell every time, so the pwd will not persist from one invocation to another.
(defun abc-server ()
(interactive)
(shell-command "cd /opt/abc/; python abc.py &"))
While #jpkotta's answer is good enough, a proper solution would use the anync primitives of Emacs. For one thing, you can only have one async shell command running at a time, whereas you can have a large number of named subprocesses.
(defun abc-server ()
(interactive)
;; Create buffer ahead of time so we can change its default directory
(save-excursion
(get-buffer-create "*abc-server*")
(cd "/opt/abc") )
(start-process "abc" "*abc-server*" "python" "abc.py") )
(I'm not altogether happy with the save-excursion hoop. I was hoping I could simply let-bind default-directory, but that didn't seem to work as I had expected. Alternatively, you could (start-process "abc" "*abc-server*" "sh" "-c" "cd /opt/abc; python abc.py").)
If you need to extend the command further, I would argue that this is a more scalable platform than the quick and dirty async shell command approach, but if this is all you are ever going to need, it doesn't matter much.
Emacs M-x compile does not see any aliases set in .bashrc. If I use M-x shell then type the alias, it is fine. I tried sourcing .bashrc from /etc/profile, from ~/.profile, ~/bash_env, anything I can think of to no avail.
I am on Emacs 23 and Ubuntu 11. I start emacs using /usr/bin/emacs %F, from a desktop button.
Emacs inherits its environment from the parent process. How are you invoking Emacs - from the command line, or some other way?
What happens if you:
M-x compile RET C-a C-k bash -i -c your_alias RET
Invoking bash as an interactive shell (-i option) should read your .bashrc aliases.
Edit: I think both M-x shell-command and M-x compile execute commands in an inferior shell via call-process. Try the following in your .emacs (or just evaluate):
(setq shell-file-name "bash")
(setq shell-command-switch "-ic")
I notice that after evaluation of the above, .bashrc aliases are picked up for use by both M-x shell-command and M-x compile, i.e
M-x compile RET your_alias RET
should then work.
My environment: Emacs 24.1 (pretest rc1), OSX 10.7.3
Keith Flower's answer works but can result in some slowdowns due to .bashrc being unnecessarily loaded in other places (presumably many many times, my computer is not exactly under-powered but emacs was almost unusable when trying to use autocomplete.el).
An alternative way is to locally modify shell-command-switch only for the functions where it is needed. This can be done using emacs' "advice" feature to create a wrapper around those functions. Here's an example that modifies compile:
;; Define + active modification to compile that locally sets
;; shell-command-switch to "-ic".
(defadvice compile (around use-bashrc activate)
"Load .bashrc in any calls to bash (e.g. so we can use aliases)"
(let ((shell-command-switch "-ic"))
ad-do-it))
You need to write similar "advice" for each function that you want to use .bashrc (e.g. I also needed to define the same advice for recompile), just copy the above and replace compile in the above with another function name.
You may like emac's bash-completion :
https://github.com/szermatt/emacs-bash-completion
You'll be able to use tab completion of your aliases in the compilation minibuffer and in shell-mode.
Enjoy !
(they speak about it here Bash autocompletion in Emacs shell-mode )
I think compilation commands are not interpreted through a shell: they are juste exec'ed by emacs (which means aliases, shell functions and other shell-specific things are not taken into account).
Try to wrap you compilation command into a shell-script which would source the correct environment.
You can do this either with a full-fledged shell-script in the form
#!/bin/bash
source "~/.bashrc"
my_command
or directly in emacs with a compilation command of the form
bash -c "source ~/.bashrc; my_command"
See Is there a way to get my emacs to recognize my bash aliases and custom functions when I run a shell command? for a fix which doesn't run all your .bashrc and doesn't create these error messages:
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
I have followed instructions from How can I run Cygwin Bash Shell from within Emacs? this question and I have gone further and added the (setq explicit-bash-args '("--login" "-i")) command, however emacs continues to only display the dos prompt when I type M-x shell. In summery my .emacs file looks like this:
(defun cygwin-shell ()
"Run cygwin bash in shell mode."
(interactive)
(let ((explicit-shell-file-name "C:/cygwin/bin/bash"))
(call-interactively 'shell)))
(setq explicit-bash-args '("--login" "-i"))`
Please be gentle with the answers as I am right at the bottom of the famous vertical emacs learning curve!
If you implemented the answer from that question, note that you have to do M-x cygwin-shell to start bash. If you want to use it for every M-x shell you need to call
(setq explicit-shell-file-name "C:/cygwin/bin/bash")
Since you stated that you are learning, here's a few tips when trying this out.
type C-x C-f ~/.emacs to open your .emacs file in your user path.
Enter your function above at the end
M-x load-file [RET] .emacs: loads the buffer (no need to restart emacs)
C-h a: If you are interested in some specific action, you can look it up
C-h v [RET] variable: can inspect the variable, check the value of explicit-bash-args for instance
And, btw, I'm not sure what the "--login -i" does, but someone stated in a comment that you should have that so "ls" would work. If you have your cygwin bin path in your PATH environment variable, bash will find ls anyway. No need to escape the path variable either, this is handled by bash (do an echo $PATH in bash when you get it working and you'll see).