Emacs shell-mode display is too wide after splitting window - emacs

If I run M-x shell in emacs to get a terminal, it knows where to wrap lines automatically. For example, the output of ls is formatted into columns that fit the window properly.
My problem is if I then split the window vertically with C-x 3, shell-mode still thinks the window fills the whole frame. The result is ugly wrapping of command output. Is there a way to let shell-mode know it has to update the screen width?
EDIT:
Using HN's answer below, I came up with this fix:
(defun my-resize-window ()
"Reset the COLUMNS environment variable to the current width of the window."
(interactive)
(let ((proc (get-buffer-process (current-buffer)))
(str (format "export COLUMNS=%s" (window-width))))
(funcall comint-input-sender proc str)))
(defun my-shell-mode-hook ()
(local-set-key "\C-cw" 'my-resize-window))

I'm a bit late to the party, but COLUMNS isn't the way to do this. Here is an excerpt from my .emacs:
(defun comint-fix-window-size ()
"Change process window size."
(when (derived-mode-p 'comint-mode)
(set-process-window-size (get-buffer-process (current-buffer))
(window-height)
(window-width))))
(defun my-shell-mode-hook ()
;; add this hook as buffer local, so it runs once per window.
(add-hook 'window-configuration-change-hook 'comint-fix-window-size nil t))
(add-hook 'shell-mode-hook 'my-shell-mode-hook)
Unlike exporting COLUMNS each time, this method doesn't require you to be in
bash at the moment and it doesn't spam your session with blank prompts. This
code should probably be in comint itself, maybe I will file a bug report.
EDIT: If you modify window-configuration-change-hook in a buffer-local-way
the hook runs once per window, as opposed once per frame.

Here is a slightly improved resize function from #Christopher Monsanto's answer. The original one will cause a problem due to nil process. (e.g exit in shell-mode)
(defun comint-fix-window-size ()
"Change process window size."
(when (derived-mode-p 'comint-mode)
(let ((process (get-buffer-process (current-buffer))))
(unless (eq nil process)
(set-process-window-size process (window-height) (window-width))))))

This display is dictated by the COLUMNS environment variable. In my setup COLUMNS has a value of 202, after a vertical split ls displays correctly on shell-mode if I set columns to 80 via
export COLUMNS=80
There must be a way to code this up but I don't have enough elisp-fu to do that. If you'd rather avoid the hassle multi-term manages this automagically.
http://www.emacswiki.org/emacs/MultiTerm

Try M-x eshell; it doesn't have this problem.

Related

Open Org Capture buffer in specific window?

I've been an Emacs user for about a year or so. I routinely have the same window set up each session (four windows).
I've set up capture templates and can capture what I want, but: instead of capture mode temporarily jerking me out of my window setup, I'd like the chosen capture template to open in a new (fifth) window, preserving my existing layout. I typically want the capture template open for a while, so it's disruptive.
This seems like it would be an obvious option, but I can't figure it out. Thanks in advance to all the Emacs heads out there.
I came up with a easier-to-use version of Dan's answer to the linked question:
(defun my-org-capture-place-template-dont-delete-windows (oldfun &rest args)
(cl-letf (((symbol-function 'delete-other-windows) 'ignore))
(apply oldfun args)))
(with-eval-after-load "org-capture"
(advice-add 'org-capture-place-template :around 'my-org-capture-place-template-dont-delete-windows))
That is, instead of having to modify Org-mode code and remove the call to delete-other-windows, this piece of code temporarily redefines delete-other-windows to ignore while org-capture-place-template is being called.
It doesn't do quite what you want: it picks one of the existing windows and puts the capture buffer there. At least it's better than the default behaviour of removing all previous windows but one.
There's probably a way to do what you want by customising the variable display-buffer-alist, but I couldn't figure it out...
You could also use https://github.com/raxod502/el-patch and patch org-capture after loading (look for the (el-patch-remove (delete-other-windows))):
(el-patch-feature org-capture)
(with-eval-after-load 'org-capture
(el-patch-defun org-capture-place-template (&optional inhibit-wconf-store)
"Insert the template at the target location, and display the buffer.
When `inhibit-wconf-store', don't store the window configuration, as it
may have been stored before."
(unless inhibit-wconf-store
(org-capture-put :return-to-wconf (current-window-configuration)))
(el-patch-remove (delete-other-windows))
(org-switch-to-buffer-other-window
(org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE"))
(widen)
(org-show-all)
(goto-char (org-capture-get :pos))
(setq-local outline-level 'org-outline-level)
(pcase (org-capture-get :type)
((or `nil `entry) (org-capture-place-entry))
(`table-line (org-capture-place-table-line))
(`plain (org-capture-place-plain-text))
(`item (org-capture-place-item))
(`checkitem (org-capture-place-item)))
(org-capture-mode 1)
(setq-local org-capture-current-plist org-capture-plist)) )
For some reason, the #legoscia approach fails for me in emacs 28.
So here is the el-patch snippet as suggested previously:
(el-patch-feature org-capture)
(with-eval-after-load 'org-capture
(el-patch-define-and-eval-template
(defun org-capture-place-template)
(el-patch-remove (delete-other-windows))))

How do I configure Emacs to dedicate the Calculator window?

I'm using emacs 24.3 from emacsformacosx.com on OS X 10.9 (Mavericks). The behavior is the same on emacs 23.4.1 on Debian Wheezy.
I want to automate applying set-window-dedicated-p so switching/opening a buffer won't use certain windows. For example, if I'm in the Calculator and manually use Meta-: and enter (set-window-dedicated-p (get-buffer-window) t) then it works great - my Calculator window doesn't get hijacked by other buffers. I want it to work like that automatically.
I put this in my .emacs file:
(add-hook 'calc-mode-hook
(lambda ()
(message "Dedicating %s" (buffer-name))
(set-window-dedicated-p (get-buffer-window) t)
(message "Dedication %s" (window-dedicated-p (get-buffer-window "*Calculator*")))))
Then I start up emacs, switch to the *Messages* window, and Meta-x calc. The *Messages* buffer shows
Dedicating *Calculator*
Dedication t
so I know my hook was called and what buffer it operated on. But the *Calculator* buffer is not dedicated - it doesn't behave properly and Meta-: (window-dedicated-p) returns nil. The *Messages* buffer is dedicated instead.
Why is the *Calculator* window shown as dedicated in the hook but not afterwards? What am I doing wrong here?
Unfortunately the *Calculator* buffer is not displayed in any window at the point your code runs.
Your 'validation' messages were misleading you. (buffer-name) is certainly the buffer you want, but it's not in any window, and so you're actually passing a nil argument for the window in all situations. i.e. You're setting the current window dedicated, and then confirming that it's dedicated (which it should indeed be).
I think after advice to calc is what you need here. e.g.:
(defadvice calc (after my-dedicated-calc-window)
"Make the *Calculator* window dedicated."
(let ((win (get-buffer-window "*Calculator*")))
(when win
(set-window-dedicated-p win t))))
(ad-activate 'calc)
n.b. I'm not sure exactly how the arguments to calc affect the window display, but I think with the test for the window wrapping the call to set-window-dedicated-p this code is probably fine in all cases.

Select the previously-selected window in emacs

I need an emacs built-in function or elisp function that can take me to the previously-selected window. I thought that (select-window (get-lru-window)) would do it, but if I run it several times, seems to just cycle between windows instead of swapping back and forth between them, which is what I expect.
Any other ideas?
There doesn't seem to be a way to get the most recently selected window in emacs (as opposed to the least recently used returned by get-lru-window). Internally emacs tracks use_time on windows, and get-lru-window uses that to find the "oldest" window. But unfortunately that is not exposed in elisp.
The window list is ordered in cyclic window ordering which doesn't help in your case.
The buffer-list is however ordered most-to-least recently used buffer (or not really strictly, there is a (bury-buffer) function to move a buffer last).
This means that, if you can transform your problem into something like "how can I switch to the buffer in a different window that was most recently the selected buffer", it should be possible.
One way would be to do something like this:
(defun switch-to-previous-buffer-in-a-different-window ()
(interactive)
(let* ((otherbuf (other-buffer (current-buffer) t))
(otherwin (get-buffer-window otherbuf)))
(if otherwin
(select-window otherwin)
(message "Last buffer (%s) is not currently visible" (buffer-name otherbuf)))))
Or the shorter, and more featureful:
(defun switch-to-previous-buffer-possibly-creating-new-window ()
(interactive)
(pop-to-buffer (other-buffer (current-buffer) t)))
Here other-buffer is used to get the most recently used buffer (except current-buffer). This should work fine as long as you don't switch buffers in the windows, because then other-buffer will no longer return the buffer in the other window, but the buffer you switched from in current window.
So instead of using other-buffer lets walk the buffer-list ourself to find the best candidate:
(defun switch-to-the-window-that-displays-the-most-recently-selected-buffer ()
(interactive)
(let* ((buflist (buffer-list (selected-frame))) ; get buffer list in this frames ordered
(buflist (delq (current-buffer) buflist)) ; if there are multiple windows showing same buffer.
(winlist (mapcar 'get-buffer-window buflist)) ; buf->win
(winlist (delq nil winlist)) ; remove non displayed windows
(winlist (delq (selected-window) winlist))) ; remove current-window
(if winlist
(select-window (car winlist))
(message "Couldn't find a suitable window to switch to"))))
Hope this helps.
If the last window switch was done programmatically, then it is possible to select the previously selected window.
(defun your-function ()
(interactive)
(let ((sw (selected-window)))
(do-something-useful-and-switch-window)
(select-window sw)))
If the last window switch was done manually, then it should be possible to overload the window switching command to update a global list of window selection order, which is then used to switch back.
(defun gs/pop-to-previous-window ()
(interactive)
(let ((win (get-mru-window t t t)))
(select-window win)))

show org-mode outline up to a certain heading level

I'm making an outline for my thesis using org-mode, and I'd like to show all headings up to a certain level (e.g. all level-1 and level-2 headings).
I haven't found anything about that in the org-mode manual. Cycling shows either only level-1 headings, or all headings, which is too much information in my outline right now.
Thanks,
daniel.
Update: I found a workaround for his: set the variable org-cycle-max-level. This is a global setting, though.
Just stumbled on this question. One year later but what the heck.. There are commands for this that allows you to show headings to a certain level.
One command is C-<n> C-c tab will show subheadings up to level <n> (<n>=1,2,3...).
Another command is C-<n> S-tab which will operate on the whole buffer. It shows all headings up to level <n> (<n>=1,2,3...)
I found a solution that suits me: The command org-content shows the folder hierarchy, and giving it a numeric argument does exactly what I want: limit the maximum level shown. In my example, I wanted to show 2 levels, so I can do C-2 M-x org-content <RET>.
I also added my own command to my .emacs init file, binding that command to C-c m
(defun org-show-two-levels ()
(interactive)
(org-content 2))
(add-hook 'org-mode-hook
(lambda ()
(define-key org-mode-map "\C-cm" 'org-show-two-levels)))
If the prefix arguments from M. Kullman's answer take too much mental capacity for you (a limited resource when you are thinking hard about something else at the same time) then you can use the following functions to expand contract headings
(defvar hf-org-depth-point nil)
(defvar hf-org-depth-depth nil)
(defun hf-org-depth-increase ()
(interactive)
(hf-org-depth-incr 1))
(defun hf-org-depth-decrease ()
(interactive)
(hf-org-depth-incr -1))
(defun hf-org-depth-incr (incr)
(when (not (equal (point) hf-org-depth-point))
(setq hf-org-depth-point nil)
(setq hf-org-depth-depth 0))a
(setq hf-org-depth-point (point))
(setq hf-org-depth-depth (max (+ hf-org-depth-depth incr) 0))
(hide-subtree)
(show-children hf-org-depth-depth))
```
I am way late to the party, but let us add a simple way for posterity. Simply use Cycle Global Visibility (<backtab>). If your headings are open, it will close them. However, if you apply it repeatedly with all headings collapsed, they will open to the level you want.
I use it from the keyboard by <SHIFT>+<TAB>. You can also find it in the Org menu (in Emacs) under Show/Hide -> Cycle Global Visibility ()

How to automatically save files on lose focus in Emacs

Is it possible to configure Emacs, so that it saves all files when the emacs window loses
focus?
I added focus hooks to Gnu Emacs 24.4.
They are called focus-in-hook and focus-out-hook.
You can add
(defun save-all ()
(interactive)
(save-some-buffers t))
(add-hook 'focus-out-hook 'save-all)
to your .emacs file and it should save all files on loss of focus.
I use this, it will only work if emacs is running under X (like it probably would in something like ubuntu).
(when
(and (featurep 'x) window-system)
(defvar on-blur--saved-window-id 0 "Last known focused window.")
(defvar on-blur--timer nil "Timer refreshing known focused window.")
(defun on-blur--refresh ()
"Runs on-blur-hook if emacs has lost focus."
(let* ((active-window (x-window-property
"_NET_ACTIVE_WINDOW" nil "WINDOW" 0 nil t))
(active-window-id (if (numberp active-window)
active-window
(string-to-number
(format "%x00%x"
(car active-window)
(cdr active-window)) 16)))
(emacs-window-id (string-to-number
(frame-parameter nil 'outer-window-id))))
(when (and
(= emacs-window-id on-blur--saved-window-id)
(not (= active-window-id on-blur--saved-window-id)))
(run-hooks 'on-blur-hook))
(setq on-blur--saved-window-id active-window-id)
(run-with-timer 1 nil 'on-blur--refresh)))
(add-hook 'on-blur-hook #'(lambda () (save-some-buffers t)))
(on-blur--refresh))
Not sure if this is what you want.
(defun dld-deselect-frame-hook ()
(save-some-buffers 1))
(add-hook 'deselect-frame-hook 'dld-deselect-frame-hook)
From: http://www.dribin.org/dave/blog/archives/2003/09/10/emacs/
EDIT: It only seems to work in XEmacs
[…] the feature I am talking about is from
Scribes. It is very convient when
editing html and the like, you don't
have to press C-x C-s anymore, you
just change the window and check your
browser.
In that case, instead of switching to the browser application, order Emacs to load the browser application (C-c C-v or M-x browse-url-of-buffer). With this method, you can write your own function that saves the buffer and then brings the browser up, like:
(defun my-browse-url-of-buffer ()
"Save current buffer and view its content in browser."
(interactive)
(save-buffer)
(browse-url-of-buffer))
And hook it to a convenient binding.
Or you can still use the html-autoview-mode that each time you saves the buffer, automatically loads the file into your favorite browser.
You can use `auto-save-interval' to save every n characters you type. Mine is set to 100. So about every 2-3 lines of code, maybe?
auto-save-interval is a variable
defined in `C source code'. Its value
is 100
Documentation:
*Number of input events between auto-saves. Zero means disable
autosaving due to number of characters
typed.
You can customize this variable.
This doesn't answer your original question; it's just a way to achieve something similar.