ncurses scroll text contents of window - text

I'm looking for definitive answers about scrolling methods in a window or pad using ncurses.
I would like to display a stdout stream which quickly fills the number of available lines on the screen and starts to overflow. Using stdio the terminal simply scrolls the contents. But with ncurses as far as I understand the output is only limited to the screen area. Is this entirely accurate?
Is the usual approach then to put the entire contents of stdout into a buffer and then read specific parts of the buffer into a ncurses window or pad? Which other methods are there to scroll text using ncurses?

You may have overlooked scrollok:
The scrollok option controls what happens when the cursor
of a window is moved off the edge of the window or
scrolling region, either as a result of a newline action
on the bottom line, or typing the last character of the
last line. If disabled, (bf is FALSE), the cursor is left
on the bottom line. If enabled, (bf is TRUE), the window
is scrolled up one line (Note that to get the physical
scrolling effect on the terminal, it is also necessary to
call idlok).
Using that, you can write to any window, and have it scroll up—just like stdio.
Further reading:
clearok, idlok, idcok, immedok, leaveok, setscrreg,
wsetscrreg, scrollok, nl, nonl - curses output options
scroll, scrl, wscrl - scroll a curses window

Use scrollok like:
scrollok(win, TRUE);

Related

vim x/y scrollbar hiding my commands and being really anoying

i'm a new vim user since 2 weeks and i've currently have my biggest trouble for the moment on vim.
i always have a x and y scrollbar on my vim and the x one is very anoying because it cover my commands.
here is a screenshot of the scrollbars that appears when i use terminal inside of vim using `:term` / `:!dir` or even when i save my vimrc or source it (`:so ~/.vimrc`)
if there is any solutions to it i will be really grateful, thanks for reading
This is an issue with your layout settings in Powershell and Ubuntu. Right click on the top bar of either program, go to Properties and then go to the Layout tab. You can check the Wrap text output on resize box and that should get rid of your horizontal scrollbar, thereby allowing you to use Vim as normal. Alternatively, in the same menu, you can decrease the width of the screen buffer size so that it is smaller than the width of the window size.

buffernext is distorting the window layout

I've been using :bnext to jump to to the next buffer in the buffer list (among
all hidden buffers). However, whenever I issue the "buffer next" command, there
are two circumstances:
If I were in the :only mode, i.e. there is only one buffer per
window, that is fine. The previous buffer become hidden and :bnext will bring
me the next buffer up front.
If I were having two buffers up and had arranged them through :vsplit,
still, switching is fine. The new buffer will pop up at the left panel
(vertically spliced)
If I were having two buffers up and have arrange them through :split, i.e.
two buffers is laid out one on top of the other, I will have trouble. Issuing
:bnext will distort the buffer layout of the window by bringing the new buffer
to the left, and have the two buffers vertically split.
Is there a global setting that I can turn on to administrate the action taken by
the :bnext? I am looking for a way to switch to the next buffer without
distilling all my current buffer layout.
(Note that, this distortion gets worse when I have more than two buffers shown
on the screen/session. In that case, :bnext will squeeze all the previous
buffers to the right, and occupy a vertical panel alone.)
Does this look familiar to you? Hope you could help me with this.
All the best,
-Linfeng
To answer my own question.
dwm.vim
is the plug-in that causes the problem. It tries to make the buffer that it switches to the "main buffer", which is be default lying on the left of the screen, occupying the whole panel length.
Update on solution at the dwm.vim side:
Solution had been offered by TimoDritschler in the following thread:
https://github.com/spolu/dwm.vim/issues/62#issuecomment-73743583
A "ready-to-go" dwm distribution of mine could be found at:
https://github.com/llinfeng/dwm.vim/
With the update, the main "compartment" of the window will not be occupied by the buffer that we switch to. Moreover, pressing <C-#> will send the current active buffer (the one with flashing cursor) to the "main compartment". It seems that nothing had been lost and stability had been gained.
Many thanks to TimoDritschler on Github again!

Emacs-like scrolling in Vim

For those unaware, AFAIK by default in Emacs scrolling works the following way.
It doesn't scroll until the user has reached the end of the visible buffer, when you reach the end of the visible buffer and you go one over the visible buffer it doesn't load one line, instead it loads an entire new page, basically. I imagine this is to reduce lag when re-rendering the screen.
What would be a way to achieve this in Vim? Is there a way to do this? If there isn't, what are some pointers to implement something like this? My idea was to maybe get the best of both worlds and scroll half a page or one page when scrolloff is reached.
Any help is appreciated. :)
I think this would do what you want:
set sj=-50
check :h 'sj' for details:
'scrolljump' 'sj' number (default 1)
global
{not in Vi}
Minimal number of lines to scroll when the cursor gets off the
screen (e.g., with "j"). Not used for scroll commands (e.g., CTRL-E,
CTRL-D). Useful if your terminal scrolls very slowly.
When set to a negative number from -1 to -100 this is used as the
percentage of the window height. Thus -50 scrolls half the window
height.
NOTE: This option is set to 1 when 'compatible' is set.

I need to draw a line moving with the cursor, but I want to avoid redrawing the whole window every 100ms

I have a program which displays a ruler on the screen, and with Xlib it polls for the cursor position every 100ms and updates the display. The display consists of numbers/lines etc, in particular a line indicating the position of the cursor (which is why it updates).
The problem is that the old line needs to be erased and the content underneath restored, so I have to redraw the whole window to reflect a change in position. Doing this 10 times a second results in a very flickery program.
I could only redraw the ruler after I have confirmed that the cursor is in a position to change the indicator line (i.e. within the bounds of the ruler), but it would still flicker pretty bad when it was updating.
Sort of a noob to GTK and Xlib and all, any advice would be appreciated.
Code is at https://github.com/zjmichen/zRuler
Well you have arrived at one of the earliest problems faced when cursors were being implemented!! Cursor changes are so frequent that redrawing full window every time just doesn't make any sense! Coming to your problem, look at what is needed & what exactly you are doing. Do you need to update the full window when cursor moves? No. You need to update only a section of the window so don't update the whole window. Off the top, I can think of 2 ways of reducing flicker:
1. Simple way is to make use of GdkCursor. Create a new cursor from the pixmap (Sample provided on the developer page) with the shape of your need, a line in your case. Associate cursor with the GdkWindow of your application's main window. This way you don't have to track cursor & draw the line. The cursor itself will appear as the line (so you don't to bother about clearing & redrawing it). Now in the timer callback where you redraw the complete window, redraw only the component which has to be updated on cursor position change. This should hopefully reduce the flicker as you are not drawing all the components.
2. In case you don't want to use GdkCursor, you could create a separate transparent window on top of application window dedicated to cursor. In this approach you can update only the cursor window & the component in the application window which is to updated on change in cursor position. This way other components in the application window are not redrawn each time & this hopefully should also be able to reduce flicker.
Hope this helps!

How can I add to the terminal's scrollback using ncurses?

I'm writing an app using ncurses which displays the status of tests running on multiple machines. It displays several progress bars at the bottom of the screen, and a failure log above them. However, the log may easily be longer than the rest of the terminal.
I'd like to have excess log roll off the top in such a way that if the user scrolls their terminal up they'll see the rest of the log. This is what happens when you scroll through a file using less; it replaces the current view with the next page, but the text you've passed ends up in the terminal's scrollback.
How can I get ncurses to do that?
Turns out this is easy. I just put a window at the top of the screen, made it scrollable (scrollok), and addstr'd text to it until it scrolled. The text scrolled right off into the scrollback without trouble.

Resources