Search code examples
cncursescurses

Moving the cursor to the end of a line of text in ncurses window?


I have a couple of ncurses windows and am trying to move the cursor, to the end of the current line of text.

In other words, I want to move to the first non-blank character from the end of the window.

Example:

If I have a line of text in a ncurses window

I need help! Please! !
   ^
   |
 cursor

I want to move the cursor last character

I need help! Please! !
                     ^
                     |
                   cursor

My best attempt is this:

#include <ncurses.h>

int main()
{
    initscr();
    refresh();

    WINDOW* w = newwin(100, 100, 0, 0);
    wprintw(w, "I need help! Please! !");
    wmove(w, 0, 3);
    wrefresh(w);

    // MY ATTEMPT
    int maxX, maxY, x, y;
    getmaxyx(w, maxY, maxX);
    getyx(w, y, x);

    wmove(w, y, maxX);
    while (winch(w) == ' ') {
        wmove(w, y, maxX-1);
    }
    wrefresh(w);
    // END OF MY ATTEMPT

    getch();
    delwin(w);
    endwin();
    return 0;
}

Which I think is logically sound, but is not working, and I am not sure why (the position of cursor isn't changing at all)

How do I do this? Is there an easy way I am missing? Why is my solution not working?


Solution

  • You never update your x position inside the loop, so you repeatedly move to one before the right edge of your window.

    Assuming you do not use maxX elsewhere, simply pre-decrement it within the loop.

    while((winch(w) & A_CHARTEXT) == ' ') {
       wmove(w, y, --maxX);
    }
    

    Note that you should also use the A_CHARTEXT bit mask to extract the char from a chtype.


    A very rough example of your method working, using stdscr:

    #include <ncurses.h>
    
    int main(void) {
        initscr();
        noecho();
        cbreak();
    
        while (1) {
            clear();
            mvprintw(10, 5, "Hello world");
            move(0, 0);
    
            int my,mx;
            getmaxyx(stdscr, my, mx);
    
            move(10, mx);
    
            while ((inch() & A_CHARTEXT) == ' ')
                move(10, --mx);
    
            refresh();
            napms(100);
        }
    
        endwin();
    }