chewing / libchewing

libchewing - The intelligent phonetic input method library
https://chewing.im/
GNU Lesser General Public License v2.1
357 stars 89 forks source link

Rust version: When candidate is not on page 0, chewing_handle_Down would have invalid behavior #513

Closed wengxt closed 2 months ago

wengxt commented 2 months ago

Describe the bug Default layout, type "zp zp " for 紛紛, press space twice to select the last character, move to the second page, and press down again.

Candidate would return empty after this in rust version.

To Reproduce

#include <chewing.h>
#include <iostream>
#include <string>
#include <cstdarg>
#include <vector>

void logger(void * /*context*/, int /*level*/, const char *fmt, ...) {
    std::va_list argp;
    va_start(argp, fmt);
    char onechar[1];
    int len = std::vsnprintf(onechar, 1, fmt, argp);
    va_end(argp);
    if (len < 1) {
        return;
    }
    std::vector<char> buf;
    buf.resize(len + 1);
    buf.back() = 0;
    va_start(argp, fmt);
    std::vsnprintf(buf.data(), len, fmt, argp);
    va_end(argp);
    std::cerr << buf.data() << std::endl;
}

int main() {
    auto *c = chewing_new();
    // chewing_set_logger(c, logger, nullptr);
    chewing_set_maxChiSymbolLen(c, 18);
    chewing_set_ChiEngMode(c, CHINESE_MODE);
    int selkey[10];
    for (size_t i = 0; i < 10; i++) {
        selkey[i] = '0' + (i + 1) % 10;
    }

    chewing_set_selKey(c, selkey, 10);
    chewing_set_candPerPage(c, 10);
    chewing_set_addPhraseDirection(c, 1);
    chewing_set_phraseChoiceRearward(c, 1);
    chewing_set_autoShiftCur(c, 1);
    chewing_set_spaceAsSelection(c, 1);
    chewing_set_escCleanAllBuf(c, 1);
    chewing_set_KBType(c, chewing_KBStr2Num("KB_DEFAULT"));
    chewing_handle_Default(c, 'z');
    chewing_handle_Default(c, 'p');
    chewing_handle_Space(c);
    chewing_handle_Default(c, 'z');
    chewing_handle_Default(c, 'p');
    chewing_handle_Space(c);
    // Select last character
    chewing_handle_Down(c);
    chewing_handle_Down(c);
    // Move to 2nd page
    chewing_handle_Right(c);
    chewing_handle_Down(c);

    int pageSize = chewing_cand_ChoicePerPage(c);
    if (pageSize <= 0) {
        return 0;
    }
    int index = 0;
    chewing_cand_Enumerate(c);
    while (chewing_cand_hasNext(c) && index < pageSize) {
        std::cout << chewing_cand_String_static(c) << std::endl;
    }

    return 0;
}

Expected behavior Above code should print: 紛紛 分分

Platform (please complete the following information):

Additional context Add any other context about the problem here.

kanru commented 2 months ago

Thanks for the report.

Current C behavior <D><D><R><D> will circle back to the first level of candidate page (equals to <D>)

Current Rust behavior <D><D><R><D> will close the candidate list.