⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_python.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 4 页
字号:
static PyObject *RangeAppend(PyObject *, PyObject *);

/* Window list type - Implementation functions
 * -------------------------------------------
 */

static int WinListLength(PyObject *);
static PyObject *WinListItem(PyObject *, int);

/* Buffer list type - Implementation functions
 * -------------------------------------------
 */

static int BufListLength(PyObject *);
static PyObject *BufListItem(PyObject *, int);

/* Current objects type - Implementation functions
 * -----------------------------------------------
 */

static PyObject *CurrentGetattr(PyObject *, char *);
static int CurrentSetattr(PyObject *, char *, PyObject *);

/* Vim module - Definitions
 */

static struct PyMethodDef VimMethods[] = {
    /* name,	     function,		calling,    documentation */
    {"command",	     VimCommand,	1,	    "" },
    {"eval",	     VimEval,		1,	    "" },
    { NULL,	     NULL,		0,	    NULL }
};

/* Vim module - Implementation
 */
/*ARGSUSED*/
    static PyObject *
VimCommand(PyObject *self, PyObject *args)
{
    char *cmd;
    PyObject *result;

    if (!PyArg_ParseTuple(args, "s", &cmd))
	return NULL;

    PyErr_Clear();

    Py_BEGIN_ALLOW_THREADS
    Python_Lock_Vim();

    do_cmdline((char_u *)cmd, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
    update_screen(NOT_VALID);

    Python_Release_Vim();
    Py_END_ALLOW_THREADS

    if (VimErrorCheck())
	result = NULL;
    else
	result = Py_None;

    Py_XINCREF(result);
    return result;
}

/*ARGSUSED*/
    static PyObject *
VimEval(PyObject *self, PyObject *args)
{
    char *expr;
    char *str;
    PyObject *result;

    if (!PyArg_ParseTuple(args, "s", &expr))
	return NULL;

#ifdef WANT_EVAL
    Py_BEGIN_ALLOW_THREADS
    Python_Lock_Vim();
    str = (char *)eval_to_string((char_u *)expr, NULL);
    Python_Release_Vim();
    Py_END_ALLOW_THREADS

    if (str == NULL)
    {
	PyErr_SetVim("invalid expression");
	return NULL;
    }
#else
    PyErr_SetVim("expressions disabled at compile time");
    return NULL;
#endif

    result = Py_BuildValue("s", str);

    Py_BEGIN_ALLOW_THREADS
    Python_Lock_Vim();
    vim_free(str);
    Python_Release_Vim();
    Py_END_ALLOW_THREADS

    return result;
}

/* Common routines for buffers and line ranges
 * -------------------------------------------
 */
    static int
CheckBuffer(BufferObject *this)
{
    if (this->buf == INVALID_BUFFER_VALUE)
    {
	PyErr_SetVim("attempt to refer to deleted buffer");
	return -1;
    }

    return 0;
}

    static PyObject *
RBItem(BufferObject *self, int n, int start, int end)
{
    if (CheckBuffer(self))
	return NULL;

    if (n < 0 || n > end - start)
    {
	PyErr_SetString(PyExc_IndexError, "line number out of range");
	return NULL;
    }

    return GetBufferLine(self->buf, n+start);
}

    static PyObject *
RBSlice(BufferObject *self, int lo, int hi, int start, int end)
{
    int size;

    if (CheckBuffer(self))
	return NULL;

    size = end - start + 1;

    if (lo < 0)
	lo = 0;
    else if (lo > size)
	lo = size;
    if (hi < 0)
	hi = 0;
    if (hi < lo)
	hi = lo;
    else if (hi > size)
	hi = size;

    return GetBufferLineList(self->buf, lo+start, hi+start);
}

    static int
RBAssItem(BufferObject *self, int n, PyObject *val, int start, int end, int *new_end)
{
    int len_change;

    if (CheckBuffer(self))
	return -1;

    if (n < 0 || n > end - start)
    {
	PyErr_SetString(PyExc_IndexError, "line number out of range");
	return -1;
    }

    if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
	return -1;

    if (new_end)
	*new_end = end + len_change;

    return 0;
}

    static int
RBAssSlice(BufferObject *self, int lo, int hi, PyObject *val, int start, int end, int *new_end)
{
    int size;
    int len_change;

    /* Self must be a valid buffer */
    if (CheckBuffer(self))
	return -1;

    /* Sort out the slice range */
    size = end - start + 1;

    if (lo < 0)
	lo = 0;
    else if (lo > size)
	lo = size;
    if (hi < 0)
	hi = 0;
    if (hi < lo)
	hi = lo;
    else if (hi > size)
	hi = size;

    if (SetBufferLineList(self->buf, lo+start, hi+start, val, &len_change) == FAIL)
	return -1;

    if (new_end)
	*new_end = end + len_change;

    return 0;
}

    static PyObject *
RBAppend(BufferObject *self, PyObject *args, int start, int end, int *new_end)
{
    PyObject *lines;
    int len_change;
    int max;
    int n;

    if (CheckBuffer(self))
	return NULL;

    max = n = end - start + 1;

    if (!PyArg_ParseTuple(args, "O|i", &lines, &n))
	return NULL;

    if (n < 0 || n > max)
    {
	PyErr_SetString(PyExc_ValueError, "line number out of range");
	return NULL;
    }

    if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
	return NULL;

    if (new_end)
	*new_end = end + len_change;

    Py_INCREF(Py_None);
    return Py_None;
}


/* Buffer object - Definitions
 */

static struct PyMethodDef BufferMethods[] = {
    /* name,	    function,		calling,    documentation */
    {"append",	    BufferAppend,	1,	    "" },
    {"mark",	    BufferMark,		1,	    "" },
    {"range",	    BufferRange,	1,	    "" },
    { NULL,	    NULL,		0,	    NULL }
};

static PySequenceMethods BufferAsSeq = {
    (inquiry)		BufferLength,	    /* sq_length,    len(x)   */
    (binaryfunc)	0, /* BufferConcat, */	     /* sq_concat,    x+y      */
    (intargfunc)	0, /* BufferRepeat, */	     /* sq_repeat,    x*n      */
    (intargfunc)	BufferItem,	    /* sq_item,      x[i]     */
    (intintargfunc)	BufferSlice,	    /* sq_slice,     x[i:j]   */
    (intobjargproc)	BufferAssItem,	    /* sq_ass_item,  x[i]=v   */
    (intintobjargproc)	BufferAssSlice,     /* sq_ass_slice, x[i:j]=v */
};

static PyTypeObject BufferType = {
    PyObject_HEAD_INIT(0)
    0,
    "buffer",
    sizeof(BufferObject),
    0,

    (destructor)    BufferDestructor,	/* tp_dealloc,	refcount==0  */
    (printfunc)     0,			/* tp_print,	print x      */
    (getattrfunc)   BufferGetattr,	/* tp_getattr,	x.attr	     */
    (setattrfunc)   0,			/* tp_setattr,	x.attr=v     */
    (cmpfunc)	    0,			/* tp_compare,	x>y	     */
    (reprfunc)	    BufferRepr,		/* tp_repr,	`x`, print x */

    0,		    /* as number */
    &BufferAsSeq,   /* as sequence */
    0,		    /* as mapping */

    (hashfunc) 0,			/* tp_hash, dict(x) */
    (ternaryfunc) 0,			/* tp_call, x()     */
    (reprfunc) 0,			/* tp_str,  str(x)  */
};

/* Buffer object - Implementation
 */

    static PyObject *
BufferNew(BUF *buf)
{
    /* We need to handle deletion of buffers underneath us.
     * If we add a "python_ref" field to the BUF structure,
     * then we can get at it in buf_freeall() in vim. We then
     * need to create only ONE Python object per buffer - if
     * we try to create a second, just INCREF the existing one
     * and return it. The (single) Python object referring to
     * the buffer is stored in "python_ref".
     * Question: what to do on a buf_freeall(). We'll probably
     * have to either delete the Python object (DECREF it to
     * zero - a bad idea, as it leaves dangling refs!) or
     * set the BUF* value to an invalid value (-1?), which
     * means we need checks in all access functions... Bah.
     */

    BufferObject *self;

    if (buf->python_ref)
	self = buf->python_ref;
    else
    {
	self = PyObject_NEW(BufferObject, &BufferType);
	if (self == NULL)
	    return NULL;
	self->buf = buf;
	buf->python_ref = self;
    }

    return (PyObject *)(self);
}

    static void
BufferDestructor(PyObject *self)
{
    BufferObject *this = (BufferObject *)(self);

    if (this->buf && this->buf != INVALID_BUFFER_VALUE)
	this->buf->python_ref = NULL;

    PyMem_DEL(self);
}

    static PyObject *
BufferGetattr(PyObject *self, char *name)
{
    BufferObject *this = (BufferObject *)(self);

    if (CheckBuffer(this))
	return NULL;

    if (strcmp(name, "name") == 0)
	return Py_BuildValue("s",this->buf->b_ffname);
    else if (strcmp(name,"__members__") == 0)
	return Py_BuildValue("[s]", "name");
    else
	return Py_FindMethod(BufferMethods, self, name);
}

    static PyObject *
BufferRepr(PyObject *self)
{
    static char repr[50];
    BufferObject *this = (BufferObject *)(self);

    if (this->buf == INVALID_BUFFER_VALUE)
    {
	sprintf(repr, "<buffer object (deleted) at %8lX>", (long)(self));
	return PyString_FromString(repr);
    }
    else
    {
	char *name = (char *)this->buf->b_fname;
	int len = strlen(name);

	if (len > 35)
	    name = name + (35 - len);

	sprintf(repr, "<buffer %s%s>", len > 35 ? "..." : "", name);

	return PyString_FromString(repr);
    }
}

/******************/

    static int
BufferLength(PyObject *self)
{
    /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
    if (CheckBuffer((BufferObject *)(self)))
	return -1; /* ??? */

    return (((BufferObject *)(self))->buf->b_ml.ml_line_count);
}

    static PyObject *
BufferItem(PyObject *self, int n)
{
    return RBItem((BufferObject *)(self), n, 1,
		  (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
}

    static PyObject *
BufferSlice(PyObject *self, int lo, int hi)
{
    return RBSlice((BufferObject *)(self), lo, hi, 1,
		   (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
}

    static int
BufferAssItem(PyObject *self, int n, PyObject *val)
{
    return RBAssItem((BufferObject *)(self), n, val, 1,
		     (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
		     NULL);
}

    static int
BufferAssSlice(PyObject *self, int lo, int hi, PyObject *val)
{
    return RBAssSlice((BufferObject *)(self), lo, hi, val, 1,
		      (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
		      NULL);
}

    static PyObject *
BufferAppend(PyObject *self, PyObject *args)
{
    return RBAppend((BufferObject *)(self), args, 1,
		    (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
		    NULL);
}

    static PyObject *
BufferMark(PyObject *self, PyObject *args)
{
    FPOS    *posp;
    char    mark;
    BUF	    *curbuf_save;

    if (CheckBuffer((BufferObject *)(self)))
	return NULL;

    if (!PyArg_ParseTuple(args, "c", &mark))
	return NULL;

    curbuf_save = curbuf;
    curbuf = ((BufferObject *)(self))->buf;
    posp = getmark(mark, FALSE);
    curbuf = curbuf_save;

    if (posp == NULL)
    {
	PyErr_SetVim("invalid mark name");
	return NULL;
    }

    /* Ckeck for keyboard interrupt */
    if (VimErrorCheck())
	return NULL;

    if (posp->lnum == 0)
    {
	/* Or raise an error? */
	Py_INCREF(Py_None);
	return Py_None;
    }

    return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
}

    static PyObject *
BufferRange(PyObject *self, PyObject *args)
{
    int start;
    int end;

    if (CheckBuffer((BufferObject *)(self)))
	return NULL;

    if (!PyArg_ParseTuple(args, "ii", &start, &end))
	return NULL;

    return RangeNew(((BufferObject *)(self))->buf, start, end);
}

/* Line range object - Definitions
 */

static struct PyMethodDef RangeMethods[] = {
    /* name,	    function,		calling,    documentation */
    {"append",	    RangeAppend,	1,	    "" },
    { NULL,	    NULL,		0,	    NULL }
};

static PySequenceMethods RangeAsSeq = {
    (inquiry)		RangeLength,	    /* sq_length,    len(x)   */
    (binaryfunc)	0, /* RangeConcat, */	     /* sq_concat,    x+y      */
    (intargfunc)	0, /* RangeRepeat, */	     /* sq_repeat,    x*n      */
    (intargfunc)	RangeItem,	    /* sq_item,      x[i]     */
    (intintargfunc)	RangeSlice,	    /* sq_slice,     x[i:j]   */
    (intobjargproc)	RangeAssItem,	    /* sq_ass_item,  x[i]=v   */
    (intintobjargproc)	RangeAssSlice,	    /* sq_ass_slice, x[i:j]=v */
};

static PyTypeObject RangeType = {
    PyObject_HEAD_INIT(0)
    0,
    "range",
    sizeof(RangeObject),
    0,

    (destructor)    RangeDestructor,	/* tp_dealloc,	refcount==0  */
    (printfunc)     0,			/* tp_print,	print x      */
    (getattrfunc)   RangeGetattr,	/* tp_getattr,	x.attr	     */
    (setattrfunc)   0,			/* tp_setattr,	x.attr=v     */
    (cmpfunc)	    0,			/* tp_compare,	x>y	     */
    (reprfunc)	    RangeRepr,		/* tp_repr,	`x`, print x */

    0,		    /* as number */
    &RangeAsSeq,    /* as sequence */
    0,		    /* as mapping */

    (hashfunc) 0,			/* tp_hash, dict(x) */
    (ternaryfunc) 0,			/* tp_call, x()     */
    (reprfunc) 0,			/* tp_str,  str(x)  */
};

/* Line range object - Implementation
 */

    static PyObject *
RangeNew(BUF *buf, int start, int end)
{
    BufferObject *bufr;
    RangeObject *self;
    self = PyObject_NEW(RangeObject, &RangeType);
    if (self == NULL)
	return NULL;

    bufr = (BufferObject *)BufferNew(buf);
    if (bufr == NULL)
    {
	PyMem_DEL(self);
	return NULL;
    }
    Py_INCREF(bufr);

    self->buf = bufr;
    self->start = start;
    self->end = end;

    return (PyObject *)(self);
}

    static void
RangeDestructor(PyObject *self)
{
    Py_DECREF(((RangeObject *)(self))->buf);
    PyMem_DEL(self);
}

    static PyObject *
RangeGetattr(PyObject *self, char *name)
{
    return Py_FindMethod(RangeMethods, self, name);
}

    static PyObject *
RangeRepr(PyObject *self)
{
    static char repr[75];
    RangeObject *this = (RangeObject *)(self);

    if (this->buf->buf == INVALID_BUFFER_VALUE)
    {
	sprintf(repr, "<range object (for deleted buffer) at %8lX>",
								(long)(self));
	return PyString_FromString(repr);
    }
    else
    {
	char *name = (char *)this->buf->buf->b_fname;
	int len = strlen(name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -