Repository: valkey-io/valkey
File: deps/linenoise/linenoise.c (C)

Code before:
                break;
            }

            if (read(l.ifd,seq+1,1) == -1) break;

            /* ESC [ sequences. */
            if (seq[0] == '[') {
                if (seq[1] >= '0' && seq[1] <= '9') {
                    /* Extended escape, read additional bytes.
                     * Examples: ESC [1;5C  ESC [3~ */
                    const int seqBufferMaxLength = 8;
                    char seqBuffer[seqBufferMaxLength];
                    int i = 0;
                    seqBuffer[i++] = seq[1];

                    /* If first param is digit or ';', read more until we see a final in @~ */
                    char additionalChar;
                    while (i < seqBufferMaxLength-1 && read(l.ifd, &additionalChar, 1) != -1) {
                        seqBuffer[i++] = additionalChar;
                        if (additionalChar >= '@' && additionalChar <= '~') {    /* CSI final byte */
                            seqBuffer[i] = '\0';
                            break;
                        }
                    }

                    if (strstr(seqBuffer, "1;5D") || strstr(seqBuffer, "5D")) {
                        linenoiseEditMoveWordLeft(&l, isBigWordDelimiter);
                        break;
                    }
                    if (strstr(seqBuffer, "1;5C") || strstr(seqBuffer, "5C")) {
                        linenoiseEditMoveWordRight(&l, isBigWordDelimiter);
                        break;
                    }
                    if (strstr(seqBuffer, "3~")) {
                        linenoiseEditDelete(&l);
                        break;
                    }
                } else {
                    switch(seq[1]) {
                    case 'A': /* Up */
                        linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV);
                        break;
                    case 'B': /* Down */
                        linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
                        break;
                    case 'C': /* Right */
                        linenoiseEditMoveRight(&l);
                        break;
                    case 'D': /* Left */
                        linenoiseEditMoveLeft(&l);
                        break;

Review comment (suggestion):
Please add a comment like `/* Ctrl + left */` explaining what key this is, to each of these case. Not everyone knows these by heart. :)

On my system, I get "1;5D" for ctrl + left arrow. Where do you get just "5D"?

Have you found these in some manual such as xterm or VT100? I'm curious to what extent these are standard and portable.

Checking if "5D" is a substring (which is what `strstr` does) doesn't seem completely correct. Shouldn't we check the full string? Use `strcmp` to do that.

Code after:

            /* Handle Meta-b / Meta-f directly.
             * Usually generated by Alt + ←/→ (but not always)
             */
            if (seq[0] == 'b') {                 /* ESC b → word left */
                linenoiseEditMoveWordLeft(&l, isSubWordDelimiter);
                break;
            }
            if (seq[0] == 'f') {                 /* ESC f → word right */
                linenoiseEditMoveWordRight(&l, isSubWordDelimiter);
                break;
            }

            if (read(l.ifd,seq+1,1) == -1) break;

            /* ESC [ sequences. */
            if (seq[0] == '[') {
                if (seq[1] >= '0' && seq[1] <= '9') {
                    /* Extended escape, read additional bytes.
                     * Examples: ESC [1;5C  ESC [3~ */
                    const int seqBufferMaxLength = 8;
                    char seqBuffer[seqBufferMaxLength];
                    int i = 0;
                    seqBuffer[i++] = seq[1];

                    /* If first param is digit or ';', read more until we see a final in @~ */
                    char additionalChar;
                    while (i < seqBufferMaxLength-1 && read(l.ifd, &additionalChar, 1) != -1) {
                        seqBuffer[i++] = additionalChar;
                        if (additionalChar >= '@' && additionalChar <= '~') {    /* CSI final byte */
                            seqBuffer[i] = '\0';
                            break;
                        }
                    }

                    /* The exact key mapping behavior depends on your keyboard/terminal setup */
                    /* Usually Alt/Ctrl + ← */
                    if (!strcmp(seqBuffer, "1;5D") || !strcmp(seqBuffer, "1;3D")) {
                        linenoiseEditMoveWordLeft(&l, isBigWordDelimiter);
                        break;
                    }
                    /* Usually Alt/Ctrl + → */
                    if (!strcmp(seqBuffer, "1;5C") || !strcmp(seqBuffer, "1;3C")) {
                        linenoiseEditMoveWordRight(&l, isBigWordDelimiter);
                        break;
                    }
                    /* Usually the `delete` key */
                    if (!strcmp(seqBuffer, "3~")) {
                        linenoiseEditDelete(&l);
                        break;
                    }