···258258static void move_cursor_to_line_start(rl_interface_t *iface, int cols) {
259259 int prompt_len = (int)strlen(iface->prompt);
260260 int cursor_cols = prompt_len + iface->line_pos;
261261- int cursor_row = cursor_cols > 0 ? (cursor_cols - 1) / cols : 0;
261261+ int cursor_row = cursor_cols / cols;
262262+ if (cursor_cols > 0 && cursor_cols % cols == 0) cursor_row--;
262263263264 if (cursor_row > 0) {
264265 char move_buf[32];
···621622622623 char *event = js_getstr(js, args[0], NULL);
623624 if (!event) return js_mkerr(js, "event must be a string");
624624- if (vtype(args[1]) != T_FUNC) return js_mkerr(js, "listener must be a function");
625625+ int t = vtype(args[1]);
626626+ if (t != T_FUNC && t != T_CFUNC) return js_mkerr(js, "listener must be a function");
625627626628 RLEventType *evt = find_or_create_event_type(iface, event);
627629 if (evt->listener_count >= MAX_LISTENERS_PER_EVENT) {
···644646645647 char *event = js_getstr(js, args[0], NULL);
646648 if (!event) return js_mkerr(js, "event must be a string");
647647- if (vtype(args[1]) != T_FUNC) return js_mkerr(js, "listener must be a function");
649649+ int t = vtype(args[1]);
650650+ if (t != T_FUNC && t != T_CFUNC) return js_mkerr(js, "listener must be a function");
648651649652 RLEventType *evt = find_or_create_event_type(iface, event);
650653 if (evt->listener_count >= MAX_LISTENERS_PER_EVENT) {
···937940 char *query = js_getstr(js, args[0], &query_len);
938941 if (!query) return js_mkerr(js, "query must be a string");
939942940940- if (vtype(args[1]) != T_FUNC) {
943943+ int t = vtype(args[1]);
944944+ if (t != T_FUNC && t != T_CFUNC) {
941945 return js_mkerr(js, "callback must be a function");
942946 }
943947