Setting Emacs to Split Buffers Side-by-Side - emacs

A lot of Emacs functions automatically split the screen. However, they all do so such that the windows are one on top of the other. Is there any way to make them split such that they are side-by-side by default instead?

(setq split-height-threshold nil)
(setq split-width-threshold 0)
GNU Emacs Lisp Reference Manual: Choosing Window Options

Two solutions here, use any one you like:
A: Vertically(left/right) by default:
(setq split-height-threshold nil)
(setq split-width-threshold 0)
B: Automatically split window vertically(left/right) if current window is wide enough
(defun display-new-buffer (buffer force-other-window)
"If BUFFER is visible, select it.
If it's not visible and there's only one window, split the
current window and select BUFFER in the new window. If the
current window (before the split) is more than 100 columns wide,
split horizontally(left/right), else split vertically(up/down).
If the current buffer contains more than one window, select
BUFFER in the least recently used window.
This function returns the window which holds BUFFER.
FORCE-OTHER-WINDOW is ignored."
(or (get-buffer-window buffer)
(if (one-window-p)
(let ((new-win
(if (> (window-width) 100)
(split-window-horizontally)
(split-window-vertically))))
(set-window-buffer new-win buffer)
new-win)
(let ((new-win (get-lru-window)))
(set-window-buffer new-win buffer)
new-win))))
;; use display-buffer-alist instead of display-buffer-function if the following line won't work
(setq display-buffer-function 'display-new-buffer)
Put any one in you .emacs/init.el file.
You can change the "100" to the value you like, depending on you screen.
If you got two windows in one frame, and you want to change the layout from vertical to horizontal or vice verse, here is a solution:
(defun toggle-window-split ()
(interactive)
(if (= (count-windows) 2)
(let* ((this-win-buffer (window-buffer))
(next-win-buffer (window-buffer (next-window)))
(this-win-edges (window-edges (selected-window)))
(next-win-edges (window-edges (next-window)))
(this-win-2nd
(not (and (<= (car this-win-edges)
(car next-win-edges))
(<= (cadr this-win-edges)
(cadr next-win-edges)))))
(splitter
(if (= (car this-win-edges)
(car (window-edges (next-window))))
'split-window-horizontally
'split-window-vertically)))
(delete-other-windows)
(let ((first-win (selected-window)))
(funcall splitter)
(if this-win-2nd (other-window 1))
(set-window-buffer (selected-window) this-win-buffer)
(set-window-buffer (next-window) next-win-buffer)
(select-window first-win)
(if this-win-2nd (other-window 1))))))
;; C-x 4 t 'toggle-window-split
(define-key ctl-x-4-map "t" 'toggle-window-split)
Put it in your .emacs/init.el file, Use C-x 4 t to toggle the layout of your windows.

(setq split-height-threshold 0) (setq split-width-threshold 0)
is what i had to use to get the desired behaviour (no horizontal splitting)

Sometimes we need change between Horizontal and Vertical according current display and our requirement (more lines or more columns).
I recommand the great ToggleWindowSplit, And I bind key to "C-c y"
http://www.emacswiki.org/emacs/ToggleWindowSplit

the simple answer of setting 2 variables to nil and 0 didn't work for me, so I wrote 2 simple functions: one just splits the window into NX vertical buffers and opens files named (for example) file.1 file.2 ... file.NX in each and another one does the same think, except does it in 2D (NY rows by NX columns for opening files f.1 f.2 ... f.[NX*NY]). To install, add this code to .emacs:
(defun grid-files-h (nx wx pfx)
"Using dotimes, split the window into NX side-by-side buffers of width WX and load files starting with prefix PFX and ending in numbers 1 through NX"
(let (ox fn k) ; ox is not used, but fn is used to store the filename, and k to store the index string
(dotimes (x (- nx 1) ox) ; go through buffers, x goes from 0 to nx-2 and ox is not used here
; (print x)
(setq k (number-to-string (+ x 1) ) ) ; k is a string that goes from "1" to "nx-1"
; (print k)
(setq fn (concat pfx k) ) ; fn is filename - concatenate prefix with k
; (print fn)
(find-file fn) ; open the filename in current buffer
(split-window-horizontally wx) ; split window (current buffer gets wx-columns)
(other-window 1) ; switch to the next (right) buffer
)
(setq k (number-to-string nx )) ; last (rightmost) buffer gets the "nx" file
(setq fn (concat pfx k) ) ; fn = "pfx"+"nx"
(find-file fn ) ; open fn
(other-window 1) ; go back to the first buffer
)
)
(defun grid-files-sq (ny wy nx wx pfx)
"Using dotimes, split the window into NX columns of width WX and NY rows of height WY and load files starting with prefix PFX and ending in numbers 1 through NX*NY"
(let (oy ox fn k)
(dotimes (y ny oy) ; go through rows, y goes from 0 to ny-1 and oy is not used here
(split-window-vertically wy) ; create this row
(dotimes (x (- nx 1) ox) ; go through columns, x goes from 0 to nx-2 and ox is not used here
(setq k (number-to-string (+ 1 (+ x (* y nx) ) ) ) ) ; k must convert 2 indecies (x,y) into one linear one (like sub2ind in matlab)
(setq fn (concat pfx k) ) ; filename
(find-file fn ) ; open
(split-window-horizontally wx) ; create this column in this row (this "cell")
(other-window 1) ; go to the next buffer on the right
)
(setq k (number-to-string (+ nx (* y nx) ) ) ) ; rightmost buffer in this row needs a file too
(setq fn (concat pfx k) ) ; filename
(find-file fn ) ; open
(other-window 1) ; go to next row (one buffer down)
)
)
)
and then to use the vertical one, I go to *scratch* (C-x b *scratch* RET,C-x 1), type in (grid-files-h 3 20 "file.") then C-x C-e, or if you want to test out the square qrid one, C-x 1, type in (grid-files-sq 2 15 3 20 "f.") and then C-x C-e and you should see something like
This probably can be done better/more efficiently, but it's a start and it does what I need it to do (display a bunch of sequentially named small files). Feel free to improve or reuse.

I use multiple frames (OSX windows) in emacs regularly for different projects. Here's how I setup a few frames initially split to a left and right window.
(defun make-maximized-split-frame (name)
(let (( f (make-frame (list (cons 'name name))) ))
(maximize-frame f)
(split-window (frame-root-window f) nil t)
))
(make-maximized-split-frame "DocRaptor")
(make-maximized-split-frame "Gauges")
(make-maximized-split-frame "Instrumental")

The direct answer is to press C-c 3.
It's not clear from the question if you want a permanent setting change, but I found this question looking for this answer and didn't find it. (The answer has actually been sitting in a comment for the last 11 years)

Related

Emacs insert centered comment block

I would like to create a macro for emacs that will insert a latex comment block with some centerd text like:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Comment 1 %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Comment 2 Commenttext 3 %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Is this possible in emacs-lisp?
Emacs comes with the command comment-box for this purpose. It produces centered comment boxes, although the width of the box varies depending on the content. E.g., with the region set around the following line:
This is a comment
when you call M-x comment-box the text is transformed to:
;;;;;;;;;;;;;;;;;;;;;;;
;; This is a comment ;;
;;;;;;;;;;;;;;;;;;;;;;;
I use a modifed version that places the comment box around the current line if the region isn't active, and then steps out of the comment afterwards. It also temporarily reduces the fill-column, so the comment box is not wider than your longest line:
(defun ty-box-comment (beg end &optional arg)
(interactive "*r\np")
(when (not (region-active-p))
(setq beg (point-at-bol))
(setq end (point-at-eol)))
(let ((fill-column (- fill-column 6)))
(fill-region beg end))
(comment-box beg end arg)
(ty-move-point-forward-out-of-comment))
(defun ty-point-is-in-comment-p ()
"t if point is in comment or at the beginning of a commented line, otherwise nil"
(or (nth 4 (syntax-ppss))
(looking-at "^\\s *\\s<")))
(defun ty-move-point-forward-out-of-comment ()
"Move point forward until it's no longer in a comment"
(while (ty-point-is-in-comment-p)
(forward-char)))
Here's a yasnippet that you can use:
# -*- mode: snippet -*-
# name: huge_comment
# key: hc
# --
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%${1:$(repeat-char (- 33 (/ (length yas-text) 2)) " ")}$1${1:$(repeat-char (- 74 (length yas-text) (- 33 (/ (length yas-text) 2))) " ")}%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
$0
How to use it: type hc, call yas-expand and start typing the text. It will re-center itself
automatically.
This snippet will work from latex-mode or text-mode. I've noticed however a bug that
messes up the cursor position if you're using AUCTeX. In that case, you can momentarily switch
to text-mode.
The question was whether it is possible in emacs-lisp. Yes it is. There are several ways to do it.
I will show one way where you can also comment several lines of text.
Maybe, in the first line there is the title of the part of text and in the second one there is the author of this part.
A better way would be to advice LaTeX-indent-line function. This way you could edit the comment text and re-indent. When I find time I will show you also this variant.
Usage: Write your comment as clear text. Mark text as region with the mouse and then run the following command.
(defun LaTeX-centered-comment (b e)
"Convert region into centered comment."
(interactive "r")
(let* ((n (count-lines b e)))
(goto-char b)
(beginning-of-line)
(insert-char ?% fill-column)
(insert ?\n)
(setq b (point))
(center-line n)
(goto-char b)
(loop for i from 1 upto n do
(replace-region (point) (+ (point) 3) "%%%")
(end-of-line)
(insert-char ?\ (max 0 (- fill-column (- (point) (line-beginning-position)) 3)))
(insert "%%%")
(forward-line))
(insert-char ?% fill-column)
(insert ?\n)
))

Resize occur window in Emacs

When entering occur mode for example (occur "test") the frame splits into two windows as shown below:
As seen the Occur buffer is taking up too much space on the frame, since there is only two matches (for the text "test"). I would like to shrink that window accordingly.
I tried the following code:
(defun test-occur ()
(interactive)
(occur "test")
(save-window-excursion
(other-window 1)
(let (( win (selected-window))
(n (count-lines (point-min) (point-max)))
(h (window-body-height)))
(let ((delta (- (- h n) 3)))
(window-resize win (- 0 delta) nil)))))
But it does not work (nothing happens with the Occur window)..
Just do this:
(add-hook 'occur-hook
(lambda ()
(save-selected-window
(pop-to-buffer "*Occur*")
(fit-window-to-buffer))))

In split window emacs, how to search the "other buffer first line" for ":" then shift the border of the original buffer to that point

I use blame-mercurial using the monky.el package.
In a split window, when activating blame the results come up in the other window with info about the line changed (author/changeset/date:).
I would like to have a command that searches the first line of the "result" buffer, get to where the mark ":" is and shift the border of the original buffer up till that point.
Basically, if the borders of both windows are:
| ...... | ...... |
Before executing the command:
|author 4543 11-27-2013: int x; | int x; |
After executing the command:
|author 4543 11-27-2013:| int x; |
The reason for this is I would like to keep the coloring of data types/functions...etc while seeing who last changed these source file lines.
In the blame resulted file, when the lines are proceeded with author changeset date. they loose their coloring.
So I want to use the info for each line from the blame buffer "side by side" with the original fontified file.
I also can't use a fixed window border shift value, because depending on the author(s) name length for each file the position of ":" will change accordingly.
I have modified the last version at
"Mirroring location in file in two opened buffers side by side"
such that the following code makes sense. If you run the code below and then switch on sync-window-mode for the mercury-blame buffer then isearch will have the desired effect.
(defun mercury-blame-resize ()
"Resize mercury blame window to blame string at point only."
(interactive) ;; for debugging
(window-resize (selected-window)
(- (save-excursion
(beginning-of-line)
(skip-chars-forward "^:\n"))
(window-width) -1)
'horizontal 'ignore-fixed-size))
(add-hook 'sync-window-master-hook 'mercury-blame-resize)
(add-hook 'sync-window-mode-hook '(lambda ()
(setq-local isearch-update-post-hook #'(lambda () (set-window-hscroll (selected-window) 0)))))
Version for emacs 23:
(defvar mercury-blame-resize-min 5)
(defun mercury-blame-resize ()
"Resize mercury blame window to blame string at point only."
(interactive) ;; for debugging
(save-excursion
(beginning-of-line)
(let ((n (skip-chars-forward "^:\n")))
(when (looking-at ":")
(condition-case err
(enlarge-window (- (max mercury-blame-resize-min n)
(window-width) -1)
'horizontal)
(error))))))
(add-hook 'sync-window-master-hook 'mercury-blame-resize)
(add-hook 'sync-window-mode-hook '(lambda ()
(set (make-local-variable 'isearch-update-post-hook) #'(lambda () (set-window-hscroll (selected-window) 0)))))
Helper for testing (without mercury):
(loop for i from 1 upto 100 do
(loop for j from 0 upto (random 20) do
(insert (+ 32 (random 20))))
(insert ":\n"))
EDIT: In version for emacs 23: Only re-size mercurity blame buffer when there is a ":" on the current line.

Move point to next tab-stop in Emacs

I am trying to create a major mode in Emacs. In this mode the tab key should work as follows:
I define a number, e.g. (setq my-tab-stop 10)
When I hit the tab key the point moves to next column that is divisible by my-tab-stop, i.e.
If current-column is equal to 0,1,2,..,9, the point should move to column 10,
If current-column is equal to 10,11,12,..,19, the point should move to column 20, and so on..
(Note: no spaces or tabs should be inserted (like in tab-to-tab-stop), only the point moves, however, if the point moves beyond the length of the current line, spaces should be inserted to make line longer)
How can this be done?
Here's the code:
(defvar tabtab-val 10)
(defun tabtab/forward-char (n)
(let ((space (- (line-end-position) (point))))
(if (> space tabtab-val)
(forward-char n)
(move-end-of-line 1)
(insert (make-string (- n space) ? )))))
(defun tabtab ()
(interactive)
(let ((shift (mod (current-column) tabtab-val)))
(tabtab/forward-char (- tabtab-val shift))))
Just bind a key to move-to-tab-stop.
You can trivially configure the tab stop list for fixed intervals of N columns with:
(setq tab-stop-list (number-sequence N MAX N))

Permanently change the state of abbreviated display of a piece of code?

In *scratch* buffer in Emacs Lisp after you evaluated an expression that evaluates to a complex Lisp form, that form is "abbreviated", i.e. some long lists or its inner parts are replaced by ellipses. Looks something like:
(let* ((--3 (make-hash-table)) d c (--5 (let ... ... ...)) (--6 0) (--0 (make-
hash-table)) b a (--1 0) --7) (catch (quote --2) (maphash (lambda ... ... ...
... ... ... ...) --0)) (nreverse --7))
vs expanded version:
(let* ((--3 (make-hash-table)) d c (--5 (let (--4) (maphash (lambda (k v)
(setq --4(cons k --4))) --3) (nreverse --4))) (--6 0) (--0 (make-hash-table))
b a (--1 0) --7) (catch (quote --2) (maphash (lambda (k v) (when (or (> --6
150) (> --1 100)) (throw (quote --2) nil)) (setq a k b v) (setq c (car --5) d
(gethash (car --5) --3) --5 (cdr --5)) (incf --6) (setq --7 (cons (list (cons
a b) (cons c d)) --7)) (message "a: %s, b: %s, c: %s, d: %s" a b c d)) --0))
(nreverse --7))
If I press RET in the expanded or collapsed state, it toggles the state back. Obviously, my first reaction is to try to format the output, so I press RET! And then it will either collapse or expand, depends on whichever state it was in. If I copy and paste the whole thing, then it is treated as normal text, but is there a faster way of doing it? I.e. I would like to permanently expand it, w/o having to copy-paste.
I couldn't find the function which toggles the state (perhaps I'm calling it incorrectly). It took me a while to realize it was possible to toggle it anyway (yeah, it displays that in a tooltip, but who uses mouse in Emacs?).
Also, I, in general, like the idea, is it possible to apply it to other languages too? Where can I read more about this feature?
Two variables control the print out of results of eval-expression. in the *scratch* buffer:
eval-expression-print-length
eval-expression-print-level
You could set those to nil and the result would always be expanded.
If you just want the RET to switch to the fully expanded (and not to toggle), you can use this advice to strip the text properties which enable the toggling of display state:
(defadvice last-sexp-toggle-display (after last-sexp-toggle-display-only-long-form activate)
"After the function is called, check to see if the long form had been displayed, and if so, remove property enabling toggling"
(save-restriction
(widen)
(let ((value (get-text-property (point) 'printed-value)))
(when value
(let ((beg (or (previous-single-property-change (min (point-max) (1+ (point)))
'printed-value)
(point)))
(end (or (next-single-char-property-change (point) 'printed-value) (point)))
(standard-output (current-buffer))
(point (point)))
(if (< (length (nth 1 value)) (length (nth 2 value)))
(remove-text-properties beg end '(printed-value))))))))