copypastekey-bindingsnano

Hidden Copy/Paste key bindings in nano


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


Solution

  • 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 */