PerWindowPoint

Emacs conveniently allows one to work on different parts of the same buffer at the same time, but the rules governing buffer display are, for some people’s editing habits, less than ideal. Suppose for example that one is editing two parts of buffer buf in windows win-1 and win-2, switches briefly to another buffer in win-2, then returns to editing buf in win-2. This latter window will now display the same part of buf as win-1, rather than the portion that one was just recently editing in it. The package per-window-point.el (by AlpAker) creates persistent values of window-point and window-start, so that in cases like that just described win-2 will return to its previous position in buf.

In some cases, as when another Lisp program wants to move point in a buffer and then display that buffer in a window, it makes sense for Per-Window-Point not to position point in that window. (For example, when looking up a function definition via describe-function, point is moved to the function definition before the library that defines the function is displayed; we then don’t want to move point away from the definition when the library is displayed.) The package is reasonably intelligent in identifying situations in which it should defer to other Lisp programs. It also provides several hooks so that the user can define other types of exception.

Installation and Usage

To install, place the package file in your load path and put (require 'per-window-point) in your .emacs. To toggle Per-Window-Point on and off, use the command pwp-mode.

Three variables provide control over whether pwp-mode should reposition a buffer that has been displayed before in a window:

  1. pwp-no-reposition-names: If a buffer name is an element of this list, then Per-Window-Point will not position it. Default value is nil.
  2. pwp-no-reposition-regexps: If a buffer name matches one of the regular expressions in this list, Per-Window-Point will not position it. The default value is (”^\\*.+\\*$”).
  3. pwp-reposition-tests: A list of functions. When a buffer is displayed in a window, Per-Window-Point calls each function in this list with two arguments, the buffer and the window in question. If any function returns nil, Per-Window-Point does not reposition. Default value is nil.

A Note on v24

The buffer display routines were substantially rewritten for v24, and this package hasn’t been fully tested with with that version.

Discussion

Per-Window-Point and Winpoint

Do you know about winpoint.el? How does per-window-point.el compare to winpoint.el? – LennartBorgman

I was unaware of Winpoint until now, but the functionality appears to be very similar. The differences I see at first glance:

  • The internal mechanisms are different. Winpoint uses post-command-hook and window-configuration-change-hook, while pwp-mode advises functions such as switch-to-buffer, etc. In a few cases, Winpoint will likely fail to record the most up-to-date value of point (an early version of pwp-mode used the same mechanism as Winpoint and I ran into this problem). Such cases arise relatively infrequently, however.
  • Winpoint doesn’t appear to make any attempt to avoid conflicts with other Lisp programs, as described in the second paragraph of the pwp-mode description above. (It allows you to specify, on an individual basis, buffers whose point values shouldn’t be restored, but when, e.g., looking up function definitions in Elisp libraries, one needs dynamic identification of which buffers shouldn’t have point restored.) It wouldn’t be hard to add this ability to Winpoint, however.
  • Per-Window-Point allows the user more flexibility in specifying exceptions.
  • Winpoint appears only to restore point, not window-start. Whether that matters to a user is purely a matter of taste, I suppose.

In sum, the differences aren’t great, although I think Per-Window-Point is, as described above, more robust and flexible. I should note, though, that pwp-mode depends on advising primitives, which some think is bad style in Elisp; that might be a reason to be prefer Winpoint. --AA

The preferred way to do things like this is to use hooks, since that is more stable and is less likely to interfere with other programs. I think the functionality in winpoint/per-window-point is very useful and it would be good to have this in Emacs itself in my opinion. Perhaps you and the winpoint author want to take this up on Emacs devel list? – LennartBorgman

I’d like to see something like this included in Emacs. Sadly, I haven’t had much success in the past making suggestions to the developers. But perhaps joining forces with the Winpoint author will make a response more likely.

I agree, of course, that using hooks is preferable to advising primitives. However, I don’t think that hooks are sufficient here. As I mentioned above, when I first wrote pwp-mode I used the same technique as Winpoint but found that it didn’t work robustly. What’s needed is a hook that’s called just before the buffer displayed in a window changes--something like a pre-window-configuration-change-hook. Unfortunately, no such hook exists. --AA

Per-Window-Point and Indirect Buffers

Hello AlpAker,

what is the advantage of Per-Window-Point over clone-indirect-buffer? Till now I always use clone-indirect-buffer for that purpose but maybe I switch to Per-Window-Point if there are some strong reasons for that.

Best regards, TN

The differences between the two methods aren’t great, but they are based on different abstractions. Indirect buffers share text and text properties with their base buffers, but nothing else. (That’s the official description. They also share local keymaps and a few other things.) With Per-Window-Point, everything is identical except for the persistent values of point and window-start.

Which is preferable depends on what you want when you edit the same buffer in multiple windows. In general, I find the Per-Window-Point abstraction better suited to my needs. For example, if you use indirect buffers, and you want to change modes in the buffer, you need to do so multiple times, once in the base buffer and once for each indirect buffer. Similar considerations apply to, e.g., folding. There are times when that sort of separation between buffers might be convenient, but when I’m working on two different parts of the same buffer I generally want everything to be the same in the two windows except for their position in the buffer.

There are other inconveniences to indirect buffers:

  • Since they don’t have file names associated with them, functions that depend on file names won’t work when called in an indirect buffer. For example, when working with LaTeX files, many RefTeX and AucTeX functions are available only in the base buffer.
  • Indirect buffers show up as distinct buffers in the buffer menu, which makes the menu more congested than necessary.
  • Lastly, with pwp-mode, I can simply open a new window and begin working on a different part of the buffer, without pausing to create an indirect buffer. When I’m done, I simply delete the window, without needing also to kill the indirect buffer. So it’s faster and less interruptive of the flow of editing than using indirect buffers.

You might also want to look at winpoint.el, which is very similar to Per-Window-Point and which LennartBorgman brought to my attention above. --AA


CategoryBufferSwitching