15

I'm familiar with and use very frequently the C-l (recenter-top-bottom) to

Move current line to window center, top, and bottom, successively.

I'd like to have an equivalent command to move the current column to window center, left and right borders, successively. Either built-in or a snippet of Elisp.

agentofuser
  • 8,987
  • 11
  • 54
  • 85
  • `C-h f recenter` (my version (GNU 22.3) doesn't have recenter-top-bottom, what version are you using?) says this function is implemented in the c-core of emacs, so it may not be trivial to get the horizontal behavior in elisp. Consider patching the source? – dmckee --- ex-moderator kitten Aug 08 '09 at 18:48
  • 1
    I'm running GNU 23.0.91.1 from the ubuntu emacs-snapshot package version 1:20090320-1ubuntu1. The only difference between `recenter` and `recenter-top-bottom` is that, in the latter, repeating the command cycles between putting the cursor at the center, at the top and at the bottom. Horizontal scrolling already exists with `C-x C-<` and `C-x C->` and with normal `C-f` when you get close to the right border, so I don't think we'd have to go all the way to the emacs core. – agentofuser Aug 08 '09 at 19:17
  • 1
    @obvio171 `C-x C-<` and `C-x C->` are undefined in my (almost bare) config. Can you specify where you did get them from? – To1ne Dec 03 '14 at 08:15

2 Answers2

15

Here you go:

(defun my-horizontal-recenter ()
  "make the point horizontally centered in the window"
  (interactive)
  (let ((mid (/ (window-width) 2))
        (line-len (save-excursion (end-of-line) (current-column)))
        (cur (current-column)))
    (if (< mid cur)
        (set-window-hscroll (selected-window)
                            (- cur mid)))))

And the obvious binding (from obvio171) is:

(global-set-key (kbd "C-S-l") 'my-horizontal-recenter)
Community
  • 1
  • 1
Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
  • This is perfect! Bound it to C-S-l, works like a charm! Thanks a lot! :) – agentofuser Aug 08 '09 at 19:46
  • Nice ! I've added this function to integrate yours in `C-l` binding, only if you are in truncate-lines mode : (defun my-recenter () "center vertically and horizontally in truncate-lines mode" (interactive) (if (equal truncate-lines t) (my-horizontal-recenter)) (recenter-top-bottom)) (global-set-key "\C-l" 'my-recenter) – fredz Oct 22 '14 at 15:51
  • 1
    This only does the re-centering. However, successive presses of `C-l` cycle center, top, bottom successively. Would be nice if this answer could be expanded to include the complete cycle. – Christian Herenz Nov 30 '21 at 02:10
  • This is beautiful. Should be part of Emacs. I would suggest the name `recenter-left-right`. Also I agree with @ChristianHerenz. – Jeffrey Benjamin Brown Dec 11 '21 at 13:48
  • 1
    Nice. No need for extra binding, here's what I have: ```(defadvice recenter-top-bottom (after my-horizontal-recenter activate) "when re-centering window vertically around cursor, also do it horizontally" (interactive) (my-horizontal-recenter)) ``` – FerD May 17 '23 at 14:35
4

If you move to a chosen column and hit C-x C-n, then the commands C-n and C-p will go to that column until you hit C-u C-x C-n to turn the behavior off.

A sort of poor-man's version of what you are looking for.

Pinochle
  • 5,515
  • 2
  • 26
  • 20
  • This only limits the column which the cursor can be at, but doesn't move the text horizontally. What I want is for the column the cursor is at to be "dragged" to the center of the screen, doing a horizontal scroll. – agentofuser Aug 08 '09 at 18:29