From b32cb97bce472dad337c6b2f071883f6234e21d8 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 31 Oct 2019 02:13:48 -0700 Subject: bpo-38312: Add curses.{get,set}_escdelay and curses.{get,set}_tabsize. (GH-16938) --- Doc/library/curses.rst | 26 +++++ Doc/whatsnew/3.9.rst | 7 ++ Lib/test/test_curses.py | 4 + .../2019-10-26-14-42-20.bpo-38312.e_FVWh.rst | 3 + Modules/_cursesmodule.c | 84 ++++++++++++++ Modules/clinic/_cursesmodule.c.h | 124 ++++++++++++++++++++- 6 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rst diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index f1803c6..1201e89 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -511,6 +511,32 @@ The module :mod:`curses` defines the following functions: Save the current state of the terminal modes in a buffer, usable by :func:`resetty`. +.. function:: get_escdelay() + + Retrieves the value set by :func:`set_escdelay`. + + .. versionadded:: 3.9 + +.. function:: set_escdelay(ms) + + Sets the number of milliseconds to wait after reading an escape character, + to distinguish between an individual escape character entered on the + keyboard from escape sequences sent by cursor and function keys. + + .. versionadded:: 3.9 + +.. function:: get_tabsize() + + Retrieves the value set by :func:`set_tabsize`. + + .. versionadded:: 3.9 + +.. function:: set_tabsize(size) + + Sets the number of columns used by the curses library when converting a tab + character to spaces as it adds the tab to a window. + + .. versionadded:: 3.9 .. function:: setsyx(y, x) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index d41e708..7d7c502 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -130,6 +130,13 @@ that schedules a shutdown for the default executor that waits on the :func:`asyncio.run` has been updated to use the new :term:`coroutine`. (Contributed by Kyle Stanley in :issue:`34037`.) +curses +------ + +Add :func:`curses.get_escdelay`, :func:`curses.set_escdelay`, +:func:`curses.get_tabsize`, and :func:`curses.set_tabsize` functions. +(Contributed by Anthony Sottile in :issue:`38312`.) + fcntl ----- diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 09738c8..5e619d1 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -261,6 +261,10 @@ class TestCurses(unittest.TestCase): curses.putp(b'abc') curses.qiflush() curses.raw() ; curses.raw(1) + curses.set_escdelay(25) + self.assertEqual(curses.get_escdelay(), 25) + curses.set_tabsize(4) + self.assertEqual(curses.get_tabsize(), 4) if hasattr(curses, 'setsyx'): curses.setsyx(5,5) curses.tigetflag('hc') diff --git a/Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rst b/Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rst new file mode 100644 index 0000000..2a1800f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rst @@ -0,0 +1,3 @@ +Add :func:`curses.get_escdelay`, :func:`curses.set_escdelay`, +:func:`curses.get_tabsize`, and :func:`curses.set_tabsize` functions - +by Anthony Sottile. diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 98fd1f3..29840b5 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -3256,6 +3256,86 @@ _curses_setupterm_impl(PyObject *module, const char *term, int fd) } /*[clinic input] +_curses.get_escdelay + +Gets the curses ESCDELAY setting. + +Gets the number of milliseconds to wait after reading an escape character, +to distinguish between an individual escape character entered on the +keyboard from escape sequences sent by cursor and function keys. +[clinic start generated code]*/ + +static PyObject * +_curses_get_escdelay_impl(PyObject *module) +/*[clinic end generated code: output=222fa1a822555d60 input=be2d5b3dd974d0a4]*/ +{ + return PyLong_FromLong(ESCDELAY); +} +/*[clinic input] +_curses.set_escdelay + ms: int + length of the delay in milliseconds. + / + +Sets the curses ESCDELAY setting. + +Sets the number of milliseconds to wait after reading an escape character, +to distinguish between an individual escape character entered on the +keyboard from escape sequences sent by cursor and function keys. +[clinic start generated code]*/ + +static PyObject * +_curses_set_escdelay_impl(PyObject *module, int ms) +/*[clinic end generated code: output=43818efbf7980ac4 input=7796fe19f111e250]*/ +{ + if (ms <= 0) { + PyErr_SetString(PyExc_ValueError, "ms must be > 0"); + return NULL; + } + + return PyCursesCheckERR(set_escdelay(ms), "set_escdelay"); +} + +/*[clinic input] +_curses.get_tabsize + +Gets the curses TABSIZE setting. + +Gets the number of columns used by the curses library when converting a tab +character to spaces as it adds the tab to a window. +[clinic start generated code]*/ + +static PyObject * +_curses_get_tabsize_impl(PyObject *module) +/*[clinic end generated code: output=7e9e51fb6126fbdf input=74af86bf6c9f5d7e]*/ +{ + return PyLong_FromLong(TABSIZE); +} +/*[clinic input] +_curses.set_tabsize + size: int + rendered cell width of a tab character. + / + +Sets the curses TABSIZE setting. + +Sets the number of columns used by the curses library when converting a tab +character to spaces as it adds the tab to a window. +[clinic start generated code]*/ + +static PyObject * +_curses_set_tabsize_impl(PyObject *module, int size) +/*[clinic end generated code: output=c1de5a76c0daab1e input=78cba6a3021ad061]*/ +{ + if (size <= 0) { + PyErr_SetString(PyExc_ValueError, "size must be > 0"); + return NULL; + } + + return PyCursesCheckERR(set_tabsize(size), "set_tabsize"); +} + +/*[clinic input] _curses.intrflush flag: bool(accept={int}) @@ -4415,6 +4495,10 @@ static PyMethodDef PyCurses_methods[] = { _CURSES_RESIZETERM_METHODDEF _CURSES_RESIZE_TERM_METHODDEF _CURSES_SAVETTY_METHODDEF + _CURSES_GET_ESCDELAY_METHODDEF + _CURSES_SET_ESCDELAY_METHODDEF + _CURSES_GET_TABSIZE_METHODDEF + _CURSES_SET_TABSIZE_METHODDEF _CURSES_SETSYX_METHODDEF _CURSES_SETUPTERM_METHODDEF _CURSES_START_COLOR_METHODDEF diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index ad93e6a..7b30a49 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -3040,6 +3040,128 @@ exit: return return_value; } +PyDoc_STRVAR(_curses_get_escdelay__doc__, +"get_escdelay($module, /)\n" +"--\n" +"\n" +"Gets the curses ESCDELAY setting.\n" +"\n" +"Gets the number of milliseconds to wait after reading an escape character,\n" +"to distinguish between an individual escape character entered on the\n" +"keyboard from escape sequences sent by cursor and function keys."); + +#define _CURSES_GET_ESCDELAY_METHODDEF \ + {"get_escdelay", (PyCFunction)_curses_get_escdelay, METH_NOARGS, _curses_get_escdelay__doc__}, + +static PyObject * +_curses_get_escdelay_impl(PyObject *module); + +static PyObject * +_curses_get_escdelay(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_get_escdelay_impl(module); +} + +PyDoc_STRVAR(_curses_set_escdelay__doc__, +"set_escdelay($module, ms, /)\n" +"--\n" +"\n" +"Sets the curses ESCDELAY setting.\n" +"\n" +" ms\n" +" length of the delay in milliseconds.\n" +"\n" +"Sets the number of milliseconds to wait after reading an escape character,\n" +"to distinguish between an individual escape character entered on the\n" +"keyboard from escape sequences sent by cursor and function keys."); + +#define _CURSES_SET_ESCDELAY_METHODDEF \ + {"set_escdelay", (PyCFunction)_curses_set_escdelay, METH_O, _curses_set_escdelay__doc__}, + +static PyObject * +_curses_set_escdelay_impl(PyObject *module, int ms); + +static PyObject * +_curses_set_escdelay(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int ms; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + ms = _PyLong_AsInt(arg); + if (ms == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_set_escdelay_impl(module, ms); + +exit: + return return_value; +} + +PyDoc_STRVAR(_curses_get_tabsize__doc__, +"get_tabsize($module, /)\n" +"--\n" +"\n" +"Gets the curses TABSIZE setting.\n" +"\n" +"Gets the number of columns used by the curses library when converting a tab\n" +"character to spaces as it adds the tab to a window."); + +#define _CURSES_GET_TABSIZE_METHODDEF \ + {"get_tabsize", (PyCFunction)_curses_get_tabsize, METH_NOARGS, _curses_get_tabsize__doc__}, + +static PyObject * +_curses_get_tabsize_impl(PyObject *module); + +static PyObject * +_curses_get_tabsize(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _curses_get_tabsize_impl(module); +} + +PyDoc_STRVAR(_curses_set_tabsize__doc__, +"set_tabsize($module, size, /)\n" +"--\n" +"\n" +"Sets the curses TABSIZE setting.\n" +"\n" +" size\n" +" rendered cell width of a tab character.\n" +"\n" +"Sets the number of columns used by the curses library when converting a tab\n" +"character to spaces as it adds the tab to a window."); + +#define _CURSES_SET_TABSIZE_METHODDEF \ + {"set_tabsize", (PyCFunction)_curses_set_tabsize, METH_O, _curses_set_tabsize__doc__}, + +static PyObject * +_curses_set_tabsize_impl(PyObject *module, int size); + +static PyObject * +_curses_set_tabsize(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int size; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + size = _PyLong_AsInt(arg); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _curses_set_tabsize_impl(module, size); + +exit: + return return_value; +} + PyDoc_STRVAR(_curses_intrflush__doc__, "intrflush($module, flag, /)\n" "--\n" @@ -4569,4 +4691,4 @@ _curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF #define _CURSES_USE_DEFAULT_COLORS_METHODDEF #endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ -/*[clinic end generated code: output=e5b3502f1d38dff0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=985c0849e841acec input=a9049054013a1b77]*/ -- cgit v0.12