Hidden Copy/Paste key bindings in nano

Viewed 35

I am working with lidssd1306 in nano on a headless raspberry pi(bullseye). The goal is to allow execution of C programs via an encoder selection on an oled display.

For some reason ctrl+shift+c and ctrl+shift+v do not work to copy text between files/tabs when editing a file in nano. Ctl+6, Alt+6(Ctl+K), Ctl+U work as expected in the file. I had a thought that my compact wireless keyboard was to blame, but that has been ruled out, as has my connection method. SSH from another PI, ExtraPuTTY from win10 desktop, even local.

I have edited the config files /etc/nanorc and created ~/.nanorc. In a design of experiments, for each file, I enabled/disabled the options:

set mouse
bind ^X, ^C, ^V

None of which allowed me to copy/paste between files.

Since ctrl+shift+c and ctrl+shift+v do function correctly in the terminal, I have been using cat to display the file and copy the lines I want. From there I can use ctrl+shift+v to paste the text into the nano editor. I could probably use awk to accomplish the task, but both these two methods seem to be overcomplicating a simple task.

From this I deduce that there must be either keybindings or settings that are hidden/obfuscated.

What are the hidden keybindings or settings that will allow a simple copy/paste between files?

RasPi Bullseye ExtraPuTTY 0.29_RC2
nano 5.4

1 Answers

The answer is that the rmb is not supported in nano. Funny that they support buttons 4, & 5. Maybe someday I'll have the chops to code that myself, I'll add it to the list...

from winio.c in the nano src files:

#ifdef ENABLE_MOUSE
/* Handle any mouse event that may have occurred.  We currently handle
 * releases/clicks of the first mouse button.  If allow_shortcuts is
 * TRUE, releasing/clicking on a visible shortcut will put back the
 * keystroke associated with that shortcut.  If ncurses supports them,
 * we also handle presses of the fourth mouse button (upward rolls of
 * the mouse wheel) by putting back keystrokes to move up, and presses
 * of the fifth mouse button (downward rolls of the mouse wheel) by
 * putting back keystrokes to move down.  We also store the coordinates
 * of a mouse event that needs further handling in mouse_x and mouse_y.
 * Return -1 on error, 0 if the mouse event needs to be handled, 1 if it's
 * been handled by putting back keystrokes, or 2 if it's been ignored. */
int get_mouseinput(int *mouse_y, int *mouse_x, bool allow_shortcuts)
{
    bool in_middle, in_footer;
    MEVENT event;

    /* First, get the actual mouse event. */
    if (getmouse(&event) == ERR)
        return -1;

    in_middle = wenclose(midwin, event.y, event.x);
    in_footer = wenclose(footwin, event.y, event.x);

    /* Copy (and possibly adjust) the coordinates of the mouse event. */
    *mouse_x = event.x - (in_middle ? margin : 0);
    *mouse_y = event.y;

    /* Handle releases/clicks of the first mouse button. */
    if (event.bstate & (BUTTON1_RELEASED | BUTTON1_CLICKED)) {
        /* If we're allowing shortcuts, and the current shortcut list is
         * being displayed on the last two lines of the screen, and the
         * first mouse button was released on/clicked inside it, we need
         * to figure out which shortcut was released on/clicked and put
         * back the equivalent keystroke(s) for it. */
        if (allow_shortcuts && !ISSET(NO_HELP) && in_footer) {
            int width;
                /* The width of each shortcut item, except the last two. */
            int index;
                /* The calculated index of the clicked item. */
            size_t number;
                /* The number of shortcut items that get displayed. */

            /* Shift the coordinates to be relative to the bottom window. */
            wmouse_trafo(footwin, mouse_y, mouse_x, FALSE);

            /* Clicks on the status bar are handled elsewhere, so
             * restore the untranslated mouse-event coordinates. */
            if (*mouse_y == 0) {
                *mouse_x = event.x;
                *mouse_y = event.y;
                return 0;
            }

            /* Determine how many shortcuts are being shown. */
            number = shown_entries_for(currmenu);

            /* Calculate the clickable width of each menu item. */
            if (number < 5)
                width = COLS / 2;
            else
                width = COLS / ((number + 1) / 2);

            /* Calculate the one-based index in the shortcut list. */
            index = (*mouse_x / width) * 2 + *mouse_y;

            /* Adjust the index if we hit the last two wider ones. */
            if ((index > number) && (*mouse_x % width < COLS % width))
                index -= 2;

            /* Ignore clicks beyond the last shortcut. */
            if (index > number)
                return 2;

            /* Search through the list of functions to determine which
             * shortcut in the current menu the user clicked on; then
             * put the corresponding keystroke into the keyboard buffer. */
            for (funcstruct *f = allfuncs; f != NULL; f = f->next) {
                if ((f->menus & currmenu) == 0)
                    continue;
                if (first_sc_for(currmenu, f->func) == NULL)
                    continue;
                if (--index == 0) {
                    const keystruct *shortcut = first_sc_for(currmenu, f->func);

                    put_back(shortcut->keycode);
                    if (0x20 <= shortcut->keycode && shortcut->keycode <= 0x7E)
                        put_back(ESC_CODE);
                    break;
                }
            }

            return 1;
        } else
            /* Clicks outside of the bottom window are handled elsewhere. */
            return 0;
    }
#if NCURSES_MOUSE_VERSION >= 2
    /* Handle "presses" of the fourth and fifth mouse buttons
     * (upward and downward rolls of the mouse wheel). */
    else if (event.bstate & (BUTTON4_PRESSED | BUTTON5_PRESSED)) {
        if (in_footer)
            /* Shift the coordinates to be relative to the bottom window. */
            wmouse_trafo(footwin, mouse_y, mouse_x, FALSE);

        if (in_middle || (in_footer && *mouse_y == 0)) {
            int keycode = (event.bstate & BUTTON4_PRESSED) ? KEY_UP : KEY_DOWN;

            /* One roll of the mouse wheel should move three lines. */
            for (int count = 3; count > 0; count--)
                put_back(keycode);

            return 1;
        } else
            /* Ignore "presses" of the fourth and fifth mouse buttons
             * that aren't on the edit window or the status bar. */
            return 2;
    }
#endif
    /* Ignore all other mouse events. */
    return 2;
}
#endif /* ENABLE_MOUSE */
Related