emacs split into 3 even windows - emacs

Quick question: How do I specify the number of characters in a split window? C-x-3 Splits my window into two windows evenly, but a subsequent split will split one of the windows in half. I'd like 3 equal sized windows. The documentation says that I should be able to specify the number of characters for the left buffer as a parameter, but I cant seem to get that to work. Any ideas for syntax?
Thanks.

C-x 3 twice followed by C-x + to equally size all windows.

To specify the number of characters in the split window, do:
C-u number-of-characters C-x 3

I have the following in my .emacs:
(defadvice split-window-horizontally (after rebalance-windows activate)
(balance-windows))
(ad-activate 'split-window-horizontally)
this makes emacs call rebalance-windows (which is what C-x + is bound to by default) after every resize. It's not what I want all the time, but I want it much more often than the default behavior.

add in .emacs. I mapped to C-x 4, but anyone has a better idea?
(defun split-3-windows-horizontally-evenly ()
(interactive)
(command-execute 'split-window-horizontally)
(command-execute 'split-window-horizontally)
(command-execute 'balance-windows)
)
(global-set-key (kbd "C-x 4") 'split-3-windows-horizontally-evenly)

(defun wenshan-split-window-vertical (&optional wenshan-number)
"Split the current window into `wenshan-number' windows"
(interactive "P")
(setq wenshan-number (if wenshan-number
(prefix-numeric-value wenshan-number)
2))
(while (> wenshan-number 1)
(split-window-right)
(setq wenshan-number (- wenshan-number 1)))
(balance-windows))
This function can be used to split the current window into N windows, you can type "C-u 3 M-x wenshan-split-window-vertical" to achieve what you want.

If you use evil do
C-x 3 and then C-w =

I liked #quodlibetor's solution, but it didn't work as written. This works for me (emacs 24.5)
(advice-add 'split-window-right :after #'balance-windows)

One of the problems with many of the answers that use balance-windowshere is that they may not allow the window to split due to window-min-width or split-width-threshold even if everything would be fine after rebalancing. For example, I don't want windows less than 100 characters wide, but if I split my screen once I get two windows that are 160 characters wide and can't split again without resizing one of the windows. I haven't figured out how to determine whether a split is good yet, so I'll probably just dynamically bind those values to 0 while splitting, and maybe do a window-configuration-to-register beforehand just in case so that I can recover the old layout when things go wrong.

Here is my solution, hope it helps:
(defun split-vertical-evenly ()
(interactive)
(command-execute 'split-window-vertically)
(command-execute 'balance-windows))
(global-set-key (kbd "C-x 2") 'split-vertical-evenly)
(defun split-horizontal-evenly ()
(interactive)
(command-execute 'split-window-horizontally)
(command-execute 'balance-windows))
(global-set-key (kbd "C-x 3") 'split-horizontal-evenly)

Related

Control Emacs behavior when splitting windows

I would like to customize the behavior when I split windows in Emacs:
I am always splitting because I want to view a separate buffer side-by-side with the one I'm currently editing.
I use electric-buffer-list (bound to C-x C-b) to navigate buffers.
I end up doing all of the following separately:
C-x 3 to split horizontally.
C-x o to switch to the other window.
C-x C-b to invoke electric-buffer-list so I can select the buffer I want to view.
It seems like I should be able to write an Elisp function that will do all of this when I press C-x 3.
I found this post which describes the focus switching part of the behavior that I want, but I don't understand how to extend that answer to achieve all of what I'm trying to do.
Edit: After reviewing #lawlist's post and debugging my syntax, I think I want to do something like this:
(defun split-right-and-buffer-list ()
(interactive)
(split-window-horizontally)
(other-window 0)
(electric-buffer-list 0))
(global-set-key (kbd "C-x 3") 'split-right-and-buffer-list)
This does everything I want, except that the buffer list that comes up only lists the current buffer, instead of the normal list of all buffers that I get when I invoke electric-buffer-list from its key binding.
With some very small modifications the function you came up with will do what you want:
(defun split-right-and-buffer-list ()
(interactive)
(split-window-horizontally)
(other-window 1)
(electric-buffer-list nil))
(global-set-key (kbd "C-x 3") 'split-right-and-buffer-list)
Passing 1 instead of 0 as an argument to other-window causes Emacs to select the new window created as a result of calling split-window-horizontally.
Passing nil instead of 0 as an argument to electric-buffer-list causes Emacs to show all buffers, not just file-visiting ones.
The thing that can trip you up here is that this isn't mentioned in the documentation for electric-buffer-list (which doesn't include any information about the ARG it takes). But when you look at the source code of this command, you'll notice that it simply passes the value of the argument on to a function called list-buffers-noselect (and doesn't use it for anything else). The documentation of this function contains the missing piece of information mentioned above.
If you do not mind having custom commands to do what you want try the following functions
(require 'ido)
(defun my-split-window-open-buffer-right (buffer)
(interactive (list (ido-read-buffer "Please select a buffer: ")))
(select-window (split-window-right))
(switch-to-buffer buffer))
(defun my-split-window-open-buffer-below (buffer)
(interactive (list (ido-read-buffer "Please select a buffer: ")))
(select-window (split-window-below))
(switch-to-buffer buffer))
Bind them to keys of you liking. I would prefer this over redefining/advising functions I have not written.

Is there a better way to switch between multiple windows in emacs gdb besides C-x-o?

I'm using gdb-many-windows, which contains five windows to switch between. Is there a shortcut I can use to get to a specific window?
You probably already know that C-x o gets you to the next window. You can extend this to go to any arbitrary window with C-u <windowoffset> C-x o.
So, you can use C-u 2 C-x o to switch to the second window ahead of your current one.
This wraps around the window list (so in your case of 5 windows you could do C-u 4 c-x o to go back one.
You can also use negative numbers as well to go backwards.
Lastly, it takes a bit more setup, but Thomas's suggestion to use WindMove is very useful. It wasn't configured by default for me to any useful key binding. I add the following snippet to my (mac) .emacs file, whch lets me switch windows via control-arrow (you will need to reload .emacs by starting up or via 'M-x load-file')
(global-set-key (kbd "M-[ 5 d") 'windmove-left)
(global-set-key (kbd "M-[ 5 c") 'windmove-right)
(global-set-key (kbd "M-[ 5 a") 'windmove-up)
(global-set-key (kbd "M-[ 5 b") 'windmove-down)
Some people find WindMove more convenient than C-x o. It allows you to navigate between windows using Shift + arrow keys.
Possibly useful links:
http://www.emacswiki.org/emacs/WindowNumberingMode
http://www.emacswiki.org/emacs/NumberedWindows
Edit: If you decide to use WindowNumberingMode (that's what I use) you might find it useful to pin buffers to windows (so, for instance, Meta-1 switches to the buffer you expect it to switch to, not just the first window). One way of pinning is described in Pin Emacs buffers to windows (for cscope).
Window switching is so important in emacs, I have these settings.(Still feel these are not good enough)..
may help someone else..
(global-set-key "\M-t" 'other-window) ;; was transpose words
(global-set-key (kbd "C-x O") (lambda () (interactive) (other-window -1))) ;; back one
(global-set-key (kbd "C-x C-o") (lambda () (interactive) (other-window 2))) ;; forward t
I use switch-window.el.
You can choose a window by visual way with 'switch-window'.
Image of using switch-window

How can I switch focus after buffer split in emacs?

I would like that after splitting the window (C-x 3 or C-x 2) to be able to automatically get to cursor in the new opened buffer (the other than the current). How can I achieve this behavior ?
You can switch between buffers with C-x o. As to do that automatically I don't think there is an existing command for that.
You can do it like this:
(global-set-key "\C-x2" (lambda () (interactive)(split-window-vertically) (other-window 1)))
(global-set-key "\C-x3" (lambda () (interactive)(split-window-horizontally) (other-window 1)))
In Emacs 24.3.1 it works if you change the argument 1 for 0.
!!!DO NOT USE THIS ANSWER!!! -- as pointed out in the comments, advising split-window can lead to undesired side-effects.
I recommend Bozhidar Batsov's answer instead.
Put the following in your .emacs file:
(defadvice split-window (after move-point-to-new-window activate)
"Moves the point to the newly created window after splitting."
(other-window 1))
As well as splitting the frame manually with C-x 2 or C-x 3, buffers are also automatically "popped-up" some times. These are also not selected/active by default.
This can be fixed by changing the function used to split a window. It's set to split-window-sensibly by default, but you can set it to your own function that calls split-window-sensibly and then selects the buffer.
Unfortunately, though, this has the side-effect of selecting the *Completions* buffer when you hit TAB in the minibuffer. So, it's worth checking to see if the minibuffer is active and not switching in this case. I'd bet there are other such undesirable scenarios as well. I'll try to update this post as and when I find them.
;; after splitting a frame automatically, switch to the new window (unless we
;; were in the minibuffer)
(setq split-window-preferred-function 'my/split-window-func)
(defun my/split-window-func (&optional window)
(let ((new-window (split-window-sensibly window)))
(if (not (active-minibuffer-window))
(select-window new-window))))
(Works with Emacs 24.5.1.)
My thought of when you would want to follow the window after a split-window was when it had the same buffer like in the following code:
(defun split-window--select-window (orig-func &rest args)
"Switch to the other window after a `split-window'"
(let ((cur-window (selected-window))
(new-window (apply orig-func args)))
(when (equal (window-buffer cur-window) (window-buffer new-window))
(select-window new-window))
new-window))
(advice-add 'split-window :around #'split-window--select-window)
Simple
C-x o will help you switch to the "other" buffer.

By Emacs, how to join two lines into one?

I am new to Emacs. I have googled this but no good answer there. One of them is
Ctrl-n Ctrl-a Backspace
This works but is stupid. Is there a quick and simple way to join a block of lines into a single line?
Actually, I can use Esc-q to auto-fill a paragraph now, but how could I get it to revert without UNDO?
Place point anywhere on the last line of the group of lines that need joining and call
M-^
repeatedly until all the lines are merged.
Note: It leaves one space between all of the now joined lines.
M-x join-line will join two lines. Just bind it to a convenient keystroke.
Multiple Cursors combined with M-^ will collapse all selected lines into one with all extraneous white-space removed.
For example to select an entire buffer, invoke multiple cursors mode, collapse into one line, and then disable multiple cursors mode:
C-x h
M-x mc/edit-lines
M-^
C-g
The Emacs conventional name for "join" is "fill". Yes, you can join
two lines with M-^ -- and that's handy -- but more generally you'll
want to join n lines. For this, see the fill* commands, such as
fill-region, fill-paragraph, etc.
See this for more info
on selecting things which can then be filled.
Also, you can join multiple lines with M-^ by selecting those lines first. (Note that the universal argument does not work with this.)
Just replace newlines with nothing.
I like the way Sublime text Join line with Command J so I do it this way:
(defun join-lines (arg)
(interactive "p")
(end-of-line)
(delete-char 1)
(delete-horizontal-space)
(insert " "))
You could define a new command for this, temporarily adjusting the fill width before using the the Esc-q command:
;; -- define a new command to join multiple lines together --
(defun join-lines () (interactive)
(setq fill-column 100000)
(fill-paragraph nil)
(setq fill-column 78)
)
Obviously this only works, if your paragraph has less than 100000 characters.
I use the following function and bind it to 'M-J'.
(defun concat-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space))
If you prefer to keep your cursor position, you can use save-excursion.
The most simplest way ever:
Select paragraph/lines by M-h or C-SPC
Press M-q
Witness the Emagics (Emacs Magic)!!
Because join-line will left one space between two lines, also it only support join two lines. In case of you want to join plenty of lines without one space left, you can use "search-replace" mode to solve, as follows:
C-%
Query: input C-q C-j Enter
Replace: Enter
Run the replacement. Enter
Done.
Two ways come to mind:
Once you think of it, the most obvious (or at least easiest to remember) way is to use M-q format-paragraph with a long line length C-x-f 1000.
There is also a built-in tool M-^ join-line. More usefully, if you select a region then it will combine them all into one line.
"how could I get it to revert without UNDO?":
(defun toggle-fill-paragraph ()
;; Based on http://xahlee.org/emacs/modernization_fill-paragraph.html
"Fill or unfill the current paragraph, depending upon the current line length.
When there is a text selection, act on the region.
See `fill-paragraph' and `fill-region'."
(interactive)
;; We set a property 'currently-filled-p on this command's symbol
;; (i.e. on 'toggle-fill-paragraph), thus avoiding the need to
;; create a variable for remembering the current fill state.
(save-excursion
(let* ((deactivate-mark nil)
(line-length (- (line-end-position) (line-beginning-position)))
(currently-filled (if (eq last-command this-command)
(get this-command 'currently-filled-p)
(< line-length fill-column)))
(fill-column (if currently-filled
most-positive-fixnum
fill-column)))
(if (region-active-p)
(fill-region (region-beginning) (region-end))
(fill-paragraph))
(put this-command 'currently-filled-p (not currently-filled)))))
(global-set-key (kbd "M-q") 'toggle-fill-paragraph)
From EmacsWiki: Unfill Paragraph
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
A basic join of 2 lines:
(delete-indentation)
I like to line below to be joined to the current without moving the cursor:
("C-j" .
(lambda (iPoint)
"Join next line onto current line"
(interactive "d")
(next-line)
(delete-indentation)
(goto-char iPoint)))
This one behaves like in vscode. So it add space only if join line consisted something else than whitespace. And I bind it to alt+shift+j.
Shorter version based on crux-top-join-line:
(global-set-key (kbd "M-J") (lambda () (interactive) (delete-indentation 1)))
Longer version based on https://stackoverflow.com/a/33005183/588759.
;; https://stackoverflow.com/questions/1072662/by-emacs-how-to-join-two-lines-into-one/68685485#68685485
(defun join-lines ()
(interactive)
(next-line)
(join-line)
(delete-horizontal-space)
(unless (looking-at-p "\n") (insert " ")))
(global-set-key (kbd "M-J") 'join-lines)

How to scroll line by line in GNU Emacs?

To put it simply, I'm trying to get scrolling in emacs like in vim and most other editors; when I'm for example, two lines from the bottom/top, and I press down/up (Ctrl-p,n, ↑,↓) it goes only one line up or down, not half the screen.
See some of the suggestions on the Emacs Wiki:
Emacs Wiki: Smooth Scrolling
(setq scroll-step 1
scroll-conservatively 10000)
If you want to position the screen exactly, you can use Ctrl-L.
By default it positions the current line in the middle of the screen.
ESC 0 Ctrl-L positions the current line at the top.
I'm a bit late to the party, but if you don't mind installing a package then smooth-scrolling (github, also available in MELPA) may be what you're looking for - it certainly works for me.
Once you've installed it you can pop the following in your init.el:
(require 'smooth-scrolling)
(smooth-scrolling-mode 1)
(setq smooth-scroll-margin 5)
The last line is optional; it starts scrolling near the screen edge rather than at it, so you've always got a little context around the point. Adjust to taste.
My solution is not to change Emac's default scrolling, but rather to create a key sequence command from a macro. This way you have a convenient way to scroll one line at a time when you want. Not ideal, but super easy. It just happens that M-(↓) and M-(↑) are available, so that's what I used.
This is how I did it. First, you need to record a macro for one line scrolls, up and down.
Begin macro
C-x (
Scroll down one
C-u 1 C-v
Stop macro
C-x )
For scroll up one, use
C-u 1 M-v
Next you need to name the macro.
M-x name-last-kbd-macro
Give it a name when prompted like:
down-one-line
Then just use the following to bind a key sequence to that command name:
M-x global-set-key
And upon prompting, use something like:
M-(down arrow)
Then it will ask you which command you want to bind, and you should give it the name you invented earlier, e.g., down-one-line.
Here is where I got this information. You can also find instructions below and elsewhere about adding your macro to the .emacs file.
Here for macro definition explanation
Here for how to control scrolling
I've been using these in my .emacs file since 2000.
(global-set-key (quote [M-down]) (quote View-scroll-line-forward))
(global-set-key (quote [M-up]) (quote View-scroll-line-backward))
This way, I can keep the Emacs default behavior as well as scroll one line at a time, depending on what I'm doing.
This worked till at least GNU Emacs 22. I recently upgraded to Emacs 24 and discovered that View-scroll-line-forward and View-scroll-line-backward are no longer available. After some hunting, I discovered that scroll-up-line and scroll-down-line work. So if you're using Emacs 24, you can use this.
(global-set-key (quote [M-down]) (quote scroll-up-line))
(global-set-key (quote [M-up]) (quote scroll-down-line))
I mostly skipped Emacs 23, so if that is the version you're using, you can experiment with both the above.
Note: scroll-up-line actually scrolls one line down, because the buffer is being moved one line up.
I rebind my arrow keys to perform scrolling operations.
(global-set-key [up] (lambda () (interactive) (scroll-down 1)))
(global-set-key [down] (lambda () (interactive) (scroll-up 1)))
(global-set-key [left] (lambda () (interactive) (scroll-right tab-width t)))
(global-set-key [right] (lambda () (interactive) (scroll-left tab-width t)))
Simples do this:
(global-set-key [M-up] (lambda () (interactive) (scroll-up 1)))
(global-set-key [M-down] (lambda () (interactive) (scroll-down 1)))
then meta cursor up moves up and meta cursor down moves down.
QED. Not sure what all the above people were smoking!
I have the following in my .emacs file to enable a nice ctrl-up, ctrl-down scrolling behavior. I also use this for the mousewheel.
(defun scroll-down-in-place (n)
(interactive "p")
(previous-line n)
(scroll-down n))
(defun scroll-up-in-place (n)
(interactive "p")
(next-line n)
(scroll-up n))
(global-set-key [mouse-4] 'scroll-down-in-place)
(global-set-key [mouse-5] 'scroll-up-in-place)
(global-set-key [C-up] 'scroll-down-in-place)
(global-set-key [C-down] 'scroll-up-in-place)
If you are looking for a quick way to create a scroll-like effect, enter in C-n and C-l sequentially which moves the cursor down and then centers it.
To have the "vim" scrolling put this to your .emacs file:
(defun next-line-and-recenter () (interactive) (next-line) (recenter))
(defun previous-line-and-recenter () (interactive) (previous-line) (recenter))
(global-set-key (kbd "C-n") 'next-line-and-recenter)
(global-set-key (kbd "C-p") 'previous-line-and-recenter)
Since it can be annoying to use the M-up, M-down because it interferes with the org-mode which overloads these commands. To avoid this issue I personally use those commands which combine M-page-up M-page-down". Here I defined the scroll up and down to 1 line.
;;;scroll by `number-of-lines' without the cursor attached to the screen
(global-set-key [M-prior] (lambda () (interactive) (let ((number-of-lines 1))
(scroll-down number-of-lines)
(forward-line (- number-of-lines)))))
(global-set-key [M-next] (lambda () (interactive) (let ((number-of-lines 1))
(scroll-up number-of-lines)
(forward-line number-of-lines))))
;;;scroll by `number-of-lines' with the cursor attached to the screen
(global-set-key [S-M-prior] (lambda () (interactive) (let ((number-of-lines 1))
(scroll-down number-of-lines))))
(global-set-key [S-M-next] (lambda () (interactive) (let ((number-of-lines 1))
(scroll-up number-of-lines))))
M-x customize-variable scroll-conservatively
Set it to 1.
You don't really want to do this, though.
If you don't mind using the mouse and have a scroll wheel, you can customize the variable mouse-wheel-scroll-amount by either:
C-h v mouse-wheel-scroll-amount (click on customize, change value to "Specific # of lines" 1, ApplyAndSave.)
or add to .emacs the line:
'(mouse-wheel-scroll-amount '(1 ((shift) . 1) ((meta)) ((control) . text-scale)))
There are lots of possibilities listed at
https://www.emacswiki.org/emacs/Scrolling
If you start emacs in .xsession, in my case setting scroll-conservatively to 100+ will not work, nor scroll-step 1. But if u start emacs after X, it works.
After playing a bit with the available configuration (emacs 26.3), I got to the following set of values:
(setq scroll-step 1
scroll-preserve-screen-position t
scroll-margin 10
scroll-conservatively 10
maximum-scroll-margin 0.0
scroll-up-aggressively 0.0
scroll-down-aggressively 0.0)
I believe the values for scroll-margin and scroll-conservatively do not matter much because the maximum-scroll-margin clamps them down. They just need to be equal (maybe?).
Scroll happens line by line, even on the end of the file (worst case for me). The only missing feature was that with this the margin on top and bottom are lost.
Its a compromise and, for me, smooth scrolling is worth it.