Emacs lisp code to open lots of multi-terminals - emacs

When I start working on my project, I need to run lots of processes. Currently, I have to launch each process in a manual way:
M-x multi-term RET
M-x rename-buffer RET *some-name* RET
cd ~/foo/bar/
python ./task.py
How to write a code on Emacs lisp that does the following steps:
opens new multi-term buffer;
renames it (I know the title I'd like to hardcode it for each process);
runs one or two commands inside terminal

You can start from this template:
(defun python-erica ()
(interactive)
(let* ((default-directory "~/")
(proc (get-buffer-process
(ansi-term "/usr/bin/ipython" "erica"))))
(term-send-string
proc
(concat "import sys\n"))))
You can change:
function name
default dir
python executable
term buffer name
initial commands

Related

emacs cd for all splits

In emacs you can do M-x cd to change the default directory.
I usually have 5 splits/windows, so the cd I do in the first split does't affect the others. What If I want the cd to affect all my splits/buffers.
Is there an alternative command I can use?
There's nothing built-in but it's not too hard to write the function by hand:
(defun cd-all-windows (dir)
(interactive "Ddirectory: ")
(dolist (window (window-list))
(with-current-buffer (window-buffer window)
(cd dir))))
Put that in your .emacs and you should be able to run M-x cd-all-windows to get the desired effect.

How to open terminal in current directory?

When i use M-x shell to open a new terminal, it will sometimes set the current directory to the file in. But sometimes it won't. So is there a function to always open a new terminal in current directory?
There's the package shell-here available in ELPA: M-x list-packages, look for shell-here, mark for install (i) and execute (x).
An excerpt of the readme:
Open a shell buffer in (or relative to) default-directory,
e.g. whatever directory the current buffer is in. If you have
find-file-in-project installed, you can also move around relative
to the root of the current project.
I use Emacs shell buffers for everything, and shell-here is great
for getting where you need to quickly. The =find-file-in-project=
integration makes it very easy to manage multiple shells and
maintain your path / history / scrollback when switching between
projects.
github home: https://github.com/ieure/shell-here
And I like shell-pop too, to pop up and pop out a shell buffer window with one easily. And there's maybe more in ELPA !
M-x shell will switch to an existing shell if there's already one running, which may be your problem. If you don't mind creating lots of shell buffers, the command below will generate new buffers whenever it can't find one visiting the given directory:
(require 'cl-lib)
(defun shell-at-dir (dir)
"Open a shell at DIR.
If a shell buffer visiting DIR already exists, show that one."
(interactive (list default-directory))
(let ((buf (car (cl-remove-if-not
(lambda (it)
(with-current-buffer it
(and (derived-mode-p 'shell-mode)
(equal default-directory dir))))
(buffer-list)))))
(if buf
(switch-to-buffer buf)
(shell (generate-new-buffer-name "*shell*")))))

How to run multiple shells on Emacs

I am using Emacs 23.3.1 on windows 7. I know that I can run shell from emacs using M-x shell. I would like to have multiple shell windows in the same time, but typing M-x shell a second time just opens me the same shell window.
Is there a way to have different shell windows?
C-u M-x shell will do it.
It will prompt for a name for the new shell, just hit return for the default (which will be something like *shell*<2>.
Also works with eshell.
Another trick, if you use eshell: just as M-x eshell takes you back to *eshell* (rather than starting a new eshell), if you use a numeric prefix argument it will take you to that eshell buffer. For instance, C-3M-xeshell will take you to *eshell*<3>. Sadly if you use shell (rather than eshell), this trick doesn't seem to work (in my Emacs 24.0.50.1 at least.)
You can rename the buffer of your shell with M-x rename-buffer. Then you will be able to launch a second shell.
Look at MultiTerm, it makes managing multiple terminals in Emacs much easier.
After more than four years, I see that some people are still looking at this issue sometimes, so I will publish a quick function I wrote to load a shell and ask for its name. That way you can name a shell "sort-files" if it is dedicated to sorting files and another one "hive" if it's dedicated to run hive queries. I use that everyday now (on emacs 24):
(defun create-shell ()
"creates a shell with a given name"
(interactive);; "Prompt\n shell name:")
(let ((shell-name (read-string "shell name: " nil)))
(shell (concat "*" shell-name "*"))))
It might also be useful to use a screen-like interface to your shells. I've written my own, but there are others out there, like EmacsScreen.
This will autogenerate a new shell instance in whatever buffer you happen to be using; bind it to M-S or somethings like that and instant joy:
(defun new-shell ()
(interactive)
(let (
(currentbuf (get-buffer-window (current-buffer)))
(newbuf (generate-new-buffer-name "*shell*"))
)
(generate-new-buffer newbuf)
(set-window-dedicated-p currentbuf nil)
(set-window-buffer currentbuf newbuf)
(shell newbuf)
)
)
Many thanks to phils for recommending a rewrite using let, even though the result is even more awful parentheses...:\
This will open a new shell each time you invoke the function and rename it automatically if needed.
The added plus is if you are editing files remotely (dired/tramp...), this will open a shell on the remote host and rename it automatically with the remote hostname:
(defun ggshell (&optional buffer)
(interactive)
(let* (
(tramp-path (when (tramp-tramp-file-p default-directory)
(tramp-dissect-file-name default-directory)))
(host (tramp-file-name-real-host tramp-path))
(user (if (tramp-file-name-user tramp-path)
(format "%s#" (tramp-file-name-user tramp-path)) ""))
(new-buffer-nameA (format "*shell:%s*" host))
(new-buffer-nameB (generate-new-buffer-name new-buffer-nameA))
(currentbuf (get-buffer-window (current-buffer)))
)
(generate-new-buffer new-buffer-nameB)
(set-window-dedicated-p currentbuf nil)
(set-window-buffer currentbuf new-buffer-nameB)
(shell new-buffer-nameB)
))

P4CONFIG with emacs

I would like to see examples of how to setup perforce, using the config file functionality where emacs is used as the diff and merge programs (P4DIFF and P4MERGE settings). Even better if this is on Windows.
I'm also struggling with getting the P4EDITOR to work correctly when using emacsclientw, specifically specifying the alternate-editor functionality.
Any tips, suggestions, example configs are very welcome.
Here's a different trick I used to use. It adds a few command line options to emacs so that you can do diffs and merges in a new emacs instance (again using ediff).
;; -diff
(defun command-line-diff (switch)
(let ((file1 (pop command-line-args-left))
(file2 (pop command-line-args-left)))
(ediff file1 file2)))
(add-to-list 'command-switch-alist '("-diff" . command-line-diff))
;; -merge
(defun command-line-merge (switch)
(let ((base (pop command-line-args-left))
(sccs (pop command-line-args-left))
(mine (pop command-line-args-left))
(merg (pop command-line-args-left)))
(ediff-merge-with-ancestor sccs mine base () merg)))
(add-to-list 'command-switch-alist '("-merge" . command-line-merge))
Just put that in your .emacs file. Then you can set your P4DIFF program to be emacs -diff and your P4MERGE program to be emacs -merge.
I'm assuming you're already using p4.el.
Here's a function that will allow you to set your p4-client-config easily:
(defun p4-go (config)
(interactive
(list (read-file-name "P4 Config file: "
(concat (getenv "HOME") "/etc/perforce/")
""
t)))
(p4-set-client-config (expand-file-name config))
t)
Then I just run M-x p4-go <RET> conf <RET>.
My ~/etc/perforce/conf file looks like:
P4CLIENT=ewarmenhoven-ppd
P4PORT=perforce.netflix.com:1666
P4USER=ewarmenhoven
P4EDITOR=emacsclient
P4DIFF=diff -dupU8
P4MERGE=~/bin/emerge
The emerge merge program is just a short little shell script that calls emacsclient appropriately:
#!/bin/bash
base=$1
sccs=$2
mine=$3
merg=$4
emacsclient -e "(ediff-merge-files-with-ancestor \"$base\" \"$sccs\" \"$mine\" () \"$merg\")"
emacsclient "$merg"
If you're using cygwin it should work just fine.
For doing diffs, if it's running from the shell then I want the output in the shell, hence just using normal diff. If it's not, I use p4-ediff, which is bound to C-x p - by default.
The awesome answer by Eric doesn't work properly in latest emacs because of welcome screen. In order to hide the welcome screen (so that you may get the diff properly) please refer Unable to hide welcome screen in Emacs.
Another nifty setting which opens the diff in regular vertical mode is setting the below config variable
(custom-set-variables
;; custom-set-variables was added by Custom -- don't edit or cut/paste it!
;; Your init file should contain only one such instance.
'(ediff-split-window-function (quote split-window-horizontally)))

Emacs: How to start Local python interpreter when editing a remote python file via tramp

On Emacs, when I start python with C-c ! while editing a remote python file (using tramp - plinkx: on windows), the python interpreter is started on the remote host.
Is there any way I can edit the remote python file and start a local python interpreter?
I am using python-mode (not the default python.el)
python-mode creates an inferior process via 'make-comint, which uses 'start-file-process, which creates the process relative to the variable 'default-directory. So there are a few ways you can tackle this beast.
The first is to change 'default-directory to be something local, like:
(add-hook 'python-mode-hook (lambda () (setq default-directory "~"))
That has the downside that C-x C-f now behaves differently (starting at ~).
Another is to change the 'default-directory just for the invocation of 'py-shell, like so (untested):
(defadvice py-shell (around py-shell-different-directory activate)
"set default-directory just for py-shell"
(let ((default-directory "~"))
ad-do-it))