diff --git a/data/org.x.editor.gschema.xml.in b/data/org.x.editor.gschema.xml.in
index 17a16269..85b81d47 100644
--- a/data/org.x.editor.gschema.xml.in
+++ b/data/org.x.editor.gschema.xml.in
@@ -161,6 +161,12 @@
Whether xed should enable syntax highlighting.
+
+ 4
+ Maximum file size for syntax highlighting
+ Files larger than this size (in MB) will be opened without syntax highlighting and without search highlighting, for performance reasons. Use 0 to disable this limit.
+
+
true
Ensure Trailing Newline
diff --git a/xed/resources/ui/xed-preferences-dialog.ui b/xed/resources/ui/xed-preferences-dialog.ui
index 7db17f8d..c11c7f45 100644
--- a/xed/resources/ui/xed-preferences-dialog.ui
+++ b/xed/resources/ui/xed-preferences-dialog.ui
@@ -17,6 +17,13 @@
1
10
+
False
diff --git a/xed/xed-document.c b/xed/xed-document.c
index 4e6002eb..1622a7e5 100644
--- a/xed/xed-document.c
+++ b/xed/xed-document.c
@@ -1118,11 +1118,36 @@ loaded_query_info_cb (GFile *location,
g_object_unref (doc);
}
+/* Returns the file size limit (in characters) above which highlighting is
+ * disabled for performance reasons, or -1 if there is no limit. The limit
+ * is user-configurable via the "max-file-size-for-highlighting" setting
+ * (expressed in MB there; 0 means "no limit").
+ */
+static gint64
+get_max_char_count_for_highlighting (XedDocument *doc)
+{
+ XedDocumentPrivate *priv;
+ guint max_size_mb;
+
+ priv = xed_document_get_instance_private (doc);
+
+ max_size_mb = g_settings_get_uint (priv->editor_settings, XED_SETTINGS_MAX_FILE_SIZE_FOR_HIGHLIGHTING);
+
+ if (max_size_mb == 0)
+ {
+ return -1;
+ }
+
+ return (gint64) max_size_mb * 1000000;
+}
+
static void
xed_document_loaded_real (XedDocument *doc)
{
XedDocumentPrivate *priv;
GFile *location;
+ gint64 max_chars;
+ gint char_count;
priv = xed_document_get_instance_private (doc);
@@ -1136,6 +1161,21 @@ xed_document_loaded_real (XedDocument *doc)
set_language (doc, language, FALSE);
}
+ max_chars = get_max_char_count_for_highlighting (doc);
+ char_count = gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc));
+
+ if (gtk_source_buffer_get_highlight_syntax (GTK_SOURCE_BUFFER (doc)) &&
+ max_chars >= 0 && char_count > max_chars)
+ {
+ xed_debug_message (DEBUG_DOCUMENT,
+ "File has %d characters, above the %" G_GINT64_FORMAT
+ "-character limit (see the max-file-size-for-highlighting setting): "
+ "disabling syntax highlighting for performance",
+ char_count, max_chars);
+
+ gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (doc), FALSE);
+ }
+
g_get_current_time (&priv->time_of_last_save_or_load);
xed_document_set_content_type (doc, NULL);
@@ -1619,6 +1659,22 @@ xed_document_set_search_context (XedDocument *doc,
{
gboolean highlight = g_settings_get_boolean (priv->editor_settings, XED_SETTINGS_SEARCH_HIGHLIGHTING);
+ if (highlight)
+ {
+ gint64 max_chars = get_max_char_count_for_highlighting (doc);
+ gint char_count = gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc));
+
+ if (max_chars >= 0 && char_count > max_chars)
+ {
+ xed_debug_message (DEBUG_DOCUMENT,
+ "File has %d characters, above the %" G_GINT64_FORMAT
+ "-character limit (see the max-file-size-for-highlighting setting): "
+ "disabling search highlighting for performance",
+ char_count, max_chars);
+ highlight = FALSE;
+ }
+ }
+
gtk_source_search_context_set_highlight (search_context, highlight);
g_object_ref (search_context);
diff --git a/xed/xed-preferences-dialog.c b/xed/xed-preferences-dialog.c
index ca51e545..f2dfb576 100644
--- a/xed/xed-preferences-dialog.c
+++ b/xed/xed-preferences-dialog.c
@@ -113,6 +113,9 @@ struct _XedPreferencesDialog
/* Highlight matching bracket */
GtkWidget *highlight_matching_bracket_switch;
+ /* Max file size for highlighting */
+ GtkWidget *max_file_size_for_highlighting_spin;
+
/* Tabs */
GtkWidget *tab_width_spin;
GtkWidget *use_spaces_switch;
@@ -188,6 +191,7 @@ xed_preferences_dialog_class_init (XedPreferencesDialogClass *klass)
gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, draw_whitespace_newline_switch);
gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, highlight_current_line_switch);
gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, highlight_matching_bracket_switch);
+ gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, max_file_size_for_highlighting_spin);
gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, tab_width_spin);
gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, use_spaces_switch);
gtk_widget_class_bind_template_child (widget_class, XedPreferencesDialog, automatic_indentation_switch);
@@ -386,6 +390,12 @@ setup_editor_page (XedPreferencesDialog *dlg)
"active",
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
+ g_settings_bind (dlg->editor_settings,
+ XED_SETTINGS_MAX_FILE_SIZE_FOR_HIGHLIGHTING,
+ dlg->max_file_size_for_highlighting_spin,
+ "value",
+ G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
+
/* Indentation */
g_settings_bind (dlg->editor_settings,
XED_SETTINGS_TABS_SIZE,
diff --git a/xed/xed-settings.h b/xed/xed-settings.h
index 0b2c3cd0..aa05f6ba 100644
--- a/xed/xed-settings.h
+++ b/xed/xed-settings.h
@@ -98,6 +98,7 @@ void xed_settings_set_list (GSettings *settings,
#define XED_SETTINGS_RESTORE_CURSOR_POSITION "restore-cursor-position"
#define XED_SETTINGS_SYNTAX_HIGHLIGHTING "syntax-highlighting"
#define XED_SETTINGS_SEARCH_HIGHLIGHTING "search-highlighting"
+#define XED_SETTINGS_MAX_FILE_SIZE_FOR_HIGHLIGHTING "max-file-size-for-highlighting"
#define XED_SETTINGS_ENABLE_TAB_SCROLLING "enable-tab-scrolling"
#define XED_SETTINGS_AUTO_CLOSE "auto-close"
#define XED_SETTINGS_TOOLBAR_VISIBLE "toolbar-visible"