summaryrefslogtreecommitdiff
path: root/src/fe-text/textbuffer-view.c
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2001-10-24 22:52:15 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2001-10-24 22:52:15 +0000
commit2a75c88f99e1aa24fbac81deac007ceca313b993 (patch)
tree5267820ea1eab3c7061056f2e7dbb92f2ace729b /src/fe-text/textbuffer-view.c
parentf7683c0423277dec3ec939cf33c3044658ee48a5 (diff)
downloadirssi-2a75c88f99e1aa24fbac81deac007ceca313b993.zip
Added support for changing indentation behaviour with modules.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1912 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/fe-text/textbuffer-view.c')
-rw-r--r--src/fe-text/textbuffer-view.c180
1 files changed, 126 insertions, 54 deletions
diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c
index 12191f05..adb9a320 100644
--- a/src/fe-text/textbuffer-view.c
+++ b/src/fe-text/textbuffer-view.c
@@ -105,6 +105,7 @@ static void textbuffer_cache_unref(TEXT_BUFFER_CACHE_REC *cache)
static LINE_CACHE_REC *
view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
{
+ INDENT_FUNC indent_func;
LINE_CACHE_REC *rec;
LINE_CACHE_SUB_REC *sub;
GSList *lines;
@@ -117,6 +118,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
xpos = 0; color = 0; indent_pos = view->default_indent;
last_space = last_color = 0; last_space_ptr = NULL; sub = NULL;
+ indent_func = view->default_indent_func;
linecount = 1;
lines = NULL;
for (ptr = line->text;;) {
@@ -162,6 +164,12 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
it if we're too close to right border */
if (xpos < view->width-5) indent_pos = xpos;
break;
+ case LINE_CMD_INDENT_FUNC:
+ memcpy(&indent_func, ptr, sizeof(INDENT_FUNC));
+ ptr += sizeof(INDENT_FUNC);
+ if (indent_func == NULL)
+ indent_func = view->default_indent_func;
+ break;
}
continue;
}
@@ -175,7 +183,8 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
}
if (xpos == view->width) {
- xpos = indent_pos;
+ xpos = indent_func == NULL ? indent_pos :
+ indent_func(view, line, -1);
sub = g_new0(LINE_CACHE_SUB_REC, 1);
if (last_space > indent_pos && last_space > 10) {
@@ -191,6 +200,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
sub->start = ptr;
sub->indent = xpos;
+ sub->indent_func = indent_func;
sub->color = color;
lines = g_slist_append(lines, sub);
@@ -227,9 +237,52 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
return rec;
}
+static void view_remove_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
+ unsigned char update_counter)
+{
+ LINE_CACHE_REC *cache;
+
+ if (view->cache->update_counter == update_counter)
+ return;
+ view->cache->update_counter = update_counter;
+
+ cache = g_hash_table_lookup(view->cache->line_cache, line);
+ if (cache != NULL) {
+ g_free(cache);
+ g_hash_table_remove(view->cache->line_cache, line);
+ }
+}
+
+static void view_update_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
+ unsigned char update_counter)
+{
+ view_remove_cache(view, line, update_counter);
+
+ if (view->buffer->cur_line == line)
+ view->cache->last_linecount = view_get_linecount(view, line);
+}
+
+static void view_reset_cache(TEXT_BUFFER_VIEW_REC *view)
+{
+ GSList *tmp;
+
+ /* destroy line caches - note that you can't do simultaneously
+ unrefs + cache_get()s or it will keep using the old caches */
+ textbuffer_cache_unref(view->cache);
+ g_slist_foreach(view->siblings, (GFunc) textbuffer_cache_unref, NULL);
+
+ view->cache = textbuffer_cache_get(view->siblings, view->width);
+ for (tmp = view->siblings; tmp != NULL; tmp = tmp->next) {
+ TEXT_BUFFER_VIEW_REC *rec = tmp->data;
+
+ rec->cache = textbuffer_cache_get(rec->siblings, rec->width);
+ }
+}
+
static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
int subline, int ypos, int max)
{
+ INDENT_FUNC indent_func;
LINE_CACHE_REC *cache;
const unsigned char *text, *text_newline;
char *tmp;
@@ -252,15 +305,19 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
break;
}
- if (subline > 0) {
- xpos = cache->lines[subline-1].indent;
- color = cache->lines[subline-1].color;
- }
-
+ /* first clear the line */
screen_set_color(view->window, 0);
screen_move(view->window, 0, ypos);
screen_clrtoeol(view->window);
+ if (subline > 0) {
+ indent_func = cache->lines[subline-1].indent_func;
+ xpos = indent_func != NULL ?
+ indent_func(view, line, ypos) :
+ cache->lines[subline-1].indent;
+ color = cache->lines[subline-1].color;
+ }
+
screen_move(view->window, xpos, ypos);
screen_set_color(view->window, color);
@@ -302,6 +359,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
break;
case LINE_CMD_BLINK:
color |= 0x80;
+ break;
+ case LINE_CMD_INDENT_FUNC:
+ text += sizeof(INDENT_FUNC);
break;
}
screen_set_color(view->window, color);
@@ -378,8 +438,6 @@ static void textbuffer_view_init_ypos(TEXT_BUFFER_VIEW_REC *view)
/* Create new view. */
TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer,
int width, int height,
- int default_indent,
- int longword_noindent,
int scroll)
{
TEXT_BUFFER_VIEW_REC *view;
@@ -393,8 +451,6 @@ TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer,
view->width = width;
view->height = height;
- view->default_indent = default_indent;
- view->longword_noindent = longword_noindent;
view->scroll = scroll;
view->cache = textbuffer_cache_get(view->siblings, width);
@@ -445,10 +501,65 @@ void textbuffer_view_destroy(TEXT_BUFFER_VIEW_REC *view)
/* Change the default indent position */
void textbuffer_view_set_default_indent(TEXT_BUFFER_VIEW_REC *view,
int default_indent,
- int longword_noindent)
+ int longword_noindent,
+ INDENT_FUNC indent_func)
{
- view->default_indent = default_indent;
- view->longword_noindent = longword_noindent;
+ if (default_indent != -1)
+ view->default_indent = default_indent;
+ if (view->longword_noindent != -1)
+ view->longword_noindent = longword_noindent;
+
+ view->default_indent_func = indent_func;
+}
+
+static void view_unregister_indent_func(TEXT_BUFFER_VIEW_REC *view,
+ INDENT_FUNC indent_func)
+{
+ INDENT_FUNC func;
+ LINE_REC *line;
+ const unsigned char *text, *tmp;
+
+ if (view->default_indent_func == indent_func)
+ view->default_indent_func = NULL;
+
+ /* recreate cache so it won't contain references
+ to the indent function */
+ view_reset_cache(view);
+ view->cache = textbuffer_cache_get(view->siblings, view->width);
+
+ /* remove all references to the indent function from buffer */
+ line = view->buffer->first_line;
+ while (line != NULL) {
+ text = line->text;
+
+ for (text = line->text;; text++) {
+ if (*text != '\0')
+ continue;
+
+ text++;
+ if (*text == LINE_CMD_EOL)
+ break;
+
+ if (*text == LINE_CMD_INDENT_FUNC) {
+ text++;
+ memcpy(&func, text, sizeof(INDENT_FUNC));
+ if (func == indent_func)
+ memset(&func, 0, sizeof(INDENT_FUNC));
+ text += sizeof(INDENT_FUNC);
+ } else if (*text == LINE_CMD_CONTINUE) {
+ memcpy(&tmp, text+1, sizeof(char *));
+ text = tmp-1;
+ }
+ }
+
+ line = line->next;
+ }
+}
+
+void textbuffer_views_unregister_indent_func(INDENT_FUNC indent_func)
+{
+ g_slist_foreach(views, (GFunc) view_unregister_indent_func,
+ indent_func);
}
void textbuffer_view_set_scroll(TEXT_BUFFER_VIEW_REC *view, int scroll)
@@ -721,31 +832,6 @@ LINE_CACHE_REC *textbuffer_view_get_line_cache(TEXT_BUFFER_VIEW_REC *view,
return cache;
}
-static void view_remove_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
- unsigned char update_counter)
-{
- LINE_CACHE_REC *cache;
-
- if (view->cache->update_counter == update_counter)
- return;
- view->cache->update_counter = update_counter;
-
- cache = g_hash_table_lookup(view->cache->line_cache, line);
- if (cache != NULL) {
- g_free(cache);
- g_hash_table_remove(view->cache->line_cache, line);
- }
-}
-
-static void view_update_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
- unsigned char update_counter)
-{
- view_remove_cache(view, line, update_counter);
-
- if (view->buffer->cur_line == line)
- view->cache->last_linecount = view_get_linecount(view, line);
-}
-
static void view_insert_line(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
{
int linecount, ypos, subline;
@@ -1003,8 +1089,6 @@ static int g_free_true(void *data)
/* Remove all lines from buffer. */
void textbuffer_view_remove_all_lines(TEXT_BUFFER_VIEW_REC *view)
{
- GSList *tmp;
-
g_return_if_fail(view != NULL);
textbuffer_remove_all_lines(view->buffer);
@@ -1012,21 +1096,9 @@ void textbuffer_view_remove_all_lines(TEXT_BUFFER_VIEW_REC *view)
g_hash_table_foreach_remove(view->bookmarks,
(GHRFunc) g_free_true, NULL);
- /* destroy line caches - note that you can't do simultaneously
- unrefs + cache_get()s or it will keep using the old caches */
- textbuffer_cache_unref(view->cache);
- g_slist_foreach(view->siblings, (GFunc) textbuffer_cache_unref, NULL);
-
- /* recreate caches, clear screens */
- view->cache = textbuffer_cache_get(view->siblings, view->width);
+ view_reset_cache(view);
textbuffer_view_clear(view);
-
- for (tmp = view->siblings; tmp != NULL; tmp = tmp->next) {
- TEXT_BUFFER_VIEW_REC *rec = tmp->data;
-
- rec->cache = textbuffer_cache_get(rec->siblings, rec->width);
- textbuffer_view_clear(rec);
- }
+ g_slist_foreach(view->siblings, (GFunc) textbuffer_view_clear, NULL);
}
/* Set a bookmark in view */