Emacs / Slime / Hard Code Vertical Split Ratio - emacs

I'm currently in mode: C-x 2
Normally, I don't care much about vertical splitting. However, I'm coding on a 13" display, which makes vertical space rather precious.
I would like some setup where when I do C-x 2, my window is not split 50/50, but rather 70/30 [this way I can send the repl to the bottom portion of the screen, and stll see quite a bit of code.]
C-h a vertical split
brings up:
split-window-vertically, table-split-call-vertically
However, I suspect there is some parameter that changes / controls the split ratio.
What emacs option tells my computer to split 70/30 rather than 50/50?
Thanks!

You can use a prefix argument to tell Emacs how many lines to give each of the two windows.
See: C-hk C-x2
or C-hf split-window-below RET
If optional argument SIZE is omitted or nil, both windows get the
same height, or close to it. If SIZE is positive, the upper
(selected) window gets SIZE lines. If SIZE is negative, the
lower (new) window gets -SIZE lines.
So you could give the upper window 20 lines and the lower window the remainder with: C-u 20 C-x2
(or M-2M-0C-x2, etc...)
And you could give the lower window 10 lines and the upper window the remainder with: C-u -10 C-x2
(or M--M-1M-0C-x2, etc...)
See How to change size of split screen emacs windows? for lots of ways to modify the size of windows after splitting.
Edit:
You can use the following function to do what you want:
(defun my-split-window-below (&optional arg)
"Split the current window 70/30 rather than 50/50.
A single-digit prefix argument gives the top window arg*10%."
(interactive "P")
(let ((proportion (* (or arg 7) 0.1)))
(split-window-below (round (* proportion (window-height))))))
(global-set-key (kbd "C-c x 2") 'my-split-window-below)
The default ratio is 70/30, but you can supply a single-digit prefix argument to specify the size of the top window in 10% increments.
If you bound this command to C-x2 then C-9C-x2 would give the top window 90% and the bottom 10%.
Edit 2: I ended up using a variation of that as my own C-x2 binding. This version defaults to a normal 50/50 split, but provides the same prefix arg functionality of the other function in case I want something different.
(defun my-split-window-below (&optional arg)
"Split the current window 50/50 by default.
A single-digit prefix argument gives the top window ARG * 10%
of the available lines."
(interactive "P")
(let* ((proportion (and arg (* arg 0.1)))
(size (and proportion (round (* proportion (window-height))))))
(split-window-below size)))

Related

Moving point to the end of the last line without reorienting the buffer

Is it possible to move point to the end of a buffer without reorienting the text around that line? This seems to be the default behaviour of goto-char. My goal is to correct a minor annoyance which places the cursor at the second last line when I press "L". I wrote a custom function to do this properly but now when I move the point to the last line the screen scrolls down half a page and it becomes the center of the buffer.
(defun cf-last-line (count) (interactive "p")
(let ((max (truncate (window-screen-lines))))
(move-to-window-line max)
(line-move (* -1 (1- count)) t t)
(beginning-of-line)))
Edit: It turns out my problem is related to the fact that the GUI shows partial lines (which may appear to be fully exposed but upon closer inspection lie just below the status bus). I suppose my question then becomes whether or not it is possible to have the point lie on such a partial line (though I suspect this is unlikely) without moving it to the center and if not whether it is possible to instead prevent the X11 frame from showing partial lines at the bottom of the window.
Solution as described by lawlist:
(setq scroll-conservatively 101)
(setq make-cursor-line-fully-visible nil)

How select a rectangle in emacs

In Notepad++, you can press Alt-LeftMouseClick-Drag to select a rectangular region.
How do I do this in emacs (windows) ?
I tried the methods in http://www.emacswiki.org/emacs/RectangleCommands but
my selection happens as a regular region instead of rectangular shape:
http://i.stack.imgur.com/tBMBN.png
I also tried enabling/disabling cua mode.
In Emacs 24.4 and greater, C-x SPC is bound to rectangle-mark-mode which selects a rectangle visually.
http://emacsredux.com/blog/2014/01/01/a-peek-at-emacs-24-dot-4-rectangular-selection/ describes this in greater detail.
One more fun one to add to the list.
If you're using evil-mode (ie, the Vim emulation layer), you can use evil-visual-block (default binding of C-v) to select a rectangle visually.
In Emacs, whether a command affects a continuous piece of text or a rectangle depends on the command, not on what the selection looks like.
I'm not aware of any way to make the selection appear as a rectangle on the screen (but see this answer), but if you use any of the rectangle commands listed in the page you linked to, such as C-x r k or C-x r t, you'll see that they operate on the rectangle defined by the beginning and the end of the selection, despite the fact that the selection looks like a regular region.
You use rectangle commands by placing the mark at one corner of the rectangle and point at the opposite corner. Even though the region will be displayed as normal, the rectangle commands will act on the rectangle delimited by point and mark. CUA mode doesn't affect this.
You just have to use your imagination :)
Enter rectangle mark mode with C-x SPC
Shrink or grow region by (This is going to select a rectangle):
2.1. Do C-n or C-p to expand the cursor to the next or previous lines respectively.
2.2. You can now play with text selection by doing C-f, C-b, M-f, M-b, etc.
This selected rectangle region can be used to perform some actions like
kill : C-x r k
delete: C-x r d
yank: C-x r y (paste last killed rectangle at cursor position)
If you want to see the rectangular selection, use CUA rectangles instead. Enable it with
(cua-selection-mode t)
Then use M-RET to start the selection, move the cursor to change it (you can also hit RET to move the cursor to different corners), C-? to get a list of commands to operate on the rectangle. M-RET with the selection active cancels the selection, as does C-g.
CUA selection mode does not enable the rest of CUA, so C-x, C-c, C-v, etc. will not change.
You can do the same thing with the mouse if you so wish. While not as specific as doing it via keyboard where you can select characters that don't exist following the end of the line for example it will fulfill most use cases.
(defun mouse-start-rectangle (start-event)
(interactive "e")
(deactivate-mark)
(mouse-set-point start-event)
(rectangle-mark-mode +1)
(let ((drag-event))
(track-mouse
(while (progn
(setq drag-event (read-event))
(mouse-movement-p drag-event))
(mouse-set-point drag-event)))))
(global-set-key (kbd "M-<down-mouse-1>") #'mouse-start-rectangle)
Found this here: https://emacs.stackexchange.com/a/7261
Most rectangle commands are accessed via the C-x r prefix (shared
with the "register" commands). See the
Rectangles manual section
here
for a description of all the special kill, yank, delete, number, replace,
etc. commands, which you'll need to do anything useful with your rectangles.
The only non-prefixed rectangle command is the initiator C-x SPC
(rectangle-mark-mode), but that's easy enough to remember, being a
lot like the very common C-SPC (set-mark-command).
It looks like in recent Emacs versions, the selected region is working
well to show exactly what's selected.
(I recommend
helm-descbinds or
guide-key to complete your
C-x r command prefixes, as well as any others.)
In addition to what others have mentioned, including about highlighting shown as a rectangle by rectangle-mark-mode and cua-rectangle-mark-mode, library Mode-Line Position (modeline-posn.el) provides the following feature for use with rectangle commands: It shows the length and width of the rectangle in the mode line, as part of size-indication-mode.
Normally, size-indication-mode shows only the buffer size and the current relative position in the buffer. With library modeline-posn.el what you see is different when the region is active:
For a rectangle command that reads input, you see the number of rectangle rows and columns (e.g. 21 rows, 16 cols)
Otherwise, the region size.
You can customize how this information appears (option modelinepos-style). By default, the active region size is shown as the number of characters and the number of lines in the region (e.g. 473 ch, 3 l).
The face used for the mode-line indication of an active region (including rectangle) is face region, so it looks the same as the region.
An additional feature draws your attention further to the mode-line region indication when a command that acts on the active region or changes its behavior when the region is active reads input. This just uses a different face, which by default is face region but with a red overline and underline.
Finally, Boolean option modelinepos-empty-region-flag determines whether an empty active region is indicated in the mode line, to attract your attention (you might not otherwise notice that you are acting on an empty region). E.g., you see (highlighted using face region): 0 ch, 0 l.

Centre Emacs buffer within window

I wrap all my code at 80 columns, and there are times where the Emacs window is wider than 80 columns and there is a lot of unused whitespace on the right side.
I would like to position the Emacs buffer, so all the text is displayed in the middle of the window.
This is different to centre aligning text (more akin to the whitespace on either side of the text when viewing pdfs).
I think this can be achieved by dynamically adjusting the fringe mode widths, depending on the current window size, but I'm not sure where to start. Any ideas?
As demonstrated here this is indeed possible:
(set-fringe-mode
(/ (- (frame-pixel-width)
(* 80 (frame-char-width)))
2))
However, as I am testing this I seem to have more luck with using margins, at least when also resizing my frame:
(defun my-resize-margins ()
(let ((margin-size (/ (- (frame-width) 80) 2)))
(set-window-margins nil margin-size margin-size)))
(add-hook 'window-configuration-change-hook #'my-resize-margins)
(my-resize-margins)
Here is a function which should do what you want, using margins instead of fringes (since I tend to display buffer boundaries in the fringe and I find it becomes ugly if the fringe is too large).
(defun my/center (width)
(interactive "nBuffer width: ")
(let* ((adj (- (window-text-width)
width))
(total-margin (+ adj
left-margin-width
right-margin-width)))
(setq left-margin-width (/ total-margin 2))
(setq right-margin-width (- total-margin left-margin-width)))
(set-window-buffer (selected-window) (current-buffer)))
You ask to display the buffer in the center of the window, which just moves some of the extra whitespace to the left of the buffer, from the right.
How about a solution that eliminates that extra whitespace instead? If that is acceptable, here are two approaches.
If the buffer is alone in its frame, then you can fit the frame to the buffer, using library fit-frame.el. I bind command fit-frame to C-x C-_. This saves space not only within Emacs but for your desktop. (Library zoom-frm.el lets you also shrink/enlarge a frame incrementally, so you can save space by shrinking a frame when you don't need to see its content in detail.)
If not (so the buffer is shown in a frame where there are multiple windows), and if the buffer's window has another window to the left or right of it, then you can do one of the following:
2a. If the buffer's window has another window to the left or right of it, then you can use command fit-window-to-buffer. But you will also need to set option fit-window-to-buffer-horizontally to non-nil.
2b. Use C-{ (shrink-window-horizontally), followed by C-x z z z..., to incrementally shrink the window width (removing the extra whitespace).
2c. Load library face-remap+.el. Whenever you use text-scaling (e.g. C-x C- or C-x =), the window size grows or shrinks along with the text size, so you don't get extra whitespace added at the right when you shrink the text. This is controlled by user option text-scale-resize-window.
Center window mode
https://github.com/anler/centered-window-mode
Global minor mode that centers the text of the window.
If another window is visible the text goes back to normal if its width is less than "cwm-centered-window-width."
Modern answer is https://github.com/rnkn/olivetti or https://github.com/joostkremers/writeroom-mode, both worked immediately for me where other things did not

Setting Both `fullheight` and `width` in Emacs on OS X

I find the default size of the Emacs frame a little too small. From reading around I know that I can set the height and width quite easily with something like the following:
;;; 140 x 60 window size
(setq default-frame-alist '((width . 140) (height . 60)))
Which works great on my external monitor, however it is a litte too big for the laptop display. I can solve the height problem by changing to the follwing:
;;; automatically set the height
(setq default-frame-alist '((fullscreen . fullheight)))
Which sets the frame to be as tall as possible for the current screen. I can't however set the width of the frame if I use this method. Adding (width . 140) to the above alist sets the width to the right value but also sets the height to the default height again.
When I see the frame appear it sets itself to the full height, and then sets the width to the value I requested, and shrinks in height.
I can overcome this problem with the following code:
;;; Full height for the default window
(setq default-frame-alist
'((fullscreen . fullheight)))
;; Set the width in a hook and have all windows inherit
(setq frame-inherited-parameters
'(width height))
(add-hook 'after-init-hook
(lambda ()
(set-frame-parameter nil 'width 140)))
Which uses a hook to set the width of the first frame to the value I want, and then sets all other windows to inherit this value.
This isn't very elegant however, so the question is "how can I accomplish this in a simpler (or less hackish) way?".
If you want to see my exact init.el script, take a look at this gist
TL;DR
How can I set both the width of a frame, and set the frame to be as tall as possible on the current monitor, on OS X? It seems you can't specify (width . 140) and (fullscreen . fullheight) in the default-frame-alist.
I have come up with a solution to this. I explicitly calculate the height of the window rather than relying on (fullscreen . fullheight) to do it for me.
The updated code to set the values for the height and width is quite simple:
;;; Nice size for the default window
(defun get-default-height ()
(/ (- (display-pixel-height) 120)
(frame-char-height)))
(add-to-list 'default-frame-alist '(width . 140))
(add-to-list 'default-frame-alist (cons 'height (get-default-height)))
In this code the subtraction of 120 from the height of the screen makes sure that the height of the window takes into account the height of the dock and the menubar. For correct results you will have to make sure that this code is executed after you have chosen the font face to use, otherwise the computed height value will not be valid.
Placing the height calculation in its own function should allow special casing certain operating systems and versions. This method also has the added advantage that is faster to open the window as it doesn't "animate" the height to the full height value.
The last paragraph of the help text for display-pixel-height is:
For graphical terminals, note that on "multi-monitor" setups this
refers to the pixel height for all physical monitors associated
with DISPLAY. To get information for each physical monitor, use
‘display-monitor-attributes-list’.
What got me to this page is what looks like a bug in the X11 implementation but I'm not sure yet. In any case, display-pixel-height works only often but not always.
Sample output from display-monitor-attributes-list is:
(
(
(geometry 0 0 1920 1080)
(workarea 0 25 1920 1055)
(mm-size 478 268)
(frames #<frame *scratch* 0x14489a030>)
(source . "NS")
)
(
(geometry 192 1080 1512 982)
(workarea 192 1080 1512 950)
(mm-size 301 195)
(frames)
(source . "NS")
)
)
In my case, I have a laptop (bottom entry) and a monitor connected to it (the top entry).
One possible solution would be to go through the list, find the monitor with the largest height and do the computations based upon that height and then at the end also do something like (set-frame-position nil 192 1080) where the two coordinates come from the top and left coordinates (the first two values of geometry and work area of the monitor that has the greatest height.
It appears that the workarea is the more prudent set of values to use.
And to further make a robust solution, a hook should be added to window-configuration-change-hook so that when a monitor is added or removed, things will get updated.
I am currently asking some questions on the Emacs developers mailing list and working on a solution for myself. I plan to return and update this entry when I have a solution that I'm happy with but thought this information may be of use to others as is.
Update:
There is no bug. x-display-pixel-height has various X11 rude facts of life. For more details, see this reply.
The "Frame Layout" node in the info documentation for ELisp as a description of the Inner and Outer Frame along with many other concepts that are pertinent to this question.
Here is my current solution. I have not done the hook yet. I don't claim to know how to program in lisp but this code is working for me.
(defun workarea-height ( monitor )
"MONITOR is an entry from `display-monitor-attributes-list' The
height entry (4th value) of the 'workarea' is returned"
(nth 4 (assoc 'workarea monitor)))
(defun monitor-with-largest-height-helper ( a b )
"Compares the height of the workarea of two monitor entries such as
those contained in the output of `display-monitor-attributes-list'"
(let* ((a-height (workarea-height a))
(b-height (workarea-height b)))
(if (> a-height b-height)
a
b)))
(defun monitor-with-largest-height ()
"Returns the monitor entry from `display-monitor-attributes-list'
with the largest 'workarea' height"
(cl-reduce #'monitor-with-largest-height-helper
(display-monitor-attributes-list)))
(defun largest-monitor-height ()
"Returns the usable height in lines of the largest monitor currently
attached"
(let* ((largest-monitor (monitor-with-largest-height)))
(/ (- (workarea-height largest-monitor)
(- (frame-outer-height)
(frame-inner-height)))
(frame-char-height))))
(defun my-resize-frame-height ()
"Resizes the current frame to the full height of the largest monitor
currently attached."
(interactive)
(set-frame-height nil (largest-monitor-height)))
The other work left to do is to make sure the left and top of the frame are within the area of the largest monitor to the frame will be displayed on that monitor.

Emacs / C-x 3 / Slightly Wider Vertical Bar

I'm in Emacs. I have a window setup with C-x 3 (so there is a vertical bar that splits the two buffers.)
Right now, what splits the two buffers is a single "|" char.
What I would prefer for my vertical split is something that looks like " | " -- i.e. I want a buffer of 2 spaces on either side of the vertical bar.
Is there an easy way to construct this?
Thanks!
It seems like this basically does the trick, although you'll get the margin at the far left and right sides of the frame as well; so it's not strictly for the window separator.
(setq-default left-margin-width 2)
(setq-default right-margin-width 2)
The part I'm not sure of is the effect it has on the minibuffer.
I tried setqing those buffer-local values to nil in minibuffer-setup-hook, but that didn't resolve it.