forked from bartvdbraak/blender
Added a documentation panel with primitive word-wrap functionality. It can be displayed by Text.showDoc(string) in python and has a text-plugin script for function docs which may be invoked with Ctrl+I inside its params list. Eg. type "dir(" <Ctrl+I>
This commit is contained in:
parent
b205cf34b4
commit
123407e0b4
68
release/scripts/textplugin_functiondocs.py
Normal file
68
release/scripts/textplugin_functiondocs.py
Normal file
@ -0,0 +1,68 @@
|
||||
#!BPY
|
||||
"""
|
||||
Name: 'Function Documentation'
|
||||
Blender: 246
|
||||
Group: 'TextPlugin'
|
||||
Shortcut: 'Ctrl+I'
|
||||
Tooltip: 'Attempts to display documentation about the function preceding the cursor.'
|
||||
"""
|
||||
|
||||
# Only run if we have the required modules
|
||||
try:
|
||||
import bpy
|
||||
from BPyTextPlugin import *
|
||||
OK = True
|
||||
except ImportError:
|
||||
OK = False
|
||||
|
||||
def main():
|
||||
txt = bpy.data.texts.active
|
||||
if not txt:
|
||||
return
|
||||
|
||||
(line, c) = current_line(txt)
|
||||
|
||||
# Check we are in a normal context
|
||||
if get_context(txt) != NORMAL:
|
||||
return
|
||||
|
||||
# Look backwards for first '(' without ')'
|
||||
b = 0
|
||||
for i in range(c-1, -1, -1):
|
||||
if line[i] == ')': b += 1
|
||||
elif line[i] == '(':
|
||||
b -= 1
|
||||
if b < 0:
|
||||
c = i
|
||||
break
|
||||
|
||||
pre = get_targets(line, c)
|
||||
|
||||
if len(pre) == 0:
|
||||
return
|
||||
|
||||
imports = get_imports(txt)
|
||||
builtins = get_builtins()
|
||||
|
||||
# Identify the root (root.sub.sub.)
|
||||
if imports.has_key(pre[0]):
|
||||
obj = imports[pre[0]]
|
||||
elif builtins.has_key(pre[0]):
|
||||
obj = builtins[pre[0]]
|
||||
else:
|
||||
return
|
||||
|
||||
# Step through sub-attributes
|
||||
try:
|
||||
for name in pre[1:]:
|
||||
obj = getattr(obj, name)
|
||||
except AttributeError:
|
||||
print "Attribute not found '%s' in '%s'" % (name, '.'.join(pre))
|
||||
return
|
||||
|
||||
if hasattr(obj, '__doc__') and obj.__doc__:
|
||||
txt.showDocs(obj.__doc__)
|
||||
|
||||
# Check we are running as a script and not imported as a module
|
||||
if __name__ == "__main__" and OK:
|
||||
main()
|
@ -60,20 +60,26 @@ typedef struct SuggList {
|
||||
SuggItem *selected;
|
||||
} SuggList;
|
||||
|
||||
/* Free all suggestion related memory */
|
||||
void free_suggestions();
|
||||
|
||||
/* Used to identify which Text object the current tools should appear against */
|
||||
void suggest_set_active(Text *text);
|
||||
void suggest_clear_active();
|
||||
short suggest_is_active(Text *text);
|
||||
|
||||
void suggest_add(const char *name, char type);
|
||||
void suggest_prefix(const char *prefix);
|
||||
SuggItem *suggest_first();
|
||||
SuggItem *suggest_last();
|
||||
|
||||
void suggest_set_text(Text *text);
|
||||
void suggest_clear_text();
|
||||
short suggest_is_active(Text *text);
|
||||
|
||||
void suggest_set_selected(SuggItem *sel);
|
||||
SuggItem *suggest_get_selected();
|
||||
|
||||
void suggest_documentation(const char *docs);
|
||||
char *suggest_get_docs();
|
||||
void suggest_clear_docs();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -37,20 +37,23 @@
|
||||
#include "BKE_text.h"
|
||||
#include "BKE_suggestions.h"
|
||||
|
||||
static SuggList suggestions= {NULL, NULL, NULL, NULL, NULL};
|
||||
static SuggList suggestions = {NULL, NULL, NULL, NULL, NULL};
|
||||
static Text *suggText = NULL;
|
||||
static SuggItem *lastInsert= NULL;
|
||||
static SuggItem *lastInsert = NULL;
|
||||
static char *documentation = NULL;
|
||||
static int doc_lines = 0;
|
||||
|
||||
static suggest_cmp(const char *first, const char *second, int len) {
|
||||
static int suggest_cmp(const char *first, const char *second, int len) {
|
||||
int cmp, i;
|
||||
for (cmp=0, i=0; i<len; i++) {
|
||||
if (cmp= toupper(first[i]) - toupper(second[i])) {
|
||||
if (cmp= toupper(first[i])-toupper(second[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
void free_suggestions() {
|
||||
|
||||
static void sugg_free() {
|
||||
SuggItem *item, *prev;
|
||||
for (item = suggestions.last; item; item=prev) {
|
||||
prev = item->prev;
|
||||
@ -61,6 +64,18 @@ void free_suggestions() {
|
||||
suggestions.selected = NULL;
|
||||
}
|
||||
|
||||
static void docs_free() {
|
||||
if (documentation) {
|
||||
MEM_freeN(documentation);
|
||||
documentation = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void free_suggestions() {
|
||||
sugg_free();
|
||||
docs_free();
|
||||
}
|
||||
|
||||
void suggest_add(const char *name, char type) {
|
||||
SuggItem *newitem;
|
||||
|
||||
@ -87,7 +102,7 @@ void suggest_add(const char *name, char type) {
|
||||
|
||||
void suggest_prefix(const char *prefix) {
|
||||
SuggItem *match, *first, *last;
|
||||
int cmp, len = strlen(prefix), i;
|
||||
int cmp, len = strlen(prefix);
|
||||
|
||||
if (!suggestions.first) return;
|
||||
if (len==0) {
|
||||
@ -111,10 +126,13 @@ void suggest_prefix(const char *prefix) {
|
||||
}
|
||||
if (first) {
|
||||
if (!last) last = suggestions.last;
|
||||
suggestions.selected = suggestions.firstmatch = first;
|
||||
suggestions.firstmatch = first;
|
||||
suggestions.lastmatch = last;
|
||||
suggestions.selected = first;
|
||||
} else {
|
||||
suggestions.firstmatch = suggestions.lastmatch = NULL;
|
||||
suggestions.firstmatch = NULL;
|
||||
suggestions.lastmatch = NULL;
|
||||
suggestions.selected = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,11 +144,13 @@ SuggItem *suggest_last() {
|
||||
return suggestions.lastmatch;
|
||||
}
|
||||
|
||||
void suggest_set_text(Text *text) {
|
||||
void suggest_set_active(Text *text) {
|
||||
if (suggText == text) return;
|
||||
suggest_clear_active();
|
||||
suggText = text;
|
||||
}
|
||||
|
||||
void suggest_clear_text() {
|
||||
void suggest_clear_active() {
|
||||
free_suggestions();
|
||||
suggText = NULL;
|
||||
}
|
||||
@ -146,3 +166,37 @@ void suggest_set_selected(SuggItem *sel) {
|
||||
SuggItem *suggest_get_selected() {
|
||||
return suggestions.selected;
|
||||
}
|
||||
|
||||
/* Documentation methods */
|
||||
|
||||
void suggest_documentation(const char *docs) {
|
||||
int len;
|
||||
|
||||
if (!docs) return;
|
||||
|
||||
len = strlen(docs);
|
||||
|
||||
if (documentation) {
|
||||
MEM_freeN(documentation);
|
||||
documentation = NULL;
|
||||
}
|
||||
|
||||
/* Ensure documentation ends with a '\n' */
|
||||
if (docs[len-1] != '\n') {
|
||||
documentation = MEM_mallocN(len+2, "Documentation");
|
||||
strncpy(documentation, docs, len);
|
||||
documentation[len++] = '\n';
|
||||
} else {
|
||||
documentation = MEM_mallocN(len+1, "Documentation");
|
||||
strncpy(documentation, docs, len);
|
||||
}
|
||||
documentation[len] = '\0';
|
||||
}
|
||||
|
||||
char *suggest_get_docs() {
|
||||
return documentation;
|
||||
}
|
||||
|
||||
void suggest_clear_docs() {
|
||||
docs_free();
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ static PyObject *Text_asLines( BPy_Text * self );
|
||||
static PyObject *Text_getCursorPos( BPy_Text * self );
|
||||
static PyObject *Text_setCursorPos( BPy_Text * self, PyObject * args );
|
||||
static PyObject *Text_suggest( BPy_Text * self, PyObject * args );
|
||||
static PyObject *Text_showDocs( BPy_Text * self, PyObject * args );
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python BPy_Text methods table: */
|
||||
@ -136,7 +137,9 @@ static PyMethodDef BPy_Text_methods[] = {
|
||||
{"setCursorPos", ( PyCFunction ) Text_setCursorPos, METH_VARARGS,
|
||||
"(row, col) - Set the cursor position to (row, col)"},
|
||||
{"suggest", ( PyCFunction ) Text_suggest, METH_VARARGS,
|
||||
"(list) - List of tuples of the form (name, type) where type is one of 'm', 'v', 'f', 'k' for module, variable, function and keyword respectively"},
|
||||
"(list, prefix) - List of tuples of the form (name, type) where type is one of 'm', 'v', 'f', 'k' for module, variable, function and keyword respectively"},
|
||||
{"showDocs", ( PyCFunction ) Text_showDocs, METH_VARARGS,
|
||||
"(docs) - Documentation string"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@ -548,7 +551,7 @@ static PyObject *Text_setCursorPos( BPy_Text * self, PyObject * args )
|
||||
int row, col;
|
||||
int oldstate;
|
||||
|
||||
if(!self->text)
|
||||
if (!self->text)
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"This object isn't linked to a Blender Text Object");
|
||||
|
||||
@ -573,12 +576,12 @@ static PyObject *Text_suggest( BPy_Text * self, PyObject * args )
|
||||
char *prefix, *name, type;
|
||||
SpaceText *st;
|
||||
|
||||
if(!self->text)
|
||||
if (!self->text)
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"This object isn't linked to a Blender Text Object");
|
||||
|
||||
/* Parse args for a list of tuples */
|
||||
if(!PyArg_ParseTuple(args, "O!s", &PyList_Type, &list, &prefix))
|
||||
if (!PyArg_ParseTuple(args, "O!s", &PyList_Type, &list, &prefix))
|
||||
return EXPP_ReturnPyObjError(PyExc_TypeError,
|
||||
"expected list of tuples followed by a string");
|
||||
|
||||
@ -591,8 +594,8 @@ static PyObject *Text_suggest( BPy_Text * self, PyObject * args )
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"Active text area has no Text object");
|
||||
|
||||
suggest_set_active(st->text);
|
||||
list_len = PyList_Size(list);
|
||||
suggest_clear_text();
|
||||
|
||||
for (i = 0; i < list_len; i++) {
|
||||
item = PyList_GetItem(list, i);
|
||||
@ -610,7 +613,35 @@ static PyObject *Text_suggest( BPy_Text * self, PyObject * args )
|
||||
suggest_add(name, type);
|
||||
}
|
||||
suggest_prefix(prefix);
|
||||
suggest_set_text(st->text);
|
||||
scrarea_queue_redraw(curarea);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Text_showDocs( BPy_Text * self, PyObject * args )
|
||||
{
|
||||
char *docs;
|
||||
SpaceText *st;
|
||||
|
||||
if (!self->text)
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"This object isn't linked to a Blender Text Object");
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s", &docs))
|
||||
return EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected a string as argument" );
|
||||
|
||||
if (curarea->spacetype != SPACE_TEXT)
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"Active space type is not text");
|
||||
|
||||
st = curarea->spacedata.first;
|
||||
if (!st || !st->text)
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"Active text area has no Text object");
|
||||
|
||||
suggest_set_active(st->text);
|
||||
suggest_documentation(docs);
|
||||
scrarea_queue_redraw(curarea);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
@ -87,10 +87,14 @@
|
||||
#include "blendef.h"
|
||||
#include "winlay.h"
|
||||
|
||||
#define TEXTXLOC 38
|
||||
#define TEXTXLOC 38
|
||||
|
||||
#define SUGG_LIST_SIZE 7
|
||||
#define SUGG_LIST_WIDTH 20
|
||||
#define SUGG_LIST_SIZE 7
|
||||
#define SUGG_LIST_WIDTH 20
|
||||
#define DOC_WIDTH 40
|
||||
|
||||
#define TOOL_SUGG_LIST 0x01
|
||||
#define TOOL_DOCUMENT 0x02
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
@ -106,6 +110,7 @@ static int check_numbers(char *string);
|
||||
static int check_builtinfuncs(char *string);
|
||||
static int check_specialvars(char *string);
|
||||
static int check_identifier(char ch);
|
||||
static int check_whitespace(char ch);
|
||||
|
||||
static void get_suggest_prefix(Text *text);
|
||||
static void confirm_suggestion(Text *text, int skipleft);
|
||||
@ -1068,7 +1073,78 @@ static int do_suggest_select(SpaceText *st)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void draw_suggestion_list(SpaceText *st) {
|
||||
void draw_documentation(SpaceText *st)
|
||||
{
|
||||
TextLine *tmp;
|
||||
char *docs, buf[DOC_WIDTH+1];
|
||||
int len, prevsp, i, a;
|
||||
int boxw=0, boxh, l, x, y;
|
||||
|
||||
if (!st || !st->text) return;
|
||||
if (!suggest_is_active(st->text)) return;
|
||||
|
||||
docs = suggest_get_docs();
|
||||
|
||||
if (!docs) return;
|
||||
|
||||
/* Count the visible lines to the cursor */
|
||||
for (tmp=st->text->curl, l=-st->top; tmp; tmp=tmp->prev, l++);
|
||||
if (l<0) return;
|
||||
|
||||
if(st->showlinenrs) {
|
||||
x = spacetext_get_fontwidth(st)*(st->text->curc-st->left) + TXT_OFFSET + TEXTXLOC - 4;
|
||||
} else {
|
||||
x = spacetext_get_fontwidth(st)*(st->text->curc-st->left) + TXT_OFFSET - 4;
|
||||
}
|
||||
if (suggest_first()) {
|
||||
x += SUGG_LIST_WIDTH*spacetext_get_fontwidth(st) + 50;
|
||||
}
|
||||
y = curarea->winy - st->lheight*l - 2;
|
||||
|
||||
len = strlen(docs);
|
||||
|
||||
boxw = DOC_WIDTH*spacetext_get_fontwidth(st) + 20;
|
||||
boxh = (2*len/DOC_WIDTH+1)*st->lheight + 8; /* Rough guess at box height */
|
||||
|
||||
BIF_ThemeColor(TH_SHADE1);
|
||||
glRecti(x-1, y+1, x+boxw+1, y-boxh-1);
|
||||
BIF_ThemeColor(TH_BACK);
|
||||
glRecti(x, y, x+boxw, y-boxh);
|
||||
BIF_ThemeColor(TH_TEXT);
|
||||
|
||||
len = strlen(docs);
|
||||
prevsp = a = 0;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
if (docs[i] == ' ' || docs[i] == '\t' || docs[i] == '\n') {
|
||||
|
||||
/* If we would exceed the line length, print up to the last space */
|
||||
if (a + i-prevsp > DOC_WIDTH) {
|
||||
y -= st->lheight;
|
||||
buf[a] = '\0';
|
||||
text_draw(st, buf, 0, 0, 1, x+4, y-1, NULL);
|
||||
a = 0;
|
||||
}
|
||||
|
||||
/* Buffer up the next bit ready to draw */
|
||||
if (i-prevsp > DOC_WIDTH) break; /* TODO: Deal with long, unbroken strings */
|
||||
strncpy(buf+a, docs+prevsp, i-prevsp);
|
||||
a += i-prevsp;
|
||||
prevsp = i;
|
||||
|
||||
/* Hit a new line, print what we have */
|
||||
if (docs[i] == '\n') {
|
||||
y -= st->lheight;
|
||||
buf[a] = '\0';
|
||||
text_draw(st, buf, 0, 0, 1, x+4, y-1, NULL);
|
||||
a = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_suggestion_list(SpaceText *st)
|
||||
{
|
||||
SuggItem *item, *first, *last, *sel;
|
||||
TextLine *tmp;
|
||||
char str[SUGG_LIST_WIDTH+1];
|
||||
@ -1079,6 +1155,9 @@ void draw_suggestion_list(SpaceText *st) {
|
||||
|
||||
first = suggest_first();
|
||||
last = suggest_last();
|
||||
|
||||
if (!first || !last) return;
|
||||
|
||||
sel = suggest_get_selected();
|
||||
|
||||
/* Count the visible lines to the cursor */
|
||||
@ -1208,6 +1287,7 @@ void drawtextspace(ScrArea *sa, void *spacedata)
|
||||
}
|
||||
|
||||
draw_textscroll(st);
|
||||
draw_documentation(st);
|
||||
draw_suggestion_list(st);
|
||||
|
||||
curarea->win_swap= WIN_BACK_OK;
|
||||
@ -1693,7 +1773,7 @@ static void confirm_suggestion(Text *text, int skipleft) {
|
||||
for (i=0; i<skipleft; i++)
|
||||
txt_move_right(text, 0);
|
||||
|
||||
suggest_clear_text();
|
||||
suggest_clear_active();
|
||||
}
|
||||
|
||||
void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
@ -1704,7 +1784,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
SpaceText *st= curarea->spacedata.first;
|
||||
Text *text;
|
||||
int do_draw=0, p;
|
||||
int suggesting=0, do_suggest=0; /* 0:just redraw, -1:clear, 1:update prefix */
|
||||
int tools=0, tools_cancel=0, tools_update=0; /* Bitmasks for operations */
|
||||
|
||||
if (st==NULL || st->spacetype != SPACE_TEXT) return;
|
||||
|
||||
@ -1768,7 +1848,10 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
return;
|
||||
}
|
||||
|
||||
suggesting = st->showsyntax && suggest_is_active(text);
|
||||
if (st->showsyntax && suggest_is_active(text)) {
|
||||
if (suggest_first()) tools |= TOOL_SUGG_LIST;
|
||||
if (suggest_get_docs()) tools |= TOOL_DOCUMENT;
|
||||
}
|
||||
|
||||
if (event==LEFTMOUSE) {
|
||||
if (val) {
|
||||
@ -1779,10 +1862,9 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
|
||||
if (mval[0]>2 && mval[0]<20 && mval[1]>2 && mval[1]<curarea->winy-2) {
|
||||
do_textscroll(st, 2);
|
||||
do_suggest= -1;
|
||||
tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
|
||||
} else if (do_suggest_select(st)) {
|
||||
do_draw= 1;
|
||||
do_suggest= 0;
|
||||
} else {
|
||||
do_selection(st, G.qual&LR_SHIFTKEY);
|
||||
if (txt_has_sel(text)) {
|
||||
@ -1791,7 +1873,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
MEM_freeN(buffer);
|
||||
}
|
||||
do_draw= 1;
|
||||
do_suggest= -1;
|
||||
tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
|
||||
}
|
||||
}
|
||||
} else if (event==MIDDLEMOUSE) {
|
||||
@ -1799,15 +1881,16 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
if (do_suggest_select(st)) {
|
||||
confirm_suggestion(text, 0);
|
||||
do_draw= 1;
|
||||
do_suggest= 0;
|
||||
} else if (U.uiflag & USER_MMB_PASTE) {
|
||||
do_selection(st, G.qual&LR_SHIFTKEY);
|
||||
get_selection_buffer(text);
|
||||
do_draw= 1;
|
||||
} else {
|
||||
do_textscroll(st, 1);
|
||||
if (U.uiflag & USER_MMB_PASTE) {
|
||||
do_selection(st, G.qual&LR_SHIFTKEY);
|
||||
get_selection_buffer(text);
|
||||
do_draw= 1;
|
||||
} else {
|
||||
do_textscroll(st, 1);
|
||||
}
|
||||
tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
|
||||
}
|
||||
do_suggest= -1;
|
||||
}
|
||||
} else if (event==RIGHTMOUSE) {
|
||||
if (val) {
|
||||
@ -1840,7 +1923,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
do_suggest= -1;
|
||||
tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
|
||||
}
|
||||
} else if (ascii) {
|
||||
if (text && text->id.lib) {
|
||||
@ -1850,19 +1933,23 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
if (st->showsyntax) get_format_string(st);
|
||||
pop_space_text(st);
|
||||
do_draw= 1;
|
||||
if (suggesting) {
|
||||
if (ispunct(ascii) || check_whitespace(ascii)) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
if ((ascii != '_' && ascii != '*' && ispunct(ascii)) || check_whitespace(ascii)) {
|
||||
confirm_suggestion(text, 1);
|
||||
if (st->showsyntax) get_format_string(st);
|
||||
do_suggest= 0;
|
||||
} else {
|
||||
do_suggest= 1;
|
||||
tools_update |= TOOL_SUGG_LIST;
|
||||
}
|
||||
}
|
||||
tools_cancel |= TOOL_DOCUMENT;
|
||||
}
|
||||
} else if (val) {
|
||||
do_suggest= -1; /* Note that the default label sets this to 0,
|
||||
so -1 only applies to the explicit cases below */
|
||||
|
||||
/* Cases that require tools not to be cancelled must explicitly say so.
|
||||
* The default case does this to prevent window/mousemove events
|
||||
* from cancelling. */
|
||||
tools_cancel |= TOOL_SUGG_LIST | TOOL_DOCUMENT;
|
||||
|
||||
switch (event) {
|
||||
case AKEY:
|
||||
if (G.qual & LR_ALTKEY) {
|
||||
@ -2126,7 +2213,10 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
}
|
||||
break;
|
||||
case ESCKEY:
|
||||
do_suggest= -1;
|
||||
/* To allow ESC to close one tool at a time we remove all others from the cancel list */
|
||||
if (tools & TOOL_DOCUMENT) {
|
||||
tools_cancel &= ~TOOL_SUGG_LIST;
|
||||
}
|
||||
break;
|
||||
case TABKEY:
|
||||
if (text && text->id.lib) {
|
||||
@ -2157,7 +2247,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
error_libdata();
|
||||
break;
|
||||
}
|
||||
if (suggesting) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
confirm_suggestion(text, 0);
|
||||
if (st->showsyntax) get_format_string(st);
|
||||
break;
|
||||
@ -2186,17 +2276,14 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
}
|
||||
if (G.qual & (LR_ALTKEY | LR_CTRLKEY)) {
|
||||
txt_backspace_word(text);
|
||||
do_suggest= -1;
|
||||
tools_cancel |= TOOL_SUGG_LIST;
|
||||
} else {
|
||||
/* Work out which char we are about to delete */
|
||||
if (text && text->curl && text->curc > 0) {
|
||||
char ch= text->curl->line[text->curc-1];
|
||||
if (ispunct(ch) || check_whitespace(ch))
|
||||
do_suggest= -1;
|
||||
else
|
||||
do_suggest= 1;
|
||||
} else {
|
||||
do_suggest= -1;
|
||||
if (!ispunct(ch) && !check_whitespace(ch)) {
|
||||
tools_update |= TOOL_SUGG_LIST;
|
||||
}
|
||||
}
|
||||
txt_backspace_char(text);
|
||||
}
|
||||
@ -2223,17 +2310,17 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
case INSERTKEY:
|
||||
st->overwrite= !st->overwrite;
|
||||
do_draw= 1;
|
||||
do_suggest= 0;
|
||||
tools_cancel = 0;
|
||||
break;
|
||||
case DOWNARROWKEY:
|
||||
if (suggesting) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
SuggItem *sel = suggest_get_selected();
|
||||
if (!sel) {
|
||||
suggest_set_selected(suggest_first());
|
||||
} else if (sel!=suggest_last() && sel->next) {
|
||||
suggest_set_selected(sel->next);
|
||||
}
|
||||
do_suggest= 0;
|
||||
tools_cancel &= ~TOOL_SUGG_LIST;
|
||||
break;
|
||||
}
|
||||
txt_move_down(text, G.qual & LR_SHIFTKEY);
|
||||
@ -2264,11 +2351,11 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
pop_space_text(st);
|
||||
break;
|
||||
case UPARROWKEY:
|
||||
if (suggesting) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
SuggItem *sel = suggest_get_selected();
|
||||
if (sel && sel!=suggest_first() && sel->prev)
|
||||
suggest_set_selected(sel->prev);
|
||||
do_suggest= 0;
|
||||
tools_cancel &= ~TOOL_SUGG_LIST;
|
||||
break;
|
||||
}
|
||||
txt_move_up(text, G.qual & LR_SHIFTKEY);
|
||||
@ -2277,14 +2364,14 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
pop_space_text(st);
|
||||
break;
|
||||
case PAGEDOWNKEY:
|
||||
if (suggesting) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
int i;
|
||||
SuggItem *sel = suggest_get_selected();
|
||||
if (!sel)
|
||||
sel = suggest_first();
|
||||
for (i=0; i<SUGG_LIST_SIZE-1 && sel && sel!=suggest_last() && sel->next; i++, sel=sel->next)
|
||||
suggest_set_selected(sel->next);
|
||||
do_suggest= 0;
|
||||
tools_cancel &= ~TOOL_SUGG_LIST;
|
||||
break;
|
||||
} else {
|
||||
screen_skip(st, st->viewlines);
|
||||
@ -2292,12 +2379,12 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
do_draw= 1;
|
||||
break;
|
||||
case PAGEUPKEY:
|
||||
if (suggesting) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
int i;
|
||||
SuggItem *sel = suggest_get_selected();
|
||||
for (i=0; i<SUGG_LIST_SIZE-1 && sel && sel!=suggest_first() && sel->prev; i++, sel=sel->prev)
|
||||
suggest_set_selected(sel->prev);
|
||||
do_suggest= 0;
|
||||
tools_cancel &= ~TOOL_SUGG_LIST;
|
||||
break;
|
||||
} else {
|
||||
screen_skip(st, -st->viewlines);
|
||||
@ -2315,33 +2402,35 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
pop_space_text(st);
|
||||
break;
|
||||
case WHEELUPMOUSE:
|
||||
if (suggesting) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
SuggItem *sel = suggest_get_selected();
|
||||
if (sel && sel!=suggest_first() && sel->prev)
|
||||
suggest_set_selected(sel->prev);
|
||||
do_suggest= 0;
|
||||
tools_cancel &= ~TOOL_SUGG_LIST;
|
||||
} else {
|
||||
screen_skip(st, -U.wheellinescroll);
|
||||
tools_cancel &= ~TOOL_DOCUMENT;
|
||||
}
|
||||
do_draw= 1;
|
||||
break;
|
||||
case WHEELDOWNMOUSE:
|
||||
if (suggesting) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
SuggItem *sel = suggest_get_selected();
|
||||
if (!sel) {
|
||||
suggest_set_selected(suggest_first());
|
||||
} else if (sel && sel!=suggest_last() && sel->next) {
|
||||
suggest_set_selected(sel->next);
|
||||
}
|
||||
do_suggest= 0;
|
||||
tools_cancel &= ~TOOL_SUGG_LIST;
|
||||
} else {
|
||||
screen_skip(st, U.wheellinescroll);
|
||||
tools_cancel &= ~TOOL_DOCUMENT;
|
||||
}
|
||||
do_draw= 1;
|
||||
break;
|
||||
default:
|
||||
/* We don't want all sorts of events closing the suggestions box */
|
||||
do_suggest= 0;
|
||||
tools_cancel &= ~TOOL_SUGG_LIST & ~TOOL_DOCUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2404,11 +2493,17 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
}
|
||||
}
|
||||
|
||||
if (suggesting) {
|
||||
if (do_suggest == -1) {
|
||||
suggest_clear_text();
|
||||
} else if (do_suggest == 1) {
|
||||
if (tools & TOOL_SUGG_LIST) {
|
||||
if (tools_update & TOOL_SUGG_LIST) {
|
||||
get_suggest_prefix(text);
|
||||
} else if (tools_cancel & TOOL_SUGG_LIST) {
|
||||
suggest_clear_active();
|
||||
}
|
||||
do_draw= 1;
|
||||
}
|
||||
if (tools & TOOL_DOCUMENT) {
|
||||
if (tools_cancel & TOOL_DOCUMENT) {
|
||||
suggest_clear_docs();
|
||||
}
|
||||
do_draw= 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user