Emacs continuation lines before screen edge - emacs

I would like Emacs to display a line continuation at a specified column -- say column 80 -- rather than at the edge of the screen. Is this possible? I know that I can use visual-line-mode and possibly configure that to soft-break the lines at some pre-defined width, but I prefer working on logical lines and would therefore prefer not to use visual-line-mode.

Setting the window margins more or less does this, but it's going to cause some problems (at minimum, it can interfere with splitting windows).
If you want to dig deeper, this might be a starting point.
(defvar my-right-margin-column 80
"Used by `my-right-margin-update'.")
(defun my-right-margin-update ()
"Make the right margin occupy all space beyond `my-right-margin-column'.
See `my-right-margin-auto-update'."
(set-window-margins
nil 0 (max 0 (- (+ (window-text-width)
(or (cdr (window-margins)) 0))
my-right-margin-column)))
(set-window-parameter nil 'min-margins '(0 . 0)))
(defun my-right-margin-auto-update ()
"Configure buffer-local `window-configuration-change-hook'."
(add-hook 'window-configuration-change-hook
#'my-right-margin-update nil :local))
(add-hook 'text-mode-hook #'my-right-margin-auto-update)

Related

Centering text in Emacs buffer

I'm trying to define a function which will keep my fixed width body in Emacs centered in the buffer rather than aligned to the left side. In particular I want this to be buffer-local, and I'm trying to do this by locally setting left- and right-margin-width.
This works fine by itself, but I also want a hook to adjust the margins when the window size changes, and this is causing problems for me. Here's the code (adapted from https://stackoverflow.com/a/23731757/3822233):
(defun center-body ()
(let* ((max-text-width 70)
(margin (max 0 (/ (- (window-width) max-text-width) 2))))
(setq-local left-margin-width margin)
(setq-local right-margin-width margin)
(set-window-buffer nil (current-buffer))))
(defun uncenter-body ()
(setq-local left-margin-width 0)
(setq-local right-margin-width 0)
(set-window-buffer nil (current-buffer)))
(defun body-center-mode ()
(interactive)
(if (= left-margin-width 0)
(progn
(center-body))
(add-hook 'window-configuration-change-hook 'center-body nil 1))
(uncenter-body)
(remove-hook 'window-configuration-change-hook 'center-body 1)))
When the add-hook and remove-hook lines are removed, everthing's ok. But as soon as I call the add-hook I get a nesting exceeds max-lisp-eval-depth error.
I don't really understand lisp so I'm having trouble debugging this.
Most likely set-window-buffer will end up running window-configuration-change-hook.
So I'd recommend you only call set-window-buffer when left-margin-width or right-margin-width actually changes.
But in any case you'll get into trouble as soon as your buffer gets displayed in 2 or more windows of different width.
So the better answer is to not use left-margin-width and right-margin-width but instead to use set-window-margins.
Not only this will not call window-configuration-change-hook and hence won't suffer from this infinite recursion problem, but on top of that, it will happily adjust the margins differently for every window that displays the buffer, depending on those windows's widths.

Emacs: prevent cursor movement when scrolling off of the screen

I am reviewing some code in emacs that has a series of for loops that span several pages. The indentations done by the author are poor so it is not easy to tell where loops begin and end. I am using the highlight parenthesis mode to find where loops. However, it is often the case that the loop covers a few pages of code. Thus whenever I scroll to see more code the colors of the parenthesis change and I can't find where the loop ends. I've read other's posts about using mark and multi-window scrolling but this doesn't seem to work in my situation. Also locking the cursor position on the screen isn't helpful since it still moves with the screen. Any suggestions or advice?
You can use forward-list (C-M-n) and backward-list (C-M-p) to navigate forward and backward over a parenthetical group. (Also try forward-sexp (C-M-f) and backward-sexp (C-M-b)).
Check out the EmacsWiki on Navigating Parentheses, the Emacs manual node on matching paretheses, and this SO thread on matching brackets.
Here is a modification of https://github.com/nschum/highlight-parentheses.el/blob/master/highlight-parentheses.el, which will permit you to scroll up or down without deleting the overlays. You can add additional this-command statements to suit your needs.
(defun hl-paren-highlight ()
"Highlight the parentheses around point."
(unless
(or
(eq this-command 'mwheel-scroll)
(eq this-command 'scroll-up)
(eq this-command 'scroll-down))
(unless (= (point) hl-paren-last-point)
(setq hl-paren-last-point (point))
(let ((overlays hl-paren-overlays)
pos1 pos2
(pos (point)))
(save-excursion
(condition-case err
(while (and (setq pos1 (cadr (syntax-ppss pos1)))
(cdr overlays))
(move-overlay (pop overlays) pos1 (1+ pos1))
(when (setq pos2 (scan-sexps pos1 1))
(move-overlay (pop overlays) (1- pos2) pos2)
))
(error nil))
(goto-char pos))
(dolist (ov overlays)
(move-overlay ov 1 1))))))
I think you're looking for the wrong solution.
Place your cursor on loops starting parenthesis or curly bracket and press C-M-n This runs the command forward-list which will jump your cursor to the matching end paren or curly brace.
Open the buffer, move to the starting paren, use C-x 3 to split the window in half, move to the new window, and use forward-list now you should have the starting paren in view on the left and the ending paren in view on the right.
Alternatively, use hideshow to collapse blocks of code inside the loop to shrink the size and potentially fit it on one screen.
Also look into follow-mode this will allow you to view one buffer in multiple windows continuously effectively doubling or tripling the number of continuous lines of code you can see. This will work with show-paren-mode.
Also if the indentation is really so terrible, run mark-whole-buffer and indent-region to fix it up.

Scroll-down all the way without error "beginning of buffer"

I'm looking for some assistance, please, to programmatically scroll a particular window to the very beginning without incurring an error beginning of buffer (which necessarily halts the function). The current (point) is within the visible window, but near the bottom. The number of lines to scroll-down may vary, so I cannot say for sure exactly how many is needed -- but the very beginning of the buffer is what I'm looking for. I don't think (save-excursion (goto-char (point-min))) will do what I want.
scroll-down does not have an argument for a specific window, so if the solution to this question could also include an example to perform the action with a specific window (without switching to it), that would be greatly appreciated. In other words, I'd like to be in a different window while this function is going on in the target window.
(when
(not (pos-visible-in-window-p (point-min)
(get-buffer-window calendar-buffer (selected-frame))))
(scroll-down 20))
You can wrap scroll-down in a condition-case to regain control when an error is signaled:
(condition-case nil
(scroll-down 20)
(error nil))
I wasn't exactly sure if you wanted your last code snippet was part of the function you were referring to, but you can wrap it all in a save-selected-window:
(let ((cal (get-buffer-window calendar-buffer (selected-frame))))
(when cal
(save-selected-window
(select-window cal)
(condition-case nil
(scroll-down 20)
(error nil)))))
EDIT: jpkotta suggested ignore-errors in the comment, which I agree looks cleaner:
(ignore-errors
(scroll-down 20))
(let ((win (get-buffer-window calendar-buffer (selected-frame))))
(when (not (pos-visible-in-window-p (point-min) win))
(set-window-start win (point-min))))
`set-window-start` is a built-in function in `C source code'.
(set-window-start WINDOW POS &optional NOFORCE)
Make display in WINDOW start at position POS in WINDOW's buffer.
WINDOW must be a live window and defaults to the selected one. Return
POS. Optional third arg NOFORCE non-nil inhibits next redisplay from
overriding motion of point in order to display at this exact start.
See also http://www.gnu.org/software/emacs/manual/html_node/elisp/Window-Start-and-End.html
See also http://www.gnu.org/software/emacs/manual/html_node/elisp/Selecting-Windows.html

How to show the whole line in the window?

I'm using Emacs 24.2 with a line-wrapping activated.
When I read log files of various simulations which contain messages like: "Error: ...some message...", I perform an incremental search: C-s error RET, C-s, C-s...
I find it very annoying that the highlighted result of the search (the word Error) is displayed at the bottom of the screen, and all the additional wrapped lines can't be seen:
I'd like to add modifications which ensure that the whole line of text will be displayed in the buffer, like this:
I found this question concerning re-centering of the search results. It seems that I could use the same defadvice statements for the search functions, but rather than re-centering the line I need just scroll the screen down by the number of wrapped parts.
How to do this?
You can use the solution on the question you reference, but changing recenter-top-bottom by this highly untested function:
(defun scroll-if-truncated()
(scroll-up
(/ (- (save-excursion
(end-of-line) (point))
(save-excursion
(beginning-of-line) (point)))
(window-body-width))))
After playing a bit with the code according to #juanleon's advice, I ended up with this:
;; Execute after each update in isearch-mode
(setq isearch-update-post-hook 'show-whole-line)
(defun show-whole-line ()
"Scroll such that the whole line (which contains the point) will be visible."
;; If it is the top part which is truncated
(if (not (pos-visible-in-window-p (line-beginning-position)))
(let
((amount
;; the required number of lines to scroll
(ceiling (/
(- (window-start)
(line-beginning-position))
(float (window-body-width))))))
;; don't scroll at all if the search result will be scrolled out
(if (< amount (/
(- (window-end)
(point) )
(float (window-body-width))))
(scroll-down amount)))
;; Else
(if (not (pos-visible-in-window-p (line-end-position)))
(let
((amount
(min
;; the required number of lines to scroll
(ceiling (/
(-
(line-end-position)
(window-end (selected-window) t))
(float (window-body-width))) )
;; however not to scroll out the first line
(/ (- (line-beginning-position) (window-start)) (window-body-width)))))
(scroll-up amount)))))
Few explanations:
Setting defadvice for isearch-forward is not enough - this function is not called again when you add chars to the search string. After a quick review of isearch.el.gz package I decided to advice to isearch-update function. This also eliminates the need of adding a separate advice for isearch-repeat-forward and etc. Later I noticed that there is a predefined hook in isearch-update, therefore no need for defadvice here.
show-whole-line function checks whether the beginning of the current line is visible. If not, it scrolls-down to show the beginning of the line, unless this scrolling will result in hiding the search match itself.
If the beginning of the line is visible, show-whole-line checks whether the end of the line is also visible. If not, it scrolls-up to show the end of the line, unless this scrolling will result in hiding the beginning of the line. I prefer to be able to see the beginning of the line.
This function and a hook work pretty well, but there is one annoying thing about it: the function is called when you initially press C-s (before you typed in any search string). This means that if the point is at a line which has its beginning or end out of the window, a simple invocation of C-s will result in scrolling in some manner.
While not critical at all, I'll be glad to hear suggestions how to remove the above side effect.
You should be able to get the behavior you want using variables scroll-conservatively and scroll-margin, in particular the latter.

Detecting Emacs window is already split

How do I detect that an Emacs window has already been split?
In my .emacs file, I have:
(when (display-graphic-p)
(set-frame-size (selected-frame) 166 85)
(split-window-horizontally))
which allows me to have two buffers side-by-side, each exactly 80 chars wide.
Every once in a while I change my .emacs file and want to reload it in place, so I run M-x load-file on my .emacs file and that window I'm in gets re-split.
Is there some sort of command I can call to check if the frame has already been split and only call (split-window-horizontally) if it hasn't? Something like:
(when (window-is-root)
(split-window-horizontally))
or
(when (not (window-is-already-split))
(split-window-horizontally))
window-list will return you a list of the windows (for the current frame), so you should be able to do:
(when (= (length (window-list)) 1)
(split-window-horizontally))
Check out the relevant documentation for windows.
This is a meaningless questions, windows are not split.
Yes, there are functions named split-window..., but what they do is merely to reduce the size of the window, and create a new one in the space thus freed.
You cannot just use (= 1 (length (window-list))) since you have at least one window per frame (not counting the simili-window of the minibuffer).
You could try:
(< (length (frame-list)) (length (window-list)))
but that doesn't tell you if there are several windows in the selected frame, which is what you are actually asking, since obviously it could be another frame that contains several windows.
So if you ask the question CORRECTLY, "how can I know whether the selected frame contains more than one window", you can easily find the answer:
(require 'cl)
(defun complement (fun)
(byte-compile `(lambda (&rest args) (not (apply ',fun args)))))
(defun* more-than-one-window-in-frame-p (&optional (frame (selected-frame)))
(< 1 (length (remove* frame (window-list)
:key (function window-frame)
:test (complement (function eql))))))