Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
0daad598
Commit
0daad598
authored
Sep 30, 2001
by
Martin v. Löwis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Patch #462122: add readline startup and pre_event hooks.
parent
16dc7f44
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
209 additions
and
33 deletions
+209
-33
Doc/lib/libreadline.tex
Doc/lib/libreadline.tex
+16
-0
Misc/NEWS
Misc/NEWS
+2
-0
Modules/readline.c
Modules/readline.c
+127
-24
acconfig.h
acconfig.h
+3
-0
configure
configure
+54
-9
configure.in
configure.in
+4
-0
pyconfig.h.in
pyconfig.h.in
+3
-0
No files found.
Doc/lib/libreadline.tex
View file @
0daad598
...
...
@@ -54,6 +54,22 @@ history file when saving. Negative values imply unlimited history
file size.
\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
\code
{
None
}
, any hook function already installed is removed. The
startup
_
hook function is called with no arguments just
before readline prints the first prompt.
\end{funcdesc}
\begin{funcdesc}
{
set
_
pre
_
input
_
hook
}{
\optional
{
function
}}
Set or remove the pre
_
input
_
hook function. If
\var
{
function
}
is specified,
it will be used as the new pre
_
input
_
hook function; if omitted or
\code
{
None
}
, any hook function already installed is removed. The
pre
_
input
_
hook function is called with no arguments after the first prompt
has been printed and just before readline starts reading input characters.
\end{funcdesc}
\begin{funcdesc}
{
set
_
completer
}{
\optional
{
function
}}
Set or remove the completer function. If
\var
{
function
}
is specified,
it will be used as the new completer function; if omitted or
...
...
Misc/NEWS
View file @
0daad598
...
...
@@ -8,6 +8,8 @@ Core
- binascii has now two quopri support functions, a2b_qp and b2a_qp.
- readline now supports setting the startup_hook and the pre_event_hook.
Library
- quopri's encode and decode methods take an optional header parameter,
...
...
Modules/readline.c
View file @
0daad598
...
...
@@ -158,12 +158,80 @@ get_history_length(PyObject *self, PyObject *args)
return
Py_BuildValue
(
"i"
,
history_length
);
}
/* Generic hook function setter */
static
PyObject
*
set_hook
(
const
char
*
funcname
,
PyObject
**
hook_var
,
PyThreadState
**
tstate
,
PyObject
*
args
)
{
PyObject
*
function
=
Py_None
;
char
buf
[
80
];
sprintf
(
buf
,
"|O:set_%s"
,
funcname
);
if
(
!
PyArg_ParseTuple
(
args
,
buf
,
&
function
))
return
NULL
;
if
(
function
==
Py_None
)
{
Py_XDECREF
(
*
hook_var
);
*
hook_var
=
NULL
;
*
tstate
=
NULL
;
}
else
if
(
PyCallable_Check
(
function
))
{
PyObject
*
tmp
=
*
hook_var
;
Py_INCREF
(
function
);
*
hook_var
=
function
;
Py_XDECREF
(
tmp
);
*
tstate
=
PyThreadState_Get
();
}
else
{
sprintf
(
buf
,
"set_%s(func): argument not callable"
,
funcname
);
PyErr_SetString
(
PyExc_TypeError
,
buf
);
return
NULL
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/* Exported functions to specify hook functions in Python */
static
PyObject
*
startup_hook
=
NULL
;
static
PyThreadState
*
startup_hook_tstate
=
NULL
;
#ifdef HAVE_RL_PRE_INPUT_HOOK
static
PyObject
*
pre_input_hook
=
NULL
;
static
PyThreadState
*
pre_input_hook_tstate
=
NULL
;
#endif
static
PyObject
*
set_startup_hook
(
PyObject
*
self
,
PyObject
*
args
)
{
return
set_hook
(
"startup_hook"
,
&
startup_hook
,
&
startup_hook_tstate
,
args
);
}
static
char
doc_set_startup_hook
[]
=
"\
set_startup_hook([function]) -> None
\n
\
Set or remove the startup_hook function.
\n
\
The function is called with no arguments just
\n
\
before readline prints the first prompt.
\n
\
"
;
#ifdef HAVE_RL_PRE_INPUT_HOOK
static
PyObject
*
set_pre_input_hook
(
PyObject
*
self
,
PyObject
*
args
)
{
return
set_hook
(
"pre_input_hook"
,
&
pre_input_hook
,
&
pre_input_hook_tstate
,
args
);
}
static
char
doc_set_pre_input_hook
[]
=
"\
set_pre_input_hook([function]) -> None
\n
\
Set or remove the pre_input_hook function.
\n
\
The function is called with no arguments after the first prompt
\n
\
has been printed and just before readline starts reading input
\n
\
characters.
\n
\
"
;
#endif
/* Exported function to specify a word completer in Python */
static
PyObject
*
completer
=
NULL
;
static
PyThreadState
*
tstate
=
NULL
;
static
PyThreadState
*
completer_
tstate
=
NULL
;
static
PyObject
*
begidx
=
NULL
;
static
PyObject
*
endidx
=
NULL
;
...
...
@@ -238,28 +306,7 @@ get the readline word delimiters for tab-completion";
static
PyObject
*
set_completer
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
function
=
Py_None
;
if
(
!
PyArg_ParseTuple
(
args
,
"|O:set_completer"
,
&
function
))
return
NULL
;
if
(
function
==
Py_None
)
{
Py_XDECREF
(
completer
);
completer
=
NULL
;
tstate
=
NULL
;
}
else
if
(
PyCallable_Check
(
function
))
{
PyObject
*
tmp
=
completer
;
Py_INCREF
(
function
);
completer
=
function
;
Py_XDECREF
(
tmp
);
tstate
=
PyThreadState_Get
();
}
else
{
PyErr_SetString
(
PyExc_TypeError
,
"set_completer(func): argument not callable"
);
return
NULL
;
}
Py_INCREF
(
Py_None
);
return
Py_None
;
return
set_hook
(
"completer"
,
&
completer
,
&
completer_tstate
,
args
);
}
static
char
doc_set_completer
[]
=
"\
...
...
@@ -330,9 +377,60 @@ static struct PyMethodDef readline_methods[] =
METH_VARARGS
,
doc_set_completer_delims
},
{
"get_completer_delims"
,
get_completer_delims
,
METH_OLDARGS
,
doc_get_completer_delims
},
{
"set_startup_hook"
,
set_startup_hook
,
METH_VARARGS
,
doc_set_startup_hook
},
#ifdef HAVE_RL_PRE_INPUT_HOOK
{
"set_pre_input_hook"
,
set_pre_input_hook
,
METH_VARARGS
,
doc_set_pre_input_hook
},
#endif
{
0
,
0
}
};
/* C function to call the Python hooks. */
static
int
on_hook
(
PyObject
*
func
,
PyThreadState
*
tstate
)
{
int
result
=
0
;
if
(
func
!=
NULL
)
{
PyObject
*
r
;
PyThreadState
*
save_tstate
;
/* Note that readline is called with the interpreter
lock released! */
save_tstate
=
PyThreadState_Swap
(
NULL
);
PyEval_RestoreThread
(
tstate
);
r
=
PyObject_CallFunction
(
func
,
NULL
);
if
(
r
==
NULL
)
goto
error
;
if
(
r
==
Py_None
)
result
=
0
;
else
result
=
PyInt_AsLong
(
r
);
Py_DECREF
(
r
);
goto
done
;
error:
PyErr_Clear
();
Py_XDECREF
(
r
);
done:
PyEval_SaveThread
();
PyThreadState_Swap
(
save_tstate
);
}
return
result
;
}
static
int
on_startup_hook
(
void
)
{
return
on_hook
(
startup_hook
,
startup_hook_tstate
);
}
#ifdef HAVE_RL_PRE_INPUT_HOOK
static
int
on_pre_input_hook
(
void
)
{
return
on_hook
(
pre_input_hook
,
pre_input_hook_tstate
);
}
#endif
/* C function to call the Python completer. */
static
char
*
...
...
@@ -345,7 +443,7 @@ on_completion(char *text, int state)
/* Note that readline is called with the interpreter
lock released! */
save_tstate
=
PyThreadState_Swap
(
NULL
);
PyEval_RestoreThread
(
tstate
);
PyEval_RestoreThread
(
completer_
tstate
);
r
=
PyObject_CallFunction
(
completer
,
"si"
,
text
,
state
);
if
(
r
==
NULL
)
goto
error
;
...
...
@@ -395,6 +493,11 @@ setup_readline(void)
/* Bind both ESC-TAB and ESC-ESC to the completion function */
rl_bind_key_in_map
(
'\t'
,
rl_complete
,
emacs_meta_keymap
);
rl_bind_key_in_map
(
'\033'
,
rl_complete
,
emacs_meta_keymap
);
/* Set our hook functions */
rl_startup_hook
=
(
Function
*
)
on_startup_hook
;
#ifdef HAVE_RL_PRE_INPUT_HOOK
rl_pre_input_hook
=
(
Function
*
)
on_pre_input_hook
;
#endif
/* Set our completion function */
rl_attempted_completion_function
=
(
CPPFunction
*
)
flex_complete
;
/* Set Python word break characters */
...
...
acconfig.h
View file @
0daad598
...
...
@@ -87,6 +87,9 @@
/* Define if you have GNU PTH threads */
#undef HAVE_PTH
/* Define if you have readline 4.0 */
#undef HAVE_RL_PRE_INPUT_HOOK
/* Define if you have readline 4.2 */
#undef HAVE_RL_COMPLETION_MATCHES
...
...
configure
View file @
0daad598
...
...
@@ -7027,9 +7027,54 @@ EOF
fi
# check for readline 4.0
echo
$ac_n
"checking for rl_pre_input_hook in -lreadline""...
$ac_c
"
1>&6
echo
"configure:7033: checking for rl_pre_input_hook in -lreadline"
>
&5
ac_lib_var
=
`
echo
readline
'_'
rl_pre_input_hook |
sed
'y%./+-%__p_%'
`
if
eval
"test
\"
`
echo
'$''{'
ac_cv_lib_
$ac_lib_var
'+set}'
`
\"
= set"
;
then
echo
$ac_n
"(cached)
$ac_c
"
1>&6
else
ac_save_LIBS
=
"
$LIBS
"
LIBS
=
"-lreadline -ltermcap
$LIBS
"
cat
>
conftest.
$ac_ext
<<
EOF
#line 7041 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char rl_pre_input_hook();
int main() {
rl_pre_input_hook()
; return 0; }
EOF
if
{
(
eval echo
configure:7052:
\"
$ac_link
\"
)
1>&5
;
(
eval
$ac_link
)
2>&5
;
}
&&
test
-s
conftest
${
ac_exeext
}
;
then
rm
-rf
conftest
*
eval
"ac_cv_lib_
$ac_lib_var
=yes"
else
echo
"configure: failed program was:"
>
&5
cat
conftest.
$ac_ext
>
&5
rm
-rf
conftest
*
eval
"ac_cv_lib_
$ac_lib_var
=no"
fi
rm
-f
conftest
*
LIBS
=
"
$ac_save_LIBS
"
fi
if
eval
"test
\"
`
echo
'$ac_cv_lib_'
$ac_lib_var
`
\"
= yes"
;
then
echo
"
$ac_t
""yes"
1>&6
cat
>>
confdefs.h
<<
\
EOF
#define HAVE_RL_PRE_INPUT_HOOK 1
EOF
else
echo
"
$ac_t
""no"
1>&6
fi
# check for readline 4.2
echo
$ac_n
"checking for rl_completion_matches in -lreadline""...
$ac_c
"
1>&6
echo
"configure:70
33
: checking for rl_completion_matches in -lreadline"
>
&5
echo
"configure:70
78
: checking for rl_completion_matches in -lreadline"
>
&5
ac_lib_var
=
`
echo
readline
'_'
rl_completion_matches |
sed
'y%./+-%__p_%'
`
if
eval
"test
\"
`
echo
'$''{'
ac_cv_lib_
$ac_lib_var
'+set}'
`
\"
= set"
;
then
echo
$ac_n
"(cached)
$ac_c
"
1>&6
...
...
@@ -7037,7 +7082,7 @@ else
ac_save_LIBS
=
"
$LIBS
"
LIBS
=
"-lreadline -ltermcap
$LIBS
"
cat
>
conftest.
$ac_ext
<<
EOF
#line 70
41
"configure"
#line 70
86
"configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
...
...
@@ -7048,7 +7093,7 @@ int main() {
rl_completion_matches()
; return 0; }
EOF
if
{
(
eval echo
configure:70
52
:
\"
$ac_link
\"
)
1>&5
;
(
eval
$ac_link
)
2>&5
;
}
&&
test
-s
conftest
${
ac_exeext
}
;
then
if
{
(
eval echo
configure:70
97
:
\"
$ac_link
\"
)
1>&5
;
(
eval
$ac_link
)
2>&5
;
}
&&
test
-s
conftest
${
ac_exeext
}
;
then
rm
-rf
conftest
*
eval
"ac_cv_lib_
$ac_lib_var
=yes"
else
...
...
@@ -7073,7 +7118,7 @@ fi
echo
$ac_n
"checking for broken nice()""...
$ac_c
"
1>&6
echo
"configure:7
077
: checking for broken nice()"
>
&5
echo
"configure:7
122
: checking for broken nice()"
>
&5
if
eval
"test
\"
`
echo
'$''{'
ac_cv_broken_nice
'+set}'
`
\"
= set"
;
then
echo
$ac_n
"(cached)
$ac_c
"
1>&6
else
...
...
@@ -7082,7 +7127,7 @@ if test "$cross_compiling" = yes; then
ac_cv_broken_nice
=
no
else
cat
>
conftest.
$ac_ext
<<
EOF
#line 7
086
"configure"
#line 7
131
"configure"
#include "confdefs.h"
int main()
...
...
@@ -7094,7 +7139,7 @@ int main()
}
EOF
if
{
(
eval echo
configure:7
098
:
\"
$ac_link
\"
)
1>&5
;
(
eval
$ac_link
)
2>&5
;
}
&&
test
-s
conftest
${
ac_exeext
}
&&
(
./conftest
;
exit
)
2>/dev/null
if
{
(
eval echo
configure:7
143
:
\"
$ac_link
\"
)
1>&5
;
(
eval
$ac_link
)
2>&5
;
}
&&
test
-s
conftest
${
ac_exeext
}
&&
(
./conftest
;
exit
)
2>/dev/null
then
ac_cv_broken_nice
=
yes
else
...
...
@@ -7125,12 +7170,12 @@ cat >> confdefs.h <<\EOF
#endif
EOF
echo
$ac_n
"checking for socklen_t""...
$ac_c
"
1>&6
echo
"configure:71
29
: checking for socklen_t"
>
&5
echo
"configure:71
74
: checking for socklen_t"
>
&5
if
eval
"test
\"
`
echo
'$''{'
ac_cv_type_socklen_t
'+set}'
`
\"
= set"
;
then
echo
$ac_n
"(cached)
$ac_c
"
1>&6
else
cat
>
conftest.
$ac_ext
<<
EOF
#line 71
34
"configure"
#line 71
79
"configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
...
...
@@ -7179,7 +7224,7 @@ done
SRCDIRS
=
"Parser Grammar Objects Python Modules"
echo
$ac_n
"checking for build directories""...
$ac_c
"
1>&6
echo
"configure:7
183
: checking for build directories"
>
&5
echo
"configure:7
228
: checking for build directories"
>
&5
for
dir
in
$SRCDIRS
;
do
if
test
!
-d
$dir
;
then
mkdir
$dir
...
...
configure.in
View file @
0daad598
...
...
@@ -1832,6 +1832,10 @@ then
AC_DEFINE(HAVE_GETC_UNLOCKED)
fi
# check for readline 4.0
AC_CHECK_LIB(readline, rl_pre_input_hook,
AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK), , -ltermcap)
# check for readline 4.2
AC_CHECK_LIB(readline, rl_completion_matches,
AC_DEFINE(HAVE_RL_COMPLETION_MATCHES), , -ltermcap)
...
...
pyconfig.h.in
View file @
0daad598
...
...
@@ -149,6 +149,9 @@
/* Define if you have GNU PTH threads */
#undef HAVE_PTH
/* Define if you have readline 4.0 */
#undef HAVE_RL_PRE_INPUT_HOOK
/* Define if you have readline 4.2 */
#undef HAVE_RL_COMPLETION_MATCHES
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment