wbolster/emacs-python-pytest

Customise window size and fit content to it

sammorley-short opened this issue ยท 11 comments

It would be really great if one were able to define the size of the window created to display the pytest buffer. Often half of the screen is more than enough when running a test, and in my case I'd like to limit the width of the created buffer to some maximum size.

Similarly, the content inside the buffer is formatted to match the size of the fully maximised window size. This means when the tests are running, they run off the window and out of view. Similarly, the progress percentages are never in view because of this. It would be preferable if the shell running pytest was initially aware of the size of the window it's filling, so that the content can be printed accordingly, similarly to how it works in an actual terminal session.

Thanks!

i think the answer here is (magic and tricky) configuration using display-buffer-alist. this package names its buffers properly so it should be possible to match them. and since this ultimately boils down to personal preference, i consider it out of scope for this package to contain any configuration.

for example, for me new windows (including those opened by python-pytest-โ€ฆ commands) open in a split window on the side, which works well for me.

the pytest output is adapted to the available window size (i think due to comint-mode / compilation-mode), but for me it also gets confused when a fresh window opens, and the output is wider as a result. however, if i run python-pytest-repeat to run pytest again in the already open window, the output looks good. ๐Ÿคท

(closing since none of this seems caused by python-pytest.el directly)

i think the answer here is (magic and tricky) configuration using display-buffer-alist. this package names its buffers properly so it should be possible to match them.

Rather than via the buffer list, would it be possible to expose a hook for when the buffer is open and the tests are running. I saw that the package defines a bunch of hooks, one of which I thought would achieve this, defining a hook to resize after them didn't work as I'd expected.

however, if i run python-pytest-repeat to run pytest again in the already open window, the output looks good

Interesting, when I do this, I get the output rendered to the same width as the maximised screen. Any idea how one could force it to observe the window width?

Thanks

if you leave the window open, and from that window execute M-x python-pytest-repeat, does it detect the width correctly?

because that works automatically for me, but only if the window was already open (i think comint-mode does that?)

if you leave the window open, and from that window execute M-x python-pytest-repeat, does it detect the width correctly?

Aha, yes, this now works, but only if I call python-pytest-repeat from the test window. If I call it from the window with the code in, it formats it to the original window size (half the frame size, not the full frame as I had originally thought). Even if I call repeat inside the test window (which renders correctly) and then again from outside, it still renders the rerun to the original (i.e. incorrect) window size.

Any idea what's going on here?

nope, sorry. this is something low level related to comint and terminal emulation, combined with timings/order of emacs window layout, etc.

please do report if you manage to figure out though ๐Ÿ™ƒ

One simple solution could be to map the key bindings I use to call the associated commands in the pytest buffer, rather than the current, if it exists.

I'm pretty new to emacs, so am not totally sure if this is possible/would work. What do you think @wbolster?

@wbolster Here's an interesting observation I noticed while trying to debug this:

The width of the content in the comint-mode pytest interpreter buffer is actually set to the width of the window in which the python-pytest command was run. For me this can be repro'd by setting the width of current buffer (containing the test) to something small, like say 40, and then dispatching a test. When I run this the resulting pytest buffer then attempts to render to a width of 40 characters where possible.

I am not familiar enough with the source code or comint mode to know how to propagate this information to the appropriate comint function call, but presumably it should be possible?

Looking at the comint mode source code, it seems like this would be best addressed by having the pytest window selected just before make-comint-in-buffer is called.

I have tested this and with some added hooks I can get a limited version of the solution working. When one only has two windows open, adding the following hooks solves the problem:

(defun focus-on-other-window ()
  (other-window 1))
(add-hook 'python-pytest-setup-hook 'focus-on-other-window)
(add-hook 'python-pytest-started-hook 'focus-on-other-window)

But obviously this will not work if there are more windows involved, so this could be addressed with some simple functions that select and deselect the pytest window before and after the make-comint-in-buffer call respectively.

As an Emacs newbie I am not sure how to test such a change on a development version of the package locally, but I believe it would be a small change and would have exactly the desired effect ๐Ÿ™‚

Hi,

The solution from @sammorley-short did not work for me. I managed to solve the issue in a slightly different way, and I want to share my solution with others that might encounter a similar issue:

(add-hook 'python-pytest-setup-hook (lambda () (switch-to-buffer-other-window (python-pytest--get-buffer))))

The new hook will display the buffer and switch to to it before actually calling pytest. This way, when pytest is invoked, it knows the correct size of the buffer.

I haven't yet looked at the source code and I have no experience in writing proper Emacs packages, but I think the problem might be with (with-current-buffer buffer, as this function (if I understand it correctly) does not switch focus to the buffer, or switches it back immediately.

Looking at the comint mode source code, it seems like this would be best addressed by having the pytest window selected just before make-comint-in-buffer is called.

seems like this is the right approach indeed ๐Ÿ‘๐Ÿผ