diff options
Diffstat (limited to 'src/view.c')
-rw-r--r-- | src/view.c | 66 |
1 files changed, 54 insertions, 12 deletions
@@ -46,6 +46,7 @@ #include "qreg.h" #include "eol.h" #include "memory.h" +#include "lexer.h" #include "view.h" /** @memberof teco_view_t */ @@ -205,9 +206,24 @@ teco_view_set_representations(teco_view_t *ctx) gboolean teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **error) { + gboolean ret = TRUE; + g_auto(teco_eol_reader_t) reader; teco_eol_reader_init_gio(&reader, channel); + /* + * Temporarily disable the line character index. + * This tremendously speeds up reading UTF-8 documents. + * The reason is, that UTF-8 consistency checks are rather + * costly. Also, when reading in chunks of 1024 bytes, + * we can very well add incomplete UTF-8 sequences, + * resulting in unnecessary recalculations of the line index. + */ + guint cp = teco_view_get_codepage(ctx); + if (cp == SC_CP_UTF8) + teco_interface_ssm(SCI_RELEASELINECHARACTERINDEX, + SC_LINECHARACTERINDEX_UTF32, 0); + teco_view_ssm(ctx, SCI_BEGINUNDOACTION, 0, 0); teco_view_ssm(ctx, SCI_CLEARALL, 0, 0); @@ -221,8 +237,9 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **erro struct stat stat_buf = {.st_size = 0}; if (!fstat(g_io_channel_unix_get_fd(channel), &stat_buf) && stat_buf.st_size > 0) { - if (!teco_memory_check(stat_buf.st_size, error)) - goto error; + ret = teco_memory_check(stat_buf.st_size, error); + if (!ret) + goto cleanup; teco_view_ssm(ctx, SCI_ALLOCATE, stat_buf.st_size, 0); } @@ -234,8 +251,10 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **erro teco_string_t str; GIOStatus rc = teco_eol_reader_convert(&reader, &str.data, &str.len, error); - if (rc == G_IO_STATUS_ERROR) - goto error; + if (rc == G_IO_STATUS_ERROR) { + ret = FALSE; + goto cleanup; + } if (rc == G_IO_STATUS_EOF) break; @@ -245,12 +264,14 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **erro * Even if we checked initially, knowing the file size, * Scintilla could allocate much more bytes. */ - if (!teco_memory_check(0, error)) - goto error; + ret = teco_memory_check(0, error); + if (!ret) + goto cleanup; if (G_UNLIKELY(teco_interface_is_interrupted())) { teco_error_interrupted_set(error); - goto error; + ret = FALSE; + goto cleanup; } } @@ -271,12 +292,14 @@ teco_view_load_from_channel(teco_view_t *ctx, GIOChannel *channel, GError **erro teco_interface_msg(TECO_MSG_WARNING, "Inconsistent EOL styles normalized"); +cleanup: teco_view_ssm(ctx, SCI_ENDUNDOACTION, 0, 0); - return TRUE; -error: - teco_view_ssm(ctx, SCI_ENDUNDOACTION, 0, 0); - return FALSE; + if (cp == SC_CP_UTF8) + teco_interface_ssm(SCI_ALLOCATELINECHARACTERINDEX, + SC_LINECHARACTERINDEX_UTF32, 0); + + return ret; } /** @@ -634,5 +657,24 @@ teco_view_get_character(teco_view_t *ctx, gsize pos, gsize len) * The sign bit in UCS-4/UTF-32 is unused, so this will even * suffice if TECO_INTEGER == 32. */ - return (gint32)g_utf8_get_char_validated(buf, -1); + return *buf ? (gint32)g_utf8_get_char_validated(buf, -1) : 0; +} + +void +teco_view_process_notify(teco_view_t *ctx, SCNotification *notify) +{ +#ifdef DEBUG + g_printf("SCINTILLA NOTIFY: code=%d\n", notify->nmhdr.code); +#endif + + /* + * Lexing in the container: only used for SciTECO. + * + * The "identifier" is abused to enable/disable lexing. + * It could be extended later on for several internal lexers. + * The alternative would be an ILexer5 wrapper, written in C++. + */ + if (notify->nmhdr.code == SCN_STYLENEEDED && + teco_view_ssm(ctx, SCI_GETIDENTIFIER, 0, 0) != 0) + teco_lexer_style(ctx, notify->position); } |