📄 if_python.c
字号:
if (len > 45)
name = name + (45 - len);
sprintf(repr, "<range %s%s (%d:%d)>",
len > 45 ? "..." : "", name,
this->start, this->end);
return PyString_FromString(repr);
}
}
/****************/
static int
RangeLength(PyObject *self)
{
/* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
if (CheckBuffer(((RangeObject *)(self))->buf))
return -1; /* ??? */
return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
}
static PyObject *
RangeItem(PyObject *self, int n)
{
return RBItem(((RangeObject *)(self))->buf, n,
((RangeObject *)(self))->start,
((RangeObject *)(self))->end);
}
static PyObject *
RangeSlice(PyObject *self, int lo, int hi)
{
return RBSlice(((RangeObject *)(self))->buf, lo, hi,
((RangeObject *)(self))->start,
((RangeObject *)(self))->end);
}
static int
RangeAssItem(PyObject *self, int n, PyObject *val)
{
return RBAssItem(((RangeObject *)(self))->buf, n, val,
((RangeObject *)(self))->start,
((RangeObject *)(self))->end,
&((RangeObject *)(self))->end);
}
static int
RangeAssSlice(PyObject *self, int lo, int hi, PyObject *val)
{
return RBAssSlice(((RangeObject *)(self))->buf, lo, hi, val,
((RangeObject *)(self))->start,
((RangeObject *)(self))->end,
&((RangeObject *)(self))->end);
}
static PyObject *
RangeAppend(PyObject *self, PyObject *args)
{
return RBAppend(((RangeObject *)(self))->buf, args,
((RangeObject *)(self))->start,
((RangeObject *)(self))->end,
&((RangeObject *)(self))->end);
}
/* Buffer list object - Definitions
*/
typedef struct
{
PyObject_HEAD
}
BufListObject;
static PySequenceMethods BufListAsSeq = {
(inquiry) BufListLength, /* sq_length, len(x) */
(binaryfunc) 0, /* sq_concat, x+y */
(intargfunc) 0, /* sq_repeat, x*n */
(intargfunc) BufListItem, /* sq_item, x[i] */
(intintargfunc) 0, /* sq_slice, x[i:j] */
(intobjargproc) 0, /* sq_ass_item, x[i]=v */
(intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
};
static PyTypeObject BufListType = {
PyObject_HEAD_INIT(0)
0,
"buffer list",
sizeof(BufListObject),
0,
(destructor) 0, /* tp_dealloc, refcount==0 */
(printfunc) 0, /* tp_print, print x */
(getattrfunc) 0, /* tp_getattr, x.attr */
(setattrfunc) 0, /* tp_setattr, x.attr=v */
(cmpfunc) 0, /* tp_compare, x>y */
(reprfunc) 0, /* tp_repr, `x`, print x */
0, /* as number */
&BufListAsSeq, /* as sequence */
0, /* as mapping */
(hashfunc) 0, /* tp_hash, dict(x) */
(ternaryfunc) 0, /* tp_call, x() */
(reprfunc) 0, /* tp_str, str(x) */
};
/* Buffer list object - Implementation
*/
/*ARGSUSED*/
static int
BufListLength(PyObject *self)
{
BUF *b = firstbuf;
int n = 0;
while (b)
{
++n;
b = b->b_next;
}
return n;
}
/*ARGSUSED*/
static PyObject *
BufListItem(PyObject *self, int n)
{
BUF *b;
for (b = firstbuf; b; b = b->b_next, --n)
{
if (n == 0)
return BufferNew(b);
}
PyErr_SetString(PyExc_IndexError, "no such buffer");
return NULL;
}
/* Window object - Definitions
*/
static struct PyMethodDef WindowMethods[] = {
/* name, function, calling, documentation */
{ NULL, NULL, 0, NULL }
};
static PyTypeObject WindowType = {
PyObject_HEAD_INIT(0)
0,
"window",
sizeof(WindowObject),
0,
(destructor) WindowDestructor, /* tp_dealloc, refcount==0 */
(printfunc) 0, /* tp_print, print x */
(getattrfunc) WindowGetattr, /* tp_getattr, x.attr */
(setattrfunc) WindowSetattr, /* tp_setattr, x.attr=v */
(cmpfunc) 0, /* tp_compare, x>y */
(reprfunc) WindowRepr, /* tp_repr, `x`, print x */
0, /* as number */
0, /* as sequence */
0, /* as mapping */
(hashfunc) 0, /* tp_hash, dict(x) */
(ternaryfunc) 0, /* tp_call, x() */
(reprfunc) 0, /* tp_str, str(x) */
};
/* Window object - Implementation
*/
static PyObject *
WindowNew(WIN *win)
{
/* We need to handle deletion of windows underneath us.
* If we add a "python_ref" field to the WIN structure,
* then we can get at it in win_free() in vim. We then
* need to create only ONE Python object per window - if
* we try to create a second, just INCREF the existing one
* and return it. The (single) Python object referring to
* the window is stored in "python_ref".
* On a win_free() we set the Python object's WIN* field
* to an invalid value. We trap all uses of a window
* object, and reject them if the WIN* field is invalid.
*/
WindowObject *self;
if (win->python_ref)
self = win->python_ref;
else
{
self = PyObject_NEW(WindowObject, &WindowType);
if (self == NULL)
return NULL;
self->win = win;
win->python_ref = self;
}
return (PyObject *)(self);
}
static void
WindowDestructor(PyObject *self)
{
WindowObject *this = (WindowObject *)(self);
if (this->win && this->win != INVALID_WINDOW_VALUE)
this->win->python_ref = NULL;
PyMem_DEL(self);
}
static int
CheckWindow(WindowObject *this)
{
if (this->win == INVALID_WINDOW_VALUE)
{
PyErr_SetVim("attempt to refer to deleted window");
return -1;
}
return 0;
}
static PyObject *
WindowGetattr(PyObject *self, char *name)
{
WindowObject *this = (WindowObject *)(self);
if (CheckWindow(this))
return NULL;
if (strcmp(name, "buffer") == 0)
return (PyObject *)BufferNew(this->win->w_buffer);
else if (strcmp(name, "cursor") == 0)
{
FPOS *pos = &this->win->w_cursor;
return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
}
else if (strcmp(name, "height") == 0)
return Py_BuildValue("l", (long)(this->win->w_height));
else if (strcmp(name,"__members__") == 0)
return Py_BuildValue("[sss]", "buffer", "cursor", "height");
else
return Py_FindMethod(WindowMethods, self, name);
}
static int
WindowSetattr(PyObject *self, char *name, PyObject *val)
{
WindowObject *this = (WindowObject *)(self);
if (CheckWindow(this))
return -1;
if (strcmp(name, "buffer") == 0)
{
PyErr_SetString(PyExc_TypeError, "readonly attribute");
return -1;
}
else if (strcmp(name, "cursor") == 0)
{
long lnum;
long col;
if (!PyArg_Parse(val, "(ll)", &lnum, &col))
return -1;
if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
{
PyErr_SetVim("cursor position outside buffer");
return -1;
}
/* Check for keyboard interrupts */
if (VimErrorCheck())
return -1;
/* NO CHECK ON COLUMN - SEEMS NOT TO MATTER */
this->win->w_cursor.lnum = lnum;
this->win->w_cursor.col = col;
update_screen(NOT_VALID);
return 0;
}
else if (strcmp(name, "height") == 0)
{
int height;
WIN *savewin;
if (!PyArg_Parse(val, "i", &height))
return -1;
#ifdef USE_GUI
need_mouse_correct = TRUE;
#endif
savewin = curwin;
curwin = this->win;
win_setheight(height);
curwin = savewin;
/* Check for keyboard interrupts */
if (VimErrorCheck())
return -1;
return 0;
}
else
{
PyErr_SetString(PyExc_AttributeError, name);
return -1;
}
}
static PyObject *
WindowRepr(PyObject *self)
{
static char repr[50];
WindowObject *this = (WindowObject *)(self);
if (this->win == INVALID_WINDOW_VALUE)
{
sprintf(repr, "<window object (deleted) at %.8lX>", (long)(self));
return PyString_FromString(repr);
}
else
{
int i = 0;
WIN *w;
for (w = firstwin; w != NULL && w != this->win; w = w->w_next)
++i;
if (w == NULL)
sprintf(repr, "<window object (unknown) at %.8lX>", (long)(self));
else
sprintf(repr, "<window %d>", i);
return PyString_FromString(repr);
}
}
/* Window list object - Definitions
*/
typedef struct
{
PyObject_HEAD
}
WinListObject;
static PySequenceMethods WinListAsSeq = {
(inquiry) WinListLength, /* sq_length, len(x) */
(binaryfunc) 0, /* sq_concat, x+y */
(intargfunc) 0, /* sq_repeat, x*n */
(intargfunc) WinListItem, /* sq_item, x[i] */
(intintargfunc) 0, /* sq_slice, x[i:j] */
(intobjargproc) 0, /* sq_ass_item, x[i]=v */
(intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
};
static PyTypeObject WinListType = {
PyObject_HEAD_INIT(0)
0,
"window list",
sizeof(WinListObject),
0,
(destructor) 0, /* tp_dealloc, refcount==0 */
(printfunc) 0, /* tp_print, print x */
(getattrfunc) 0, /* tp_getattr, x.attr */
(setattrfunc) 0, /* tp_setattr, x.attr=v */
(cmpfunc) 0, /* tp_compare, x>y */
(reprfunc) 0, /* tp_repr, `x`, print x */
0, /* as number */
&WinListAsSeq, /* as sequence */
0, /* as mapping */
(hashfunc) 0, /* tp_hash, dict(x) */
(ternaryfunc) 0, /* tp_call, x() */
(reprfunc) 0, /* tp_str, str(x) */
};
/* Window list object - Implementation
*/
/*ARGSUSED*/
static int
WinListLength(PyObject *self)
{
WIN *w = firstwin;
int n = 0;
while (w)
{
++n;
w = w->w_next;
}
return n;
}
/*ARGSUSED*/
static PyObject *
WinListItem(PyObject *self, int n)
{
WIN *w;
for (w = firstwin; w; w = w->w_next, --n)
{
if (n == 0)
return WindowNew(w);
}
PyErr_SetString(PyExc_IndexError, "no such window");
return NULL;
}
/* Current items object - Definitions
*/
typedef struct
{
PyObject_HEAD
}
CurrentObject;
static PyTypeObject CurrentType = {
PyObject_HEAD_INIT(0)
0,
"current data",
sizeof(CurrentObject),
0,
(destructor) 0, /* tp_dealloc, refcount==0 */
(printfunc) 0, /* tp_print, print x */
(getattrfunc) CurrentGetattr, /* tp_getattr, x.attr */
(setattrfunc) CurrentSetattr, /* tp_setattr, x.attr=v */
(cmpfunc) 0, /* tp_compare, x>y */
(reprfunc) 0, /* tp_repr, `x`, print x */
0, /* as number */
0, /* as sequence */
0, /* as mapping */
(hashfunc) 0, /* tp_hash, dict(x) */
(ternaryfunc) 0, /* tp_call, x() */
(reprfunc) 0, /* tp_str, str(x) */
};
/* Current items object - Implementation
*/
/*ARGSUSED*/
static PyObject *
CurrentGetattr(PyObject *self, char *name)
{
if (strcmp(name, "buffer") == 0)
return (PyObject *)BufferNew(curbuf);
else if (strcmp(name, "window") == 0)
return (PyObject *)WindowNew(curwin);
else if (strcmp(name, "line") == 0)
return GetBufferLine(curbuf, (int)curwin->w_cursor.lnum);
else if (strcmp(name, "range") == 0)
return RangeNew(curbuf, RangeStart, RangeEnd);
else if (strcmp(name,"__members__") == 0)
return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
else
{
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
}
}
/*ARGSUSED*/
static int
CurrentSetattr(PyObject *self, char *name, PyObject *value)
{
if (strcmp(name, "line") == 0)
{
if (SetBufferLine(curbuf, (int)curwin->w_cursor.lnum, value, NULL) == FAIL)
return -1;
return 0;
}
else
{
PyErr_SetString(PyExc_AttributeError, name);
return -1;
}
}
/* External interface
*/
void
python_buffer_free(BUF *buf)
{
if (buf->python_ref)
{
BufferObject *bp = buf->python_ref;
bp->buf = INVALID_BUFFER_VALUE;
buf->python_ref = NULL;
}
}
void
python_window_free(WIN *win)
{
if (win->python_ref)
{
WindowObject *wp = win->python_ref;
wp->win = INVALID_WINDOW_VALUE;
win->python_ref = NULL;
}
}
static BufListObject TheBufferList =
{
PyObject_HEAD_INIT(&BufListType)
};
static WinListObject TheWindowList =
{
PyObject_HEAD_INIT(&WinListType)
};
static CurrentObject TheCurrent =
{
PyObject_HEAD_INIT(&CurrentType)
};
static int
PythonMod_Init(void)
{
PyObject *mod;
PyObject *dict;
/* Fixups... */
BufferType.ob_type = &PyType_Type;
RangeType.ob_type = &PyType_Type;
WindowType.ob_type = &PyType_Type;
BufListType.ob_type = &PyType_Type;
WinListType.ob_type = &PyType_Type;
CurrentType.ob_type = &PyType_Type;
mod = Py_InitModule("vim", VimMethods);
dict = PyModule_GetDict(mod);
VimError = Py_BuildValue("s", "vim.error");
PyDict_SetItemString(dict, "error", VimError);
PyDict_SetItemString(dict, "buffers", (PyObject *)(&TheBufferList));
PyDict_SetItemString(dict, "current", (PyObject *)(&TheCurrent));
PyDict_SetItemString(dict, "windows", (PyObject *)(&TheWindowList));
if (PyErr_Occurred())
return -1;
return 0;
}
/*************************************************************************
* 4. Utility functions for handling the interface between Vim and Python.
*/
/* Get a line from the specified buffer. The line number is
* in Vim format (1-based). The line is returned as a Python
* string object.
*/
static PyObject *
GetBufferLine(BUF *buf, int n)
{
return LineToString((char *)ml_get_buf(buf, (linenr_t)n, FALSE));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -