--- python2.4/Modules/readline.orig.c 2005-04-01 11:16:08.683270880 -0800 +++ python2.4/Modules/readline.c 2005-04-01 11:16:27.991335608 -0800 @@ -203,7 +203,10 @@ static PyThreadState *pre_input_hook_tstate = NULL; #endif -static PyObject * +static PyObject *py_callback_hook = NULL; +static PyThreadState *py_callback_hook_tstate = NULL; + + static PyObject * set_startup_hook(PyObject *self, PyObject *args) { return set_hook("startup_hook", &startup_hook, @@ -237,6 +240,18 @@ #endif +static PyObject * +set_py_callback_hook(PyObject *self, PyObject *args) +{ + return set_hook("py_callback_hook", &py_callback_hook, &py_callback_hook_tstate, args); +} + +static char doc_set_py_callback_hook[] = "\ +set_py_callback_hook([function]) -> None\n\ +Set or remove the py_callback_hook function.\n\ +The function is used to set the python\n\ +key bindable callback.\n\ +"; /* Exported function to specify a word completer in Python */ @@ -535,6 +550,97 @@ Change what's displayed on the screen to reflect the current\n\ contents of the line buffer."); +/* Exported function to delete text from the line buffer */ + +static PyObject * +delete_text(PyObject *self, PyObject *args) +{ + int start, end; + if (!PyArg_ParseTuple(args, "ii", &start, &end)) + return NULL; + rl_delete_text(start, end); + Py_INCREF(Py_None); + return Py_None; +} + +static char doc_delete_text[] = "\ +delete_text(string) -> None\n\ +Insert text into the command line.\ +"; + +/* interface to message */ + +static PyObject * +message (PyObject *self, PyObject *args) +{ + char *s, *p; + if (!PyArg_ParseTuple(args, "s", &s)) + return NULL; + + p = &s[strlen(s) - 1]; /* swat the line feed */ + if (*p == '\n') + *p = 0; + rl_clear_message(); + rl_save_prompt(); + rl_message( s ); + rl_redisplay(); + return Py_None; +} + +static char doc_message[] = "\ +message(string) -> None\n\ +Print a string in echo area\ +"; + +/* interface to rl_forced_update_display */ + +static PyObject * +forced_update_display (PyObject *self, PyObject *args) +{ + rl_forced_update_display(); + return Py_None; +} + +static char doc_forced_update_display[] = "\ +forced_update_display(string) -> None\n\ +Tell readline that it's on a new line.\ +"; + + +/* interface to rl_on_new_line +*/ + +static PyObject * +on_new_line (PyObject *self, PyObject *args) +{ + rl_on_new_line(); + rl_redisplay(); + return Py_None; +} + +static char doc_on_new_line[] = "\ +on_new_line(string) -> None\n\ +Tell readline that it's on a new line.\ +"; + + +/* interface to position_cursor */ + +static PyObject * +position_cursor (PyObject *self, PyObject *args) +{ + int pos; + if (!PyArg_ParseTuple(args, "i", &pos)) + return NULL; + + rl_point = pos; + return Py_None; +} + +static char doc_position_cursor[] = "\ +position_cursor(int) -> None\n\ +Reposition cursor in edit line\ +"; /* Table of functions exported by the module */ @@ -543,8 +649,13 @@ {"parse_and_bind", parse_and_bind, METH_VARARGS, doc_parse_and_bind}, {"get_line_buffer", get_line_buffer, METH_NOARGS, doc_get_line_buffer}, {"insert_text", insert_text, METH_VARARGS, doc_insert_text}, + {"delete_text", delete_text, METH_VARARGS, doc_delete_text}, {"redisplay", redisplay, METH_NOARGS, doc_redisplay}, {"read_init_file", read_init_file, METH_VARARGS, doc_read_init_file}, + {"message", message, METH_VARARGS, doc_message}, + {"on_new_line", on_new_line, METH_VARARGS, doc_on_new_line}, + {"forced_update_display", forced_update_display, METH_VARARGS, doc_forced_update_display}, + {"position_cursor", position_cursor, METH_VARARGS, doc_position_cursor}, {"read_history_file", read_history_file, METH_VARARGS, doc_read_history_file}, {"write_history_file", write_history_file, @@ -576,6 +687,7 @@ {"set_pre_input_hook", set_pre_input_hook, METH_VARARGS, doc_set_pre_input_hook}, #endif + {"set_py_callback_hook", set_py_callback_hook, METH_VARARGS, doc_set_py_callback_hook}, #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER {"clear_history", py_clear_history, METH_NOARGS, doc_clear_history}, #endif @@ -627,6 +739,24 @@ #endif +/* This one has rl_ and __P so we can bind to it after exporting it with defun. + Where count is the numeric argument (or 1 if defaulted) and key is the + key that invoked this function. +*/ +int +rl_py_callback __P((int count, int key)) +{ + return on_hook(py_callback_hook, &py_callback_hook_tstate); +} + +static char rl_py_callback_help[] = "\ +rl_py_callback() -> None\n\ +Python bindable callback function.\n\ +The function is can be bound to any keys to provide a python\n\ +key bindable callback.\n\ +"; + + /* C function to call the Python completer. */ static char * @@ -717,6 +847,8 @@ rl_completion_append_character ='\0'; #endif + rl_add_defun( "py_callback", rl_py_callback, -1 ); + begidx = PyInt_FromLong(0L); endidx = PyInt_FromLong(0L); /* Initialize (allows .inputrc to override) @@ -928,3 +1060,4 @@ PyOS_ReadlineFunctionPointer = call_readline; setup_readline(); } + --- python2.4/Doc/lib/libreadline.orig.tex 2005-04-01 15:35:42.000000000 -0800 +++ python2.4/Doc/lib/libreadline.tex 2005-04-04 08:21:31.758899200 -0700 @@ -27,6 +27,18 @@ Insert text into the command line. \end{funcdesc} +\begin{funcdesc}{delete_text}{start, end} +Delete text from the command line. +\end{funcdesc} + +\begin{funcdesc}{message}{string} +Display a message in the readline echo area. +\end{funcdesc} + +\begin{funcdesc}{position_cursor}{pos} + Set the current cursor position in the readline buffer. +\end{funcdesc} + \begin{funcdesc}{read_init_file}{\optional{filename}} Parse a readline initialization file. The default filename is the last filename used. @@ -86,6 +98,16 @@ of the line buffer. \versionadded{2.3} \end{funcdesc} +\begin{funcdesc}{forced_update_display}{} +Force the line to be updated and redisplayed, whether or not +Readline thinks the screen display is correct +\end{funcdesc} + +\begin{funcdesc}{on_new_line}{} +Tell the update functions that we have moved onto a new (empty) +line, usually after ouputting a newline. +\end{funcdesc} + \begin{funcdesc}{set_startup_hook}{\optional{function}} Set or remove the startup_hook function. If \var{function} is specified, it will be used as the new startup_hook function; if omitted or @@ -112,6 +134,14 @@ possible completion starting with \var{text}. \end{funcdesc} +\begin{funcdesc}{set_py_callback_hook}{\optional{function}} +Set or remove a readline key-bindable callback function. +If \var{function} is specified, it will be used as the new callback_hook +function; if omitted or \code{None}, any hook function already installed is +removed. The callback_hook function is called with no arguments when the +bound key is pressed. +\end{funcdesc} + \begin{funcdesc}{get_completer}{} Get the completer function, or \code{None} if no completer function has been set. \versionadded{2.3} @@ -191,3 +221,25 @@ def save_history(self, histfile): readline.write_history_file(histfile) \end{verbatim} + +The following example demonstrates how to use the +key bindable callback function. +This sets up a function to be called anytime '?' is pressed. +The example callback function then examines the buffer and +displays context sensitive help info. + +\begin{verbatim} +import readline +import atexit +import os + +def rlHook(): + buf = readline.get_line_buffer() + eix = len( buf ) + if len(buf) and buf[0] == 'x': + show_x_help() + readline.on_new_line() + +readline.set_py_callback_hook(rlHook) +readline.parse_and_bind("?: py_callback" ) +\end{verbatim}