@@ -54,14 +54,16 @@ extern char **completion_matches(char *, CPFunction *);
5454 * with the "real" readline and cannot be detected at compile-time,
5555 * hence we use a runtime check to detect if we're using libedit
5656 *
57- * Currently there is one know API incompatibility:
57+ * Currently there is one known API incompatibility:
5858 * - 'get_history' has a 1-based index with GNU readline, and a 0-based
59- * index with libedit's emulation.
59+ * index with older versions of libedit's emulation.
6060 * - Note that replace_history and remove_history use a 0-based index
61- * with both implementation .
61+ * with both implementations .
6262 */
6363static int using_libedit_emulation = 0 ;
6464static const char libedit_version_tag [] = "EditLine wrapper" ;
65+
66+ static int libedit_history_start = 0 ;
6567#endif /* __APPLE__ */
6668
6769#ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
@@ -579,21 +581,21 @@ get_history_item(PyObject *self, PyObject *args)
579581 return NULL ;
580582#ifdef __APPLE__
581583 if (using_libedit_emulation ) {
582- /* Libedit emulation uses 0-based indexes,
583- * the real one uses 1-based indexes,
584- * adjust the index to ensure that Python
585- * code doesn't have to worry about the
586- * difference.
584+ /* Older versions of libedit's readline emulation
585+ * use 0-based indexes, while readline and newer
586+ * versions of libedit use 1-based indexes.
587587 */
588588 int length = _py_get_history_length ();
589- idx -- ;
589+
590+ idx = idx - 1 + libedit_history_start ;
590591
591592 /*
592593 * Apple's readline emulation crashes when
593594 * the index is out of range, therefore
594595 * test for that and fail gracefully.
595596 */
596- if (idx < 0 || idx >= length ) {
597+ if (idx < (0 + libedit_history_start )
598+ || idx >= (length + libedit_history_start )) {
597599 Py_RETURN_NONE ;
598600 }
599601 }
@@ -908,6 +910,17 @@ setup_readline(void)
908910 */
909911 if (using_libedit_emulation )
910912 rl_initialize ();
913+
914+ /* Detect if libedit's readline emulation uses 0-based
915+ * indexing or 1-based indexing.
916+ */
917+ add_history ("1" );
918+ if (history_get (1 ) == NULL ) {
919+ libedit_history_start = 0 ;
920+ } else {
921+ libedit_history_start = 1 ;
922+ }
923+ clear_history ();
911924#endif /* __APPLE__ */
912925
913926 using_history ();
@@ -1116,11 +1129,8 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
11161129 if (length > 0 )
11171130#ifdef __APPLE__
11181131 if (using_libedit_emulation ) {
1119- /*
1120- * Libedit's emulation uses 0-based indexes,
1121- * the real readline uses 1-based indexes.
1122- */
1123- line = (const char * )history_get (length - 1 )-> line ;
1132+ /* handle older 0-based or newer 1-based indexing */
1133+ line = (const char * )history_get (length + libedit_history_start - 1 )-> line ;
11241134 } else
11251135#endif /* __APPLE__ */
11261136 line = (const char * )history_get (length )-> line ;
0 commit comments