summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fe-common/core/formats.c33
-rw-r--r--src/fe-common/core/formats.h22
-rw-r--r--src/fe-text/gui-printtext.c88
-rw-r--r--src/fe-text/gui-printtext.h7
-rw-r--r--src/fe-text/gui-windows.c38
-rw-r--r--src/fe-text/gui-windows.h2
-rw-r--r--src/fe-text/textbuffer-view.c180
-rw-r--r--src/fe-text/textbuffer-view.h19
-rw-r--r--src/fe-text/textbuffer.c3
-rw-r--r--src/fe-text/textbuffer.h1
-rw-r--r--src/perl/textui/TextBufferView.xs65
-rw-r--r--src/perl/textui/TextUI.xs2
12 files changed, 368 insertions, 92 deletions
diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c
index 515a48a3..dbdd51f2 100644
--- a/src/fe-common/core/formats.c
+++ b/src/fe-common/core/formats.c
@@ -60,7 +60,7 @@ int format_find_tag(const char *module, const char *tag)
return -1;
}
-static void format_expand_code(const char **format, int *flags)
+static void format_expand_code(const char **format, GString *out, int *flags)
{
int set;
@@ -73,12 +73,28 @@ static void format_expand_code(const char **format, int *flags)
set = TRUE;
(*format)++;
- while (**format != ']') {
+ while (**format != ']' && **format != '\0') {
if (**format == '+')
set = TRUE;
else if (**format == '-')
set = FALSE;
else switch (**format) {
+ case 'i':
+ /* indent function */
+ (*format)++;
+ if (**format == '=')
+ (*format)++;
+
+ g_string_append_c(out, 4);
+ g_string_append_c(out, FORMAT_STYLE_INDENT_FUNC);
+ while (**format != ']' && **format != '\0' &&
+ **format != ',') {
+ g_string_append_c(out, **format);
+ (*format)++;
+ }
+ g_string_append_c(out, ',');
+ (*format)--;
+ break;
case 's':
case 'S':
*flags |= !set ? PRINT_FLAG_UNSET_LINE_START :
@@ -154,7 +170,7 @@ int format_expand_styles(GString *out, const char **format, int *flags)
break;
case '[':
/* code */
- format_expand_code(format, flags);
+ format_expand_code(format, out, flags);
break;
default:
/* check if it's a background color */
@@ -945,6 +961,17 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
case FORMAT_STYLE_INDENT:
flags |= GUI_PRINT_FLAG_INDENT;
break;
+ case FORMAT_STYLE_INDENT_FUNC: {
+ const char *start = ptr;
+ while (*ptr != ',' && *ptr != '\0')
+ ptr++;
+ if (*ptr != '\0') *ptr++ = '\0';
+ signal_emit_id(signal_gui_print_text, 6,
+ dest->window, NULL, NULL,
+ GINT_TO_POINTER(GUI_PRINT_FLAG_INDENT_FUNC),
+ str, start, dest->level);
+ break;
+ }
case FORMAT_STYLE_DEFAULTS:
fgcolor = bgcolor = -1;
flags &= GUI_PRINT_FLAG_INDENT;
diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h
index f8b91d1b..27e87715 100644
--- a/src/fe-common/core/formats.h
+++ b/src/fe-common/core/formats.h
@@ -4,14 +4,15 @@
#include "themes.h"
#include "fe-windows.h"
-#define GUI_PRINT_FLAG_BOLD 0x01
-#define GUI_PRINT_FLAG_REVERSE 0x02
-#define GUI_PRINT_FLAG_UNDERLINE 0x04
-#define GUI_PRINT_FLAG_BLINK 0x08
-#define GUI_PRINT_FLAG_MIRC_COLOR 0x10
-#define GUI_PRINT_FLAG_INDENT 0x20
-#define GUI_PRINT_FLAG_NEWLINE 0x40
-#define GUI_PRINT_FLAG_CLRTOEOL 0x80
+#define GUI_PRINT_FLAG_BOLD 0x0001
+#define GUI_PRINT_FLAG_REVERSE 0x0002
+#define GUI_PRINT_FLAG_UNDERLINE 0x0004
+#define GUI_PRINT_FLAG_BLINK 0x0008
+#define GUI_PRINT_FLAG_MIRC_COLOR 0x0010
+#define GUI_PRINT_FLAG_INDENT 0x0020
+#define GUI_PRINT_FLAG_INDENT_FUNC 0x0040
+#define GUI_PRINT_FLAG_NEWLINE 0x0080
+#define GUI_PRINT_FLAG_CLRTOEOL 0x0100
#define MAX_FORMAT_PARAMS 10
#define DEFAULT_FORMAT_ARGLIST_SIZE 200
@@ -121,8 +122,9 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text);
#define FORMAT_STYLE_BOLD (0x03 + FORMAT_STYLE_SPECIAL)
#define FORMAT_STYLE_REVERSE (0x04 + FORMAT_STYLE_SPECIAL)
#define FORMAT_STYLE_INDENT (0x05 + FORMAT_STYLE_SPECIAL)
-#define FORMAT_STYLE_DEFAULTS (0x06 + FORMAT_STYLE_SPECIAL)
-#define FORMAT_STYLE_CLRTOEOL (0x07 + FORMAT_STYLE_SPECIAL)
+#define FORMAT_STYLE_INDENT_FUNC (0x06 + FORMAT_STYLE_SPECIAL)
+#define FORMAT_STYLE_DEFAULTS (0x07 + FORMAT_STYLE_SPECIAL)
+#define FORMAT_STYLE_CLRTOEOL (0x08 + FORMAT_STYLE_SPECIAL)
int format_expand_styles(GString *out, const char **format, int *flags);
void formats_init(void);
diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c
index 364d68c3..79f86674 100644
--- a/src/fe-text/gui-printtext.c
+++ b/src/fe-text/gui-printtext.c
@@ -26,6 +26,7 @@
#include "printtext.h"
#include "screen.h"
+#include "gui-printtext.h"
#include "gui-windows.h"
int mirc_colors[] = { 15, 0, 1, 2, 12, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7 };
@@ -34,6 +35,63 @@ static int scrollback_lines, scrollback_hours, scrollback_burst_remove;
static int last_color, last_flags;
static int next_xpos, next_ypos;
+static GHashTable *indent_functions;
+static INDENT_FUNC default_indent_func;
+
+void gui_register_indent_func(const char *name, INDENT_FUNC func)
+{
+ gpointer key, value;
+ GSList *list;
+
+ if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) {
+ list = value;
+ g_hash_table_remove(indent_functions, key);
+ } else {
+ key = g_strdup(name);
+ list = NULL;
+ }
+
+ list = g_slist_append(list, func);
+ g_hash_table_insert(indent_functions, key, list);
+}
+
+void gui_unregister_indent_func(const char *name, INDENT_FUNC func)
+{
+ gpointer key, value;
+ GSList *list;
+
+ if (g_hash_table_lookup_extended(indent_functions, name, &key, &value)) {
+ list = value;
+
+ list = g_slist_remove(list, func);
+ g_hash_table_remove(indent_functions, key);
+ if (list == NULL)
+ g_free(key);
+ else
+ g_hash_table_insert(indent_functions, key, list);
+ }
+
+ if (default_indent_func == func)
+ gui_set_default_indent(NULL);
+
+ textbuffer_views_unregister_indent_func(func);
+}
+
+void gui_set_default_indent(const char *name)
+{
+ GSList *list;
+
+ list = name == NULL ? NULL :
+ g_hash_table_lookup(indent_functions, name);
+ default_indent_func = list == NULL ? NULL : list->data;
+ gui_windows_reset_settings();
+}
+
+INDENT_FUNC get_default_indent_func(void)
+{
+ return default_indent_func;
+}
+
void gui_printtext(int xpos, int ypos, const char *str)
{
next_xpos = xpos;
@@ -154,6 +212,21 @@ static void line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line,
last_color = fg | (bg << 4);
}
+static void line_add_indent_func(TEXT_BUFFER_REC *buffer, LINE_REC **line,
+ const char *function)
+{
+ GSList *list;
+ unsigned char data[1+sizeof(INDENT_FUNC)];
+
+ list = g_hash_table_lookup(indent_functions, function);
+ if (list != NULL) {
+ data[0] = LINE_CMD_INDENT_FUNC;
+ memcpy(data+1, list->data, sizeof(INDENT_FUNC));
+ *line = textbuffer_insert(buffer, *line,
+ data, sizeof(data), NULL);
+ }
+}
+
static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line)
{
static const unsigned char eol[] = { 0, LINE_CMD_EOL };
@@ -203,8 +276,14 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
if (flags & GUI_PRINT_FLAG_NEWLINE)
view_add_eol(view, &insert_after);
line_add_colors(view->buffer, &insert_after, fg, bg, flags);
- insert_after = textbuffer_insert(view->buffer, insert_after,
- str, strlen(str), &lineinfo);
+
+ if (flags & GUI_PRINT_FLAG_INDENT_FUNC) {
+ /* specify the indentation function */
+ line_add_indent_func(view->buffer, &insert_after, str);
+ } else {
+ insert_after = textbuffer_insert(view->buffer, insert_after,
+ str, strlen(str), &lineinfo);
+ }
if (gui->use_insert_after)
gui->insert_after = insert_after;
}
@@ -235,6 +314,9 @@ static void read_settings(void)
void gui_printtext_init(void)
{
next_xpos = next_ypos = -1;
+ default_indent_func = NULL;
+ indent_functions = g_hash_table_new((GHashFunc) g_str_hash,
+ (GCompareFunc) g_str_equal);
settings_add_int("history", "scrollback_lines", 500);
settings_add_int("history", "scrollback_hours", 24);
@@ -249,6 +331,8 @@ void gui_printtext_init(void)
void gui_printtext_deinit(void)
{
+ g_hash_table_destroy(indent_functions);
+
signal_remove("gui print text", (SIGNAL_FUNC) sig_gui_print_text);
signal_remove("gui print text finished", (SIGNAL_FUNC) sig_gui_printtext_finished);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h
index 44f2b44e..47cd3c23 100644
--- a/src/fe-text/gui-printtext.h
+++ b/src/fe-text/gui-printtext.h
@@ -2,6 +2,7 @@
#define __GUI_PRINTTEXT_H
#include "gui-windows.h"
+#include "textbuffer-view.h"
#include "formats.h"
extern int mirc_colors[];
@@ -9,6 +10,12 @@ extern int mirc_colors[];
void gui_printtext_init(void);
void gui_printtext_deinit(void);
+void gui_register_indent_func(const char *name, INDENT_FUNC func);
+void gui_unregister_indent_func(const char *name, INDENT_FUNC func);
+
+void gui_set_default_indent(const char *name);
+INDENT_FUNC get_default_indent_func(void);
+
void gui_printtext(int xpos, int ypos, const char *str);
void gui_printtext_after(TEXT_DEST_REC *dest, LINE_REC *prev, const char *str);
diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c
index 0f4a6702..f3266828 100644
--- a/src/fe-text/gui-windows.c
+++ b/src/fe-text/gui-windows.c
@@ -43,9 +43,11 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window,
gui->parent = parent;
gui->view = textbuffer_view_create(textbuffer_create(),
window->width, window->height,
+ settings_get_bool("scroll"));
+ textbuffer_view_set_default_indent(gui->view,
settings_get_int("indent"),
settings_get_bool("indent_always"),
- settings_get_bool("scroll"));
+ get_default_indent_func());
return gui;
}
@@ -182,6 +184,25 @@ void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent)
}
}
+void gui_windows_reset_settings(void)
+{
+ GSList *tmp;
+
+ for (tmp = windows; tmp != NULL; tmp = tmp->next) {
+ WINDOW_REC *rec = tmp->data;
+ GUI_WINDOW_REC *gui = WINDOW_GUI(rec);
+
+ textbuffer_view_set_default_indent(gui->view,
+ settings_get_int("indent"),
+ settings_get_bool("indent_always"),
+ get_default_indent_func());
+
+ textbuffer_view_set_scroll(gui->view,
+ gui->use_scroll ? gui->scroll :
+ settings_get_bool("scroll"));
+ }
+}
+
static MAIN_WINDOW_REC *mainwindow_find_unsticky(void)
{
GSList *tmp;
@@ -239,20 +260,7 @@ static void signal_window_changed(WINDOW_REC *window)
static void read_settings(void)
{
- GSList *tmp;
-
- for (tmp = windows; tmp != NULL; tmp = tmp->next) {
- WINDOW_REC *rec = tmp->data;
- GUI_WINDOW_REC *gui = WINDOW_GUI(rec);
-
- textbuffer_view_set_default_indent(gui->view,
- settings_get_int("indent"),
- settings_get_bool("indent_always"));
-
- textbuffer_view_set_scroll(gui->view,
- gui->use_scroll ? gui->scroll :
- settings_get_bool("scroll"));
- }
+ gui_windows_reset_settings();
}
void gui_windows_init(void)
diff --git a/src/fe-text/gui-windows.h b/src/fe-text/gui-windows.h
index b67f6de7..9d4afac7 100644
--- a/src/fe-text/gui-windows.h
+++ b/src/fe-text/gui-windows.h
@@ -39,4 +39,6 @@ void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line);
void gui_window_set_sticky(WINDOW_REC *window);
void gui_window_set_unsticky(WINDOW_REC *window);
+void gui_windows_reset_settings(void);
+
#endif
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 */
diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h
index d49798df..c5fc7ba2 100644
--- a/src/fe-text/textbuffer-view.h
+++ b/src/fe-text/textbuffer-view.h
@@ -4,9 +4,16 @@
#include "textbuffer.h"
#include "screen.h"
+typedef struct _TEXT_BUFFER_VIEW_REC TEXT_BUFFER_VIEW_REC;
+
+/* if ypos == -1, don't print anything, just return the indent size */
+typedef int (*INDENT_FUNC) (TEXT_BUFFER_VIEW_REC *view,
+ LINE_REC *line, int ypos);
+
typedef struct {
unsigned char *start;
int indent;
+ INDENT_FUNC indent_func;
int color;
/* first word in line belong to the end of the last word in
@@ -37,7 +44,7 @@ typedef struct {
int last_linecount;
} TEXT_BUFFER_CACHE_REC;
-typedef struct {
+struct _TEXT_BUFFER_VIEW_REC {
TEXT_BUFFER_REC *buffer;
GSList *siblings; /* other views that use the same buffer */
@@ -45,6 +52,7 @@ typedef struct {
int width, height;
int default_indent;
+ INDENT_FUNC default_indent_func;
unsigned int longword_noindent:1;
unsigned int scroll:1; /* scroll down automatically when at bottom */
@@ -67,20 +75,21 @@ typedef struct {
/* Bookmarks to the lines in the buffer - removed automatically
when the line gets removed from buffer */
GHashTable *bookmarks;
-} TEXT_BUFFER_VIEW_REC;
+};
/* 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);
/* Destroy the view. */
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);
+void textbuffer_views_unregister_indent_func(INDENT_FUNC indent_func);
+
void textbuffer_view_set_scroll(TEXT_BUFFER_VIEW_REC *view, int scroll);
/* Resize the view. */
diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c
index 1016905c..f99aacca 100644
--- a/src/fe-text/textbuffer.c
+++ b/src/fe-text/textbuffer.c
@@ -403,6 +403,9 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str)
break;
case LINE_CMD_INDENT:
break;
+ case LINE_CMD_INDENT_FUNC:
+ ptr += sizeof(void *);
+ break;
}
}
}
diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h
index cc01667b..8256309f 100644
--- a/src/fe-text/textbuffer.h
+++ b/src/fe-text/textbuffer.h
@@ -11,6 +11,7 @@ enum {
LINE_CMD_UNDERLINE, /* enable/disable underlining */
LINE_CMD_REVERSE, /* enable/disable reversed text */
LINE_CMD_INDENT, /* if line is split, indent it at this position */
+ LINE_CMD_INDENT_FUNC, /* if line is split, use the specified indentation function */
LINE_CMD_BLINK, /* blinking background */
LINE_CMD_FORMAT, /* end of line, but next will come the format that was used to create the
text in format <module><format_name><arg><arg2...> - fields are separated
diff --git a/src/perl/textui/TextBufferView.xs b/src/perl/textui/TextBufferView.xs
index dfb1d036..37efc856 100644
--- a/src/perl/textui/TextBufferView.xs
+++ b/src/perl/textui/TextBufferView.xs
@@ -1,17 +1,74 @@
#include "module.h"
+static char *default_indent_func;
+
+static int perl_indent_func(TEXT_BUFFER_VIEW_REC *view,
+ LINE_REC *line, int ypos)
+{
+ dSP;
+ int retcount, ret;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(plain_bless(view, "Irssi::TextUI::TextBufferView")));
+ XPUSHs(sv_2mortal(plain_bless(line, "Irssi::TextUI::Line")));
+ XPUSHs(sv_2mortal(newSViv(ypos)));
+ PUTBACK;
+
+ retcount = perl_call_pv(default_indent_func, G_EVAL|G_DISCARD);
+ SPAGAIN;
+
+ ret = 0;
+ if (SvTRUE(ERRSV)) {
+ STRLEN n_a;
+ char *package;
+
+ package = perl_function_get_package(default_indent_func);
+ signal_emit("script error", 2,
+ perl_script_find_package(package),
+ SvPV(ERRSV, n_a));
+ g_free(package);
+ } else if (retcount > 0) {
+ ret = POPi;
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return ret;
+}
+
+void perl_textbuffer_view_init(void)
+{
+ default_indent_func = NULL;
+}
+
+void perl_textbuffer_view_deinit(void)
+{
+ g_free_not_null(default_indent_func);
+}
+
MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBuffer PREFIX = textbuffer_
PROTOTYPES: ENABLE
Irssi::TextUI::TextBufferView
-textbuffer_view_create(buffer, width, height, default_indent, longword_noindent, scroll)
+textbuffer_view_create(buffer, width, height, scroll)
Irssi::TextUI::TextBuffer buffer
int width
int height
- int default_indent
- int longword_noindent
int scroll
+void
+gui_windows_set_default_indent_func(func)
+ char *func
+CODE:
+ g_free_not_null(default_indent_func);
+ default_indent_func = g_strdup(func);
+ gui_windows_set_default_indent_func(perl_indent_func);
+
#*******************************
MODULE = Irssi::TextUI::TextBufferView PACKAGE = Irssi::TextUI::TextBufferView PREFIX = textbuffer_view_
#*******************************
@@ -25,6 +82,8 @@ textbuffer_view_set_default_indent(view, default_indent, longword_noindent)
Irssi::TextUI::TextBufferView view
int default_indent
int longword_noindent
+CODE:
+ textbuffer_view_set_default_indent(view, default_indent, longword_noindent, NULL);
void
textbuffer_view_set_scroll(view, scroll)
diff --git a/src/perl/textui/TextUI.xs b/src/perl/textui/TextUI.xs
index c92da84a..9ebd2c6b 100644
--- a/src/perl/textui/TextUI.xs
+++ b/src/perl/textui/TextUI.xs
@@ -96,11 +96,13 @@ CODE:
irssi_add_plains(textui_plains);
perl_statusbar_init();
+ perl_textbuffer_view_init();
void
deinit()
CODE:
perl_statusbar_deinit();
+ perl_textbuffer_view_deinit();
MODULE = Irssi::TextUI PACKAGE = Irssi