Open two files in emacs in "reverse" order? - emacs

Say I open two files emacs -nw ./first-file ./second-file. The left buffer is second-file and the right buffer is first-file. Many people are used to it and I can see the argument, but for me, it's not intuitive, as first-file is to the left of second-file in the actual command. I know I switch them afterward, but I was wondering if there was perhaps a line in .emacs that could do this automatically.
Using GNU Emacs 25.3.2

Example usage: /path/to/emacs -nw --eval="(my-one-two \"foo\" \"bar\")"
(defun my-one-two (file-one file-two)
"Display FILE-ONE to the left and FILE-TWO to the right."
(let ((buffer-one (find-file-noselect file-one))
(buffer-two (find-file-noselect file-two)))
(delete-other-windows)
(set-window-buffer (selected-window) buffer-one)
(my-display-buffer buffer-two nil 'right)))
(defun my-display-buffer (buffer-or-name alist direction &optional size pixelwise)
"BUFFER: The buffer that will be displayed.
ALIST: See the doc-string of `display-buffer' for more information.
DIRECTION: Must use one of these symbols: 'left 'right 'below 'above
SIZE: See the doc-string for `split-window'.
PIXELWISE: See the doc-string for `split-window'.
There are three possibilities:
- (1) If a window on the frame already displays the target buffer,
then just reuse the same window.
- (2) If there is already a window in the specified direction in relation
to the selected window, then display the target buffer in said window.
- (3) If there is no window in the specified direction, then create one
in that direction and display the target buffer in said window."
(let* ((buffer
(if (bufferp buffer-or-name)
buffer-or-name
(get-buffer buffer-or-name)))
(window
(cond
((get-buffer-window buffer (selected-frame)))
((window-in-direction direction))
(t
(split-window (selected-window) size direction pixelwise)))))
(window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
window))

Assuming you are running on some kind of linux shell the easiest way I see is to use an alias:
alias myE="emacs -nw $2 $1"
To run emacs now, do: myE file1 file2 and it executes emacs -nw file2 file1.
In order to persist this, put the alias command into your ~/.bashrc.

Related

Emacs auto-display of things at point in a right window

I'd like to implement a function it shows relevant code paragraph in its right window when Emacs cursor is prompting on a certain word.
Let's assume that I have my own log format and I have corresponding database which I can find where a log message came from then I have the pointer on a certain log message. If so, then I like to let Emacs open the corresponding source file in a right side window of that log buffer.
Now I can query and get the location of source file thru my own db and emacs. But I still don't know how to control the right window.
If I opened a right window once, then Emacs would open an another one again, I don't want to let it do but want to let it use the previous, existing window.
How could I implement this? Please advise me, or share an example you might have.
Thanks.
In addition to the examples below using the custom function my-display-buffer, keep in mind that BUFFER can be obtained by means other than find-file-noselect; e.g., current-buffer if so desired. In terms of finding your location in the other window, you may find it helpful to select-window or with-selected-window or set-window-point, etc. If the window is selected with the target buffer visible in said window, then simple things like goto-char will suffice to go visually to a particular location. The example my-display-buffer function has a doc-string which describes generally what it was designed to do; i.e., "There are three possibilities ...".
Display buffer to the left:
(let ((buffer (find-file-noselect "~/foo.py")))
(with-current-buffer buffer
(message "major-mode: %s" major-mode))
(my-display-buffer buffer nil 'left))
Display buffer to the right:
(let ((buffer (find-file-noselect "~/foo.py")))
(with-current-buffer buffer
(message "major-mode: %s" major-mode))
(my-display-buffer buffer nil 'right))
Display buffer above:
(let ((buffer (find-file-noselect "~/foo.py")))
(with-current-buffer buffer
(message "major-mode: %s" major-mode))
(my-display-buffer buffer nil 'above))
Display buffer below:
(let ((buffer (find-file-noselect "~/foo.py")))
(with-current-buffer buffer
(message "major-mode: %s" major-mode))
(my-display-buffer buffer nil 'below))
(defun my-display-buffer (buffer-or-name alist direction &optional size pixelwise)
"BUFFER: The buffer that will be displayed.
ALIST: See the doc-string of `display-buffer' for more information.
DIRECTION: Must use one of these symbols: 'left 'right 'below 'above
SIZE: See the doc-string for `split-window'.
PIXELWISE: See the doc-string for `split-window'.
There are three possibilities:
- (1) If a window on the frame already displays the target buffer,
then just reuse the same window.
- (2) If there is already a window in the specified direction in relation
to the selected window, then display the target buffer in said window.
- (3) If there is no window in the specified direction, then create one
in that direction and display the target buffer in said window."
(let* ((buffer
(if (bufferp buffer-or-name)
buffer-or-name
(get-buffer buffer-or-name)))
(window
(cond
((get-buffer-window buffer (selected-frame)))
((window-in-direction direction))
(t
(split-window (selected-window) size direction pixelwise)))))
(window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
window))

how to show buffer content in real time in other window when focus is in buffer list

I have 2 windows, one is the buffer list, how do I show the buffer in the buffer list in the other windows when I use n and p to naviage in the buffer list?
Thanks a lot.
If I understand the question right, the answer is simply to use C-o in the buffer menu. that displays the buffer of the line you are on in another window, but it does not select that buffer. That is, it does not move the input focus to that buffer's window. The buffer list retains the input focus, so you can continue to use C-o on different lines, to display different buffers.
If you mean an Emacs window when you say "frame", then see above. The same is true even if the buffers are on different frames, with this caveat: Some window managers, including MS Windows, change the input focus to a new frame that is created. So if, for example, you have non-nil pop-up-frames (so that a separate frame is used to display a buffer), and if the buffer you choose to display (using C-o) is not already shown in some other frame, then displaying it not only creates a new frame for it but also shifts the focus to that new frame. If the buffer is already visible in another frame then C-o simply raises that frame.
There is currently no key bound in the buffer-list display, to both (a) move the cursor down or up to the next or previous buffer line and (b) invoke the C-o behavior of displaying the buffer named on the target buffer line. But you could easily define such a command and bind it to a key:
(defun show-next (arg)
"Show next line's buffer in another window."
(interactive "p")
(next-line arg)
(Buffer-menu-switch-other-window))
(defun show-previous (arg)
"Show previous line's buffer in another window."
(interactive "p")
(previous-line arg)
(Buffer-menu-switch-other-window))
(define-key Buffer-menu-mode-map "\M-n" 'show-next)
(define-key Buffer-menu-mode-map "\M-p" 'show-previous)
Here's my prototype for this feature in a dired buffer. It kills a buffer after it got visited.
This is a feature I like from the ranger file manager, it is handy when you explore a directory.
(setq show-next-current-buffer nil)
(defun show-next ()
(interactive)
(next-line 1)
(dired-find-file-other-window)
(if show-next-current-buffer (kill-buffer show-next-current-buffer))
(setq show-next-current-buffer (current-buffer))
(other-window 1)
)
(defun show-previous ()
(interactive)
(previous-line 1)
(dired-find-file-other-window)
(if show-next-current-buffer (kill-buffer show-next-current-buffer))
(setq show-next-current-buffer (current-buffer))
(other-window 1)
)
(define-key dired-mode-map "n" 'show-next)
(define-key dired-mode-map "p" 'show-previous)
edit: I've written a minor mode to enable/disable this feature easily. See https://gitlab.com/emacs-stuff/my-elisp/blob/master/dired-show.el and meld it to your needs.

Make *Buffer List* always appear in horizontal split

I know Emacs tries to be intellectual and opens its helper buffers depending on which dimension of the window is bigger, so it may appear in vertical split window if current width is bigger than height, and in horizontal split otherwise.
But I’d prefer it to open that list always in horizontal split, because there are long paths I can’t see when the buffer is placed in vertical split. How can I do this?
I believe you've got the horizontal/vertical split terminology back to front (I can never remember which is which either), but as your goal was to retain the original window's width, I'm forcing a vertical split.
See C-hf split-window-sensibly RET. It tells you what to do:
You can enforce this function to not split WINDOW horizontally,
by setting (or binding) the variable `split-width-threshold' to
nil. If, in addition, you set `split-height-threshold' to zero,
chances increase that this function does split WINDOW vertically.
So as a permanent setting:
(setq split-width-threshold nil)
(setq split-height-threshold 0)
For just a specific function, you can advise that function (but see Edit 2 below!):
(defadvice list-buffers (around list-buffers-split-vertically)
"Always split vertically when displaying the buffer list.
See `split-window-sensibly'."
(let ((split-width-threshold nil)
(split-height-threshold 0))
ad-do-it))
(ad-activate 'list-buffers)
Edit: Actually, in this instance I suspect you're only concerned with the interactive case, in which case it's preferable to define a function and remap the bindings:
(defun my-list-buffers-vertical-split ()
"`list-buffers', but forcing a vertical split.
See `split-window-sensibly'."
(interactive)
(let ((split-width-threshold nil)
(split-height-threshold 0))
(call-interactively 'list-buffers)))
(global-set-key [remap list-buffers] 'my-list-buffers-vertical-split)
Edit 2: And Stefan points out that display-buffer-alist facilitates such things without advising functions (and of course avoiding unnecessary advice is always a good thing). I believe we still need a custom action, so:
(defun my-display-buffer-pop-up-same-width-window (buffer alist)
"A `display-buffer' ACTION forcing a vertical window split.
See `split-window-sensibly' and `display-buffer-pop-up-window'."
(let ((split-width-threshold nil)
(split-height-threshold 0))
(display-buffer-pop-up-window buffer alist)))
(add-to-list 'display-buffer-alist
'("\\*Buffer List\\*" my-display-buffer-pop-up-same-width-window))
If horizontally or vertically, presently neither split-height-threshold nor split-width-threshold seem reliable WRT to expected kind of split. Which looks like a bug, resp. design issue.
As a work-around call M-x split-window-horizontally resp. -vertically before, or advise the function with it.
You can remove (5) if you prefer not to select the window after it is displayed -- i.e., remove (select-window (get-buffer-window (buffer-name buffer))). I like the bottom window to be reserved for a 3-month calendar, so that's why I have a condition to use the window above (if it exists) -- you can remove that condition if you are so inclined. Actually, it's your function so you can modify everything as you see fit now that you see how it works. The alist would be used like this: '((window-width . 33)) if you wanted to control certain aspects of the target window, etc. I find myself always going back to this document page because it is the only scanty formal example I've found . . . and, of course, the source itself window.el: http://www.gnu.org/software/emacs/manual/html_node/elisp/Display-Action-Functions.html
(defun lawlist-list-buffers-left (&optional arg)
"Display a list of existing buffers.
The list is displayed in a buffer named \"*Buffer List*\".
See `buffer-menu' for a description of the Buffer Menu.
By default, all buffers are listed except those whose names start
with a space (which are for internal use). With prefix argument
ARG, show only buffers that are visiting files."
(interactive "P")
(lawlist-display-buffer-left (list-buffers-noselect arg) nil))
(defun lawlist-list-buffers-right (&optional arg)
"Display a list of existing buffers.
The list is displayed in a buffer named \"*Buffer List*\".
See `buffer-menu' for a description of the Buffer Menu.
By default, all buffers are listed except those whose names start
with a space (which are for internal use). With prefix argument
ARG, show only buffers that are visiting files."
(interactive "P")
(lawlist-display-buffer-right (list-buffers-noselect arg) nil))
(defun lawlist-display-buffer-left (buffer alist)
"(1) If `buffer` is already displayed, then display it again in the same window.
(2) If `buffer` is not already displayed, and if there is a window to the left,
then display that `buffer` in said window. (3) If `buffer` is not already
displayed, and if there is a window to the right, then use the selected window.
(4) If all else fails, then create a new window to the left and display `buffer` there.
(5) Select the target window which displays `buffer`."
(let (
(window
(cond
((get-buffer-window buffer (selected-frame)))
((window-in-direction 'above))
((window-in-direction 'left))
((window-in-direction 'right)
(selected-window))
(t
(split-window (selected-window) nil 'left)))))
(window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
;; OPTIONAL -- uncomment to select the target window.
;; (select-window (get-buffer-window (buffer-name buffer)))
))
(defun lawlist-display-buffer-right (buffer alist)
"(1) If `buffer` is already displayed, then display it again in the same window.
(2) If `buffer` is not already displayed, and if there is a window to the right,
then display that `buffer` in said window. (3) If `buffer` is not already
displayed, and if there is a window to the left, then use the selected window.
(4) If all else fails, then create a new window to the right and display `buffer` there.
(5) Select the target window which displays `buffer`."
(let (
(window
(cond
((get-buffer-window buffer (selected-frame)))
((window-in-direction 'above))
((window-in-direction 'right))
((window-in-direction 'left)
(selected-window))
(t
(split-window (selected-window) nil 'right)))))
(window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
;; OPTIONAL -- uncomment to select the target window.
;; (select-window (get-buffer-window (buffer-name buffer)))
))

How to make *Buffer List* appear below the other windows?

So, instead of creating a split window under (or to the right of) the currently active window, it would appear below all the existed ones with a half of the frame height? And, after closing, frame layout would be restored as it was before calling C-x C-b?
I’d like see the full paths to opened files.
See also my previous answer to your related issue: https://stackoverflow.com/a/21544307/2112489
See also a related answer by #phils, which includes a nice halve-other-window-height function: https://stackoverflow.com/a/4988206/2112489
See also the built-in stock functions display-buffer-below-selected or display-buffer-at-bottom, which are available in a recent version of Emacs Trunk -- I'm not sure when each function was first introduced. They are in window.el.
The doc-string of the function split-window states in relevant part:  SIZE defaults to half of
WINDOW's size. That is the second optional argument -- i.e., split-window (&optional window size side pixelwise)
Don't be shy about modifying these things -- you can make it do whatever you want. If want to select the window automatically after it is displayed, then you can add this to the bottom of the lawlist-display-buffer-below function:  (select-window (get-buffer-window (buffer-name buffer))) -- leaving, of course, two closing parenthesis to the right -- i.e., one closing parentheis for the let binding and one closing parenthesis for the defun.
(defun lawlist-list-buffers-below (&optional arg)
"Display a list of existing buffers.
The list is displayed in a buffer named \"*Buffer List*\".
See `buffer-menu' for a description of the Buffer Menu.
By default, all buffers are listed except those whose names start
with a space (which are for internal use). With prefix argument
ARG, show only buffers that are visiting files."
(interactive "P")
(lawlist-display-buffer-below (list-buffers-noselect arg) nil))
(defun lawlist-display-buffer-below (buffer alist)
(let (
(window
(cond
((get-buffer-window buffer (selected-frame)))
((window-in-direction 'below))
(t
(split-window (selected-window) nil 'below)))))
(window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)))

How to open multiple terminals?

In Emacs, I often find myself in a situation where I need to jump back and forth between various source files to various terminals. However, I feel like I do not have a good way to do this efficiently and it's clumsy that you can only open one shell in Emacs (shell, eshell, or term).
Moreover, I need an efficient way of juggle between multiple terminals and source files.
How can I achieve this?
You can have as many terminals and shells open at once as you want. Just use M-x rename-buffer to change the name of an existing *term* or *shell* buffer, and the next time you do M-x term or M-x shell, a brand new buffer will be created. In the case of M-x shell, a prefix argument will cause you to be prompted for the name of the new shell buffer, as offby1 noted.
A few years ago I had a job where I had to regularly log in to various production servers named "host01.foo.com", "host02.foo.com", etc. I wrote a little function like this one to make it easier to manage them all:
(defun ssh-to-host (num)
(interactive "P")
(let* ((buffer-name (format "*host%02d*" num))
(buffer (get-buffer buffer-name)))
(if buffer
(switch-to-buffer buffer)
(term "/bin/bash")
(term-send-string
(get-buffer-process (rename-buffer buffer-name))
(format "ssh host%02d.foo.com\r" num)))))
Then I bound this command to (say) s-h (super H), enabling me to just type M-5 s-h. If I didn't already have a buffer named *host05*, it would start a new terminal emulator buffer, rename it to *host05*, and ssh me into host05.foo.com. If buffer *host05* already existed, it would simply switch me to it. Quite handy!
You can certainly have multiple interactive shells open. Try typing C-u M-x shell RET RET.
Try using MultiTerm to open multiple shells.
You can use Emacs Lisp Screen, which emulates GNU Screen and provides easy key bindings to jump to and between a number of different shells.
I use many methods for incorporating my terminal life into Emacs:
elscreen.el is a life saver, if you have a complicated window layout like gdb or have simply become overwhelmed with clutter you just open a new screen. In your case you could dedicate one screen to terminals.
multi-term.el makes managing terminals a bit easier.
shell-pop.el, a great tool for quick terminal access. shell-pop lets you assign a key to opening and closing a specific shell buffer window, if you've used drop-down terminals like tilda you know how incredibly handy this can be:
Here's and example of my shell-pop configuration, I use the key C-t to pop up an eshell:
(require 'shell-pop)
(shell-pop-set-internal-mode "eshell") ; Or "ansi-term" if you prefer
(shell-pop-set-window-height 60) ; Give shell buffer 60% of window
;; If you use "ansi-term" and want to use C-t
;; (defvar ansi-term-after-hook nil)
;; (add-hook 'ansi-term-after-hook
;; '(lambda ()
;; (define-key term-raw-map (kbd "C-t") 'shell-pop)))
;; (defadvice ansi-term (after ansi-term-after-advice (org))
;; (run-hooks 'ansi-term-after-hook))
;; (ad-activate 'ansi-term)
(global-set-key (kbd "C-t") 'shell-pop)
I usually do an an M-x server-start and then use emacsclient --no-wait to open files. I've aliased that to e with some embellishments so that it's a little more convenient.
I do all my work in a single terminal and just "throw" the files I want to edit into Emacs using e. Inside Emacs, I juggle around using iswitchb and it works just fine. YMMV.
I regularly used 10 or so shells in my old workplace. The secret is you have to rename additional shell buffers. I did this automatically though in my .emacs, creating and naming the shells logically (I had projnameRun and projnameBuild for every project). Worked really well together with anything, making it very easy to refind the right shell (you use the end of the project name combined with either r or b for run/build).
Instead of having several terminal windows in emacs, I spawn a different xterm whenever I need a new terminal. This of course is bearable because I use a very lightweight terminal emulator (urxvt) which starts in under 0.2s.
Then I use my window manager to switch between them and emacs frames. A configurable window manager will have plenty of options to tune to switch between windows (extremely) efficiently. Inside emacs, I use windmove and ido-mode, and have bound to C-tab a function that switches to the last buffer (because I use C-x b in that fashion a lot).
So um, not sure how useful it is to you since it's quite different from your use pattern, but this is what works for me.
I had exactly the same problem some years ago, and found nothing that satisfied me; so I wrote my own "toggle shell" function. It toggles between the current frame or window configuration and a system shell buffer. It can also put the shell into a dedicated frame, and inject a pushd to the current buffer directory.
This is an excerpt from my .emacs:
(defvar --toggle-shell-last-window-conf nil "The last window configuration.")
(defvar --toggle-shell-last-buf nil "The last buffer object in case there's no last window configuration.")
(defvar --toggle-shell-last-frame nil "The frame that was selected when opening a shell buffer.")
(defun --toggle-shell-have-conf ()
(window-configuration-p --toggle-shell-last-window-conf))
(defun --toggle-shell-store-last-conf ()
(setq --toggle-shell-last-buf (current-buffer)
--toggle-shell-last-frame (selected-frame)
--toggle-shell-last-window-conf (current-window-configuration)))
(defun --toggle-shell-restore-last-conf ()
(if (--toggle-shell-have-conf)
(progn (raise-frame --toggle-shell-last-frame)
(set-window-configuration --toggle-shell-last-window-conf))
(let ((bufnam (if (bufferp --toggle-shell-last-buf)
(buffer-name --toggle-shell-last-buf) --toggle-shell-last-buf)))
(if bufnam
(if (get-buffer bufnam) (switch-to-buffer bufnam t)
(message "%s: buffer not available" bufnam))))))
(defun --toggle-shell (&optional display inject-cd)
"Toggles between current buffers and a system shell buffer. With prefix-arg
close the shell.
When DISPLAY is 'vertical splits the shell as vertical window; when 'frame uses
a dedicated frame (default: single window). When INJECT-CD executes a `pushd'
to the working directory of the buffer from which you toggled the shell."
(interactive)
(let* ((shell-buf (get-buffer "*shell*"))
(shell-window ; non-nil when currently displayed
(if shell-buf (get-buffer-window shell-buf t)))
(shell-frame
(if shell-window (window-frame shell-window)))
(in-shell (eq (current-buffer) shell-buf))
(vertical (string= display 'vertical))
(popup-frame (or (string= display 'frame)
(and inject-cd (not (bufferp shell-buf)))
(and (framep shell-frame)
(not (eq shell-frame (selected-frame)))))))
;; With prefix-arg close shell, restore windows. Otherwise (no prefix-arg)
;; toggle shell window; restore windows when called twice in a row, or the
;; current buffer is the shell buffer (`in-shell').
(if current-prefix-arg
(if (bufferp shell-buf)
(progn (message "Exiting shell '%s'" (buffer-name shell-buf))
(kill-buffer shell-buf)
(if in-shell (--toggle-shell-restore-last-conf)))
(error "No shell buffer to kill."))
;; If already in shell-buffer toggle back to stored frame-configuration.
(if (and in-shell (not inject-cd))
(progn
(--toggle-shell-restore-last-conf)
;; Recurse to reopen the shell-buffer in a dedicated frame, or
;; close the dedicated frame and reopen the buffer in a window.
(if (and popup-frame (eq shell-frame (selected-frame)))
(--toggle-shell 'frame inject-cd)
(when (and popup-frame shell-frame)
(delete-frame shell-frame)
(--toggle-shell nil inject-cd))))
;; Not in shell buffer. Warp to it or create new one.
(unless in-shell
(--toggle-shell-store-last-conf))
(if popup-frame
(progn (switch-to-buffer-other-frame (or shell-buf "*shell*"))
(raise-frame
(or shell-frame (window-frame (get-buffer-window "*shell*" t)))))
(if (> (count-windows) 1)
(delete-other-windows)))
;; Finally `cd' into the working directory the current buffer.
(let ((new-shell (not (bufferp shell-buf)))
(new-dir ; `default-directory' of `--toggle-shell-last-buf'
(if --toggle-shell-last-buf
(buffer-local-value 'default-directory --toggle-shell-last-buf))))
;; Open shell, move point to end-of-buffer. The new shell-buffer's
;; `default-directory' will be that of the buffer the shell was
;; launched from.
(when vertical
(if (> (count-windows) 1)
(delete-other-windows))
(split-window-vertically) (other-window 1))
(funcall 'shell)
(when new-shell
(message "New shell %s (%s)" (buffer-name (current-buffer)) new-dir)
(if inject-cd (sit-for 2))) ; wait for prompt
(goto-char (point-max))
;; If on a command-prompt insert and launch a "cd" command (assume no
;; job is running).
(when (and inject-cd new-dir)
(save-excursion
(backward-line-nomark) (end-of-line)
(unless (setq inject-cd (re-search-forward comint-prompt-regexp (point-max) t))
(error "Cannot `pushd', shell is busy")))
(when (and inject-cd)
(let* ((cmd (format
"pushd '%s' %s" (comint-quote-filename new-dir)
(if (buffer-file-name --toggle-shell-last-buf)
(format "# '%s'" (file-name-directory (buffer-file-name --toggle-shell-last-buf)))
""))))
;; `shell-process-cd' set new `default-directory' and set
;; `shell-last-dir' to old. (If the pushd command is
;; successful, a dirs is performed as well; >nul discards this
;; output.)
(shell-process-cd new-dir)
(insert cmd)
(comint-send-input)
(message "%s: cd '%s'" (buffer-name --toggle-shell-last-buf) new-dir))
)
)
)
)
)
)
)
--toggle-shell is the function that does the trick. I bind it to F12:
;; F12 toggle between shell buffer and current window configuration
;; SHIFT-F12 like before, but let shell buffer appear in a dedicated frame
;; ALT-F12 inject a pushd to change to directory of current buffer
;; CTRL-F12 `shell-command'
(global-set-key [(f12)] '--toggle-shell)
(global-set-key [(shift f12)] '(lambda()(interactive)(--toggle-shell 'frame)))
(global-set-key [(meta f12)] '(lambda()(interactive)(--toggle-shell nil t)))
(global-set-key [(meta f10)] '(lambda()(interactive)(--toggle-shell nil t)))
(global-set-key [(control f12)] 'shell-command) ; alias M-!
This is a significant bunch of code to be posted here. But it shall work well.
Semi related - you can quickly run a shell command on selected file with
M+shift+!
It saves a lot of time for smaller commands chmod etc
And maybe my quick pop-up shell also might help you. A quick pop-up shell for emacs
Ecb + eshell will be what you want exactly!
I use vi, but hope this helps. I can open as many terminals as I want by (eg. in Ubuntu 16.04):
ctrl + alt + t
I usually open 2 terminals, and move (position) one terminal to the right by:
ctrl + super + right-arrow
and move the other terminal to the left by:
ctrl + super + left-arrow
so that I have a divided screen by 2 terminals.