diff --git a/data/org.mate.pluma.gschema.xml.in b/data/org.mate.pluma.gschema.xml.in index 45dd196e3..8ee4e7ead 100644 --- a/data/org.mate.pluma.gschema.xml.in +++ b/data/org.mate.pluma.gschema.xml.in @@ -50,6 +50,11 @@ Autosave Interval Number of minutes after which pluma will automatically save modified files. This will only take effect if the "Autosave" option is turned on. + + true + Hide Tailing Newline + Whether pluma should hide the final newline in opened files if one was present when loading the file. Enabling this will also cause newly created files to be saved with a trailing newline by default. + true Show save confirmation diff --git a/pluma/dialogs/pluma-preferences-dialog.c b/pluma/dialogs/pluma-preferences-dialog.c index f13a86fcd..826418004 100644 --- a/pluma/dialogs/pluma-preferences-dialog.c +++ b/pluma/dialogs/pluma-preferences-dialog.c @@ -121,6 +121,9 @@ struct _PlumaPreferencesDialogPrivate GtkWidget *auto_save_checkbutton; GtkWidget *auto_save_spinbutton; + /* File Format */ + GtkWidget *hide_trailing_newline_checkbutton; + /* Line numbers */ GtkWidget *display_line_numbers_checkbutton; @@ -353,6 +356,11 @@ setup_editor_page (PlumaPreferencesDialog *dlg) dlg->priv->auto_save_spinbutton, "value", G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET | G_SETTINGS_BIND_NO_SENSITIVITY); + g_settings_bind (dlg->priv->editor_settings, + PLUMA_SETTINGS_HIDE_TRAILING_NEWLINE, + dlg->priv->hide_trailing_newline_checkbutton, + "active", + G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET); g_settings_bind (dlg->priv->editor_settings, PLUMA_SETTINGS_DRAWER_NEWLINE, dlg->priv->draw_newlines_checkbutton, @@ -1276,6 +1284,8 @@ pluma_preferences_dialog_init (PlumaPreferencesDialog *dlg) "auto_save_checkbutton", &dlg->priv->auto_save_checkbutton, "auto_save_spinbutton", &dlg->priv->auto_save_spinbutton, + "hide_trailing_newline_checkbutton", &dlg->priv->hide_trailing_newline_checkbutton, + "default_font_checkbutton", &dlg->priv->default_font_checkbutton, "font_button", &dlg->priv->font_button, "font_hbox", &dlg->priv->font_hbox, diff --git a/pluma/dialogs/pluma-preferences-dialog.ui b/pluma/dialogs/pluma-preferences-dialog.ui index c411f0c58..f82080ba8 100644 --- a/pluma/dialogs/pluma-preferences-dialog.ui +++ b/pluma/dialogs/pluma-preferences-dialog.ui @@ -1,67 +1,67 @@ - + 1 160 80 - 1 - 10 + 1 + 10 1 24 8 - 1 - 4 + 1 + 4 1 100 8 - 1 - 10 + 1 + 10 True - False - help-browser + False + help-browser True - False - window-close + False + window-close - False - list-add + False + list-add - False + False Preferences False - True - dialog + True + dialog True - False + False vertical True - False - end + False + end _Help True - True - True - False + True + True + False image1 - True + True False @@ -73,11 +73,11 @@ _Close True - True - True - False + True + True + False image2 - True + True False @@ -89,32 +89,32 @@ False False - end + end 0 True - True - 6 + True + 6 True - False - 12 + False + 12 vertical 18 True - False + False vertical 6 True - False + False start Text Wrapping @@ -130,18 +130,18 @@ True - False - 10 + False + 10 vertical 6 Enable text _wrapping True - True - False - True - True + True + False + True + True False @@ -153,11 +153,11 @@ Do not _split words over two lines True - True - False - 12 - True - True + True + False + 12 + True + True False @@ -182,13 +182,13 @@ True - False + False vertical 6 True - False + False start Highlighting @@ -204,18 +204,18 @@ True - False - 10 + False + 10 vertical 6 Highlight current _line True - True - False - True - True + True + False + True + True False @@ -227,10 +227,10 @@ Highlight matching _bracket True - True - False - True - True + True + False + True + True False @@ -255,13 +255,13 @@ True - False + False vertical 6 True - False + False start Display @@ -277,18 +277,18 @@ True - False - 10 + False + 10 vertical 6 _Display line numbers True - True - False - True - True + True + False + True + True False @@ -299,16 +299,16 @@ True - False + False 6 Display right _margin at column True - True - False - True - True + True + False + True + True @@ -322,10 +322,10 @@ True - True + True adjustment1 - 1 - True + 1 + True True @@ -348,10 +348,10 @@ Display _grid pattern True - True - False - True - True + True + False + True + True False @@ -363,10 +363,10 @@ Display _overview map True - True - False - True - True + True + False + True + True False @@ -393,35 +393,39 @@ True - False + False View - False + False True - False - 12 + False + 12 vertical 18 True - False + False vertical 6 True - False + False start Tab Stops + + + + False @@ -432,23 +436,23 @@ True - False - 10 + False + 10 vertical 6 True - False + False 6 True - False + False _Tab width: - True + True center - tabs_width_spinbutton + tabs_width_spinbutton False @@ -459,10 +463,10 @@ True - True + True 8 adjustment2 - 1 + 1 True 8 @@ -472,6 +476,9 @@ 1 + + + False @@ -483,10 +490,13 @@ Insert _spaces instead of tabs True - True - False - True - True + True + False + True + True + + + False @@ -511,18 +521,21 @@ True - False + False vertical 6 True - False + False start Automatic Indentation + + + False @@ -533,18 +546,21 @@ True - False - 10 + False + 10 vertical 6 _Enable automatic indentation True - True - False - True - True + True + False + True + True + + + False @@ -569,18 +585,22 @@ True - False + False vertical 6 True - False + False start File Saving + + + + False @@ -591,18 +611,21 @@ True - False - 10 + False + 10 vertical 6 Create a _backup copy of files before saving True - True - False - True - True + True + False + True + True + + + False @@ -613,16 +636,16 @@ True - False + False 6 _Autosave files every True - True - False - True - True + True + False + True + True False @@ -633,10 +656,10 @@ True - True + True 8 adjustment3 - 1 + 1 True 8 @@ -649,11 +672,11 @@ True - False + False _minutes - True + True center - auto_save_spinbutton + auto_save_spinbutton False @@ -661,6 +684,9 @@ 2 + + + False @@ -682,21 +708,91 @@ 2 + + + True + False + vertical + + + True + False + start + File Format + + + + + + + + + False + False + 0 + + + + + True + False + 10 + vertical + + + Hide trailing _newline + True + True + False + Hide the final newline in opened files if one was present when loading the file. Enabling this will also cause newly created files to be saved with a trailing newline by default. + True + True + + + + + + False + True + 0 + + + + + False + False + 1 + + + + + False + False + 3 + + True - False + False vertical 6 True - False + False start Show Spaces, Tabs, Newlines + + + + + + + False @@ -708,18 +804,21 @@ vbox True - False - 10 + False + 10 vertical 6 Show _spaces True - True - False - True - True + True + False + True + True + + + False @@ -731,11 +830,14 @@ Show _trailing spaces only True - True - False - 12 - True - True + True + False + 12 + True + True + + + False @@ -747,10 +849,13 @@ Show _tabs True - True - False - True - True + True + False + True + True + + + False @@ -762,11 +867,14 @@ Show _trailing tabs only True - True - False - 12 - True - True + True + False + 12 + True + True + + + False @@ -778,10 +886,13 @@ Show _newlines True - True - False - True - True + True + False + True + True + + + False @@ -800,7 +911,7 @@ False True - 3 + 4 @@ -811,31 +922,31 @@ True - False + False Editor 1 - False + False True - False - 12 + False + 12 vertical 18 True - False + False vertical 6 True - False + False start Font @@ -851,18 +962,18 @@ True - False - 10 + False + 10 vertical 6 _Use the system fixed width font (%s) True - True - False - True - True + True + False + True + True False @@ -873,17 +984,17 @@ True - False + False 12 True - False + False start Editor _font: - True + True center - font_button + font_button False @@ -894,11 +1005,11 @@ True - True - False + True + False Sans 12 Pick the editor font - True + True False @@ -930,13 +1041,13 @@ True - False + False vertical 6 True - False + False start Color Scheme @@ -952,23 +1063,23 @@ True - False + False vertical 6 True - True + True True True - etched-in + etched-in True - True + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - True + False + True @@ -984,17 +1095,17 @@ True - False + False 6 - end + end _Add... True - True - False + True + False install_scheme_image - True + True False @@ -1006,9 +1117,9 @@ _Remove True - True - False - True + True + False + True False @@ -1045,19 +1156,19 @@ True - False + False Font & Colors 2 - False + False True - False - 12 + False + 12 vertical @@ -1070,12 +1181,12 @@ True - False + False Plugins 3 - False + False @@ -1091,8 +1202,5 @@ helpbutton1 closebutton1 - - - diff --git a/pluma/pluma-document-input-stream.c b/pluma/pluma-document-input-stream.c index 8bae35638..9187ed2f1 100644 --- a/pluma/pluma-document-input-stream.c +++ b/pluma/pluma-document-input-stream.c @@ -43,6 +43,7 @@ struct _PlumaDocumentInputStreamPrivate gint bytes_partial; PlumaDocumentNewlineType newline_type; + gboolean add_trailing_newline; guint newline_added : 1; guint is_initialized : 1; @@ -54,7 +55,8 @@ enum { PROP_0, PROP_BUFFER, - PROP_NEWLINE_TYPE + PROP_NEWLINE_TYPE, + PROP_ADD_TRAILING_NEWLINE, }; static gssize pluma_document_input_stream_read (GInputStream *stream, @@ -84,6 +86,10 @@ pluma_document_input_stream_set_property (GObject *object, stream->priv->newline_type = g_value_get_enum (value); break; + case PROP_ADD_TRAILING_NEWLINE: + stream->priv->add_trailing_newline = g_value_get_boolean (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -108,6 +114,10 @@ pluma_document_input_stream_get_property (GObject *object, g_value_set_enum (value, stream->priv->newline_type); break; + case PROP_ADD_TRAILING_NEWLINE: + g_value_set_boolean (value, stream->priv->add_trailing_newline); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -152,6 +162,16 @@ pluma_document_input_stream_class_init (PlumaDocumentInputStreamClass *klass) G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (gobject_class, + PROP_ADD_TRAILING_NEWLINE, + g_param_spec_boolean ("add-trailing-newline", + "Add Trailing Newline", + "Automatically add a trailing newline to the file contents?", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT)); } static void @@ -428,30 +448,33 @@ pluma_document_input_stream_read (GInputStream *stream, space_left -= n; } while (space_left > 0 && n != 0 && dstream->priv->bytes_partial == 0); - /* Make sure that non-empty files are always terminated with \n (see bug #95676). - * Note that we strip the trailing \n when loading the file */ - gtk_text_buffer_get_iter_at_mark (dstream->priv->buffer, - &iter, - dstream->priv->pos); - - if (gtk_text_iter_is_end (&iter) && - !gtk_text_iter_is_start (&iter)) + if (dstream->priv->add_trailing_newline) { - gssize newline_size; - - newline_size = get_new_line_size (dstream); + /* Make sure that non-empty files are always terminated with \n (see bug #95676). + * Note that we strip the trailing \n when loading the file */ + gtk_text_buffer_get_iter_at_mark (dstream->priv->buffer, + &iter, + dstream->priv->pos); - if (space_left >= newline_size && - !dstream->priv->newline_added) + if (gtk_text_iter_is_end (&iter) && + !gtk_text_iter_is_start (&iter)) { - const gchar *newline; + gssize newline_size; + + newline_size = get_new_line_size (dstream); - newline = get_new_line (dstream); + if (space_left >= newline_size && + !dstream->priv->newline_added) + { + const gchar *newline; + + newline = get_new_line (dstream); - memcpy ((void *) ((gsize) buffer + read), newline, newline_size); + memcpy ((void *) ((gsize) buffer + read), newline, newline_size); - read += newline_size; - dstream->priv->newline_added = TRUE; + read += newline_size; + dstream->priv->newline_added = TRUE; + } } } diff --git a/pluma/pluma-document-loader.c b/pluma/pluma-document-loader.c index e8ceffb91..ae4de2417 100644 --- a/pluma/pluma-document-loader.c +++ b/pluma/pluma-document-loader.c @@ -76,7 +76,9 @@ enum PROP_DOCUMENT, PROP_URI, PROP_ENCODING, - PROP_NEWLINE_TYPE + PROP_NEWLINE_TYPE, + PROP_TRIM_TRAILING_NEWLINE, + PROP_TRIMMED_TRAILING_NEWLINE, }; #define READ_CHUNK_SIZE 8192 @@ -105,6 +107,7 @@ struct _PlumaDocumentLoaderPrivate PlumaDocumentNewlineType auto_detected_newline_type; GFile *gfile; goffset bytes_read; + gboolean trim_trailing_newline; /* Handle for remote files */ GCancellable *cancellable; @@ -144,6 +147,9 @@ pluma_document_loader_set_property (GObject *object, case PROP_NEWLINE_TYPE: loader->priv->auto_detected_newline_type = g_value_get_enum (value); break; + case PROP_TRIM_TRAILING_NEWLINE: + loader->priv->trim_trailing_newline = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -172,6 +178,23 @@ pluma_document_loader_get_property (GObject *object, case PROP_NEWLINE_TYPE: g_value_set_enum (value, loader->priv->auto_detected_newline_type); break; + case PROP_TRIM_TRAILING_NEWLINE: + g_value_set_boolean (value, loader->priv->trim_trailing_newline); + break; + case PROP_TRIMMED_TRAILING_NEWLINE: + if (loader->priv->output != NULL) + { + gboolean trimmed_trailing_newline; + g_object_get (loader->priv->output, + "trimmed-trailing-newline", &trimmed_trailing_newline, + NULL); + g_value_set_boolean (value, trimmed_trailing_newline); + } + else + { + g_value_set_boolean (value, FALSE); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -277,15 +300,23 @@ pluma_document_loader_class_init (PlumaDocumentLoaderClass *klass) G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, - PROP_NEWLINE_TYPE, - g_param_spec_enum ("newline-type", - "Newline type", - "The accepted types of line ending", - PLUMA_TYPE_DOCUMENT_NEWLINE_TYPE, - PLUMA_DOCUMENT_NEWLINE_TYPE_LF, - G_PARAM_READWRITE | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_BLURB)); + PROP_TRIM_TRAILING_NEWLINE, + g_param_spec_boolean ("trim-trailing-newline", + "Trim Trailing Newline", + "Remove the final received newline from the document buffer?", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_TRIMMED_TRAILING_NEWLINE, + g_param_spec_boolean ("trimmed-trailing-newline", + "Trailing Newline Trimmed", + "Was the final received newline removed from the document buffer?", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); signals[LOADING] = g_signal_new ("loading", @@ -650,6 +681,9 @@ finish_query_info (AsyncData *async) /* Output stream */ loader->priv->output = pluma_document_output_stream_new (loader->priv->document); + g_object_set (G_OBJECT (loader->priv->output), + "trim-trailing-newline", loader->priv->trim_trailing_newline, + NULL); /* start reading */ read_file_chunk (async); diff --git a/pluma/pluma-document-output-stream.c b/pluma/pluma-document-output-stream.c index f7ecf5af2..2b54fd239 100644 --- a/pluma/pluma-document-output-stream.c +++ b/pluma/pluma-document-output-stream.c @@ -45,6 +45,9 @@ struct _PlumaDocumentOutputStreamPrivate gchar *buffer; gsize buflen; + gboolean trim_trailing_newline; + gboolean trimmed_trailing_newline; + guint is_initialized : 1; guint is_closed : 1; }; @@ -52,7 +55,9 @@ struct _PlumaDocumentOutputStreamPrivate enum { PROP_0, - PROP_DOCUMENT + PROP_DOCUMENT, + PROP_TRIM_TRAILING_NEWLINE, + PROP_TRIMMED_TRAILING_NEWLINE, }; G_DEFINE_TYPE_WITH_PRIVATE (PlumaDocumentOutputStream, pluma_document_output_stream, G_TYPE_OUTPUT_STREAM) @@ -85,6 +90,10 @@ pluma_document_output_stream_set_property (GObject *object, stream->priv->doc = PLUMA_DOCUMENT (g_value_get_object (value)); break; + case PROP_TRIM_TRAILING_NEWLINE: + stream->priv->trim_trailing_newline = g_value_get_boolean (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -105,6 +114,14 @@ pluma_document_output_stream_get_property (GObject *object, g_value_set_object (value, stream->priv->doc); break; + case PROP_TRIM_TRAILING_NEWLINE: + g_value_set_boolean (value, stream->priv->trim_trailing_newline); + break; + + case PROP_TRIMMED_TRAILING_NEWLINE: + g_value_set_boolean (value, stream->priv->trimmed_trailing_newline); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -166,6 +183,25 @@ pluma_document_output_stream_class_init (PlumaDocumentOutputStreamClass *klass) PLUMA_TYPE_DOCUMENT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_TRIM_TRAILING_NEWLINE, + g_param_spec_boolean ("trim-trailing-newline", + "Trim Trailing Newline", + "Remove the final received newline from the document buffer?", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_TRIMMED_TRAILING_NEWLINE, + g_param_spec_boolean ("trimmed-trailing-newline", + "Trailing Newline Trimmed", + "Was the final received newline removed from the document buffer?", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } static void @@ -176,6 +212,8 @@ pluma_document_output_stream_init (PlumaDocumentOutputStream *stream) stream->priv->buffer = NULL; stream->priv->buflen = 0; + stream->priv->trimmed_trailing_newline = FALSE; + stream->priv->is_initialized = FALSE; stream->priv->is_closed = FALSE; } @@ -264,13 +302,18 @@ remove_ending_newline (PlumaDocumentOutputStream *stream) gtk_text_buffer_delete (GTK_TEXT_BUFFER (stream->priv->doc), &start, &end); + + stream->priv->trimmed_trailing_newline = TRUE; } } static void end_append_text_to_document (PlumaDocumentOutputStream *stream) { - remove_ending_newline (stream); + if (stream->priv->trim_trailing_newline) + { + remove_ending_newline (stream); + } gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (stream->priv->doc), FALSE); diff --git a/pluma/pluma-document-saver.c b/pluma/pluma-document-saver.c index 7f11376f5..caafd254f 100644 --- a/pluma/pluma-document-saver.c +++ b/pluma/pluma-document-saver.c @@ -63,7 +63,8 @@ enum { PROP_URI, PROP_ENCODING, PROP_NEWLINE_TYPE, - PROP_FLAGS + PROP_ADD_TRAILING_NEWLINE, + PROP_FLAGS, }; typedef struct @@ -94,6 +95,7 @@ struct _PlumaDocumentSaverPrivate gchar *uri; const PlumaEncoding *encoding; PlumaDocumentNewlineType newline_type; + gboolean add_trailing_newline; PlumaDocumentSaveFlags flags; @@ -139,6 +141,9 @@ pluma_document_saver_set_property (GObject *object, case PROP_NEWLINE_TYPE: saver->priv->newline_type = g_value_get_enum (value); break; + case PROP_ADD_TRAILING_NEWLINE: + saver->priv->add_trailing_newline = g_value_get_boolean (value); + break; case PROP_FLAGS: saver->priv->flags = g_value_get_flags (value); break; @@ -170,6 +175,9 @@ pluma_document_saver_get_property (GObject *object, case PROP_NEWLINE_TYPE: g_value_set_enum (value, saver->priv->newline_type); break; + case PROP_ADD_TRAILING_NEWLINE: + g_value_set_boolean (value, saver->priv->add_trailing_newline); + break; case PROP_FLAGS: g_value_set_flags (value, saver->priv->flags); break; @@ -309,6 +317,16 @@ pluma_document_saver_class_init (PlumaDocumentSaverClass *klass) G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_ADD_TRAILING_NEWLINE, + g_param_spec_boolean ("add-trailing-newline", + "Add Trailing Newline", + "Automatically add a trailing newline to the file contents?", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_FLAGS, g_param_spec_flags ("flags", @@ -724,6 +742,10 @@ async_replace_ready_callback (GFile *source, saver->priv->input = pluma_document_input_stream_new (GTK_TEXT_BUFFER (saver->priv->document), saver->priv->newline_type); + g_object_set (G_OBJECT (saver->priv->input), + "add-trailing-newline", saver->priv->add_trailing_newline, + NULL); + saver->priv->size = pluma_document_input_stream_get_total_size (PLUMA_DOCUMENT_INPUT_STREAM (saver->priv->input)); read_file_chunk (async); diff --git a/pluma/pluma-document.c b/pluma/pluma-document.c index f2cb8f943..a78f6df3f 100644 --- a/pluma/pluma-document.c +++ b/pluma/pluma-document.c @@ -128,6 +128,7 @@ struct _PlumaDocumentPrivate gint num_of_lines_search_text; PlumaDocumentNewlineType newline_type; + gboolean hide_trailing_newline; /* Temp data while loading */ PlumaDocumentLoader *loader; @@ -165,7 +166,8 @@ enum { PROP_ENCODING, PROP_CAN_SEARCH_AGAIN, PROP_ENABLE_SEARCH_HIGHLIGHTING, - PROP_NEWLINE_TYPE + PROP_NEWLINE_TYPE, + PROP_HIDE_TRAILING_NEWLINE, }; enum { @@ -360,6 +362,9 @@ pluma_document_get_property (GObject *object, case PROP_NEWLINE_TYPE: g_value_set_enum (value, doc->priv->newline_type); break; + case PROP_HIDE_TRAILING_NEWLINE: + g_value_set_boolean (value, doc->priv->hide_trailing_newline); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -392,6 +397,13 @@ pluma_document_set_property (GObject *object, pluma_document_set_content_type (doc, g_value_get_string (value)); break; + case PROP_HIDE_TRAILING_NEWLINE: + doc->priv->hide_trailing_newline = g_value_get_boolean (value); + /* XXX: This should also change whether newline is visible to the user + or not (ie: add or remove the newline from the buffer). Not + really important unless this property is actually exposed in + the user interface though. */ + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -532,6 +544,21 @@ pluma_document_class_init (PlumaDocumentClass *klass) G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)); + /** + * PlumaDocument:hide-trailing-newline: + * + * The :hide-trailing-newline property determines whether the final newline + * in the document (if any) is stripped on loading and automatically readded + * on saving the document + */ + g_object_class_install_property (object_class, PROP_HIDE_TRAILING_NEWLINE, + g_param_spec_boolean ("hide-trailing-newline", + "Hide Trailing Newline", + "Drop trailing newline from input and add it on output", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* This signal is used to update the cursor position is the statusbar, * it's emitted either when the insert mark is moved explicitely or * when the buffer changes (insert/delete). @@ -981,6 +1008,8 @@ pluma_document_init (PlumaDocument *doc) doc->priv->encoding = pluma_encoding_get_utf8 (); doc->priv->newline_type = PLUMA_DOCUMENT_NEWLINE_TYPE_DEFAULT; + doc->priv->hide_trailing_newline = g_settings_get_boolean (doc->priv->editor_settings, + PLUMA_SETTINGS_HIDE_TRAILING_NEWLINE); undo_actions = g_settings_get_uint (doc->priv->editor_settings, PLUMA_SETTINGS_MAX_UNDO_ACTIONS); @@ -1422,6 +1451,33 @@ document_loader_loaded (PlumaDocumentLoader *loader, pluma_document_set_newline_type (doc, pluma_document_loader_get_newline_type (loader)); + if (doc->priv->hide_trailing_newline) + { + gboolean trimmed_trailing_newline; + gint doc_char_count; + + g_object_get (loader, + "trimmed-trailing-newline", &trimmed_trailing_newline, + NULL); + + doc_char_count = gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc)); + + if (!trimmed_trailing_newline && doc_char_count > 0) + { + /* Document did not contain any trailing newline, so we want to + change hide-trailing-newline to FALSE so that saving the + document doesn’t automatically add a trailing newline if it + wasn’t previously present. */ + /* Note that we special-case empty documents here as these never + contain a trailing newline, so we cannot make any assumptions + on whether the omission of the trailing newline was intentional + or not. */ + g_object_set (doc, + "hide-trailing-newline", FALSE, + NULL); + } + } + restore_cursor = g_settings_get_boolean (doc->priv->editor_settings, PLUMA_SETTINGS_RESTORE_CURSOR_POSITION); @@ -1541,6 +1597,10 @@ pluma_document_load_real (PlumaDocument *doc, G_CALLBACK (document_loader_loading), doc); + g_object_set (G_OBJECT (doc->priv->loader), + "trim-trailing-newline", doc->priv->hide_trailing_newline, + NULL); + doc->priv->create = create; doc->priv->requested_encoding = encoding; doc->priv->requested_line_pos = line_pos; @@ -1695,6 +1755,10 @@ pluma_document_save_real (PlumaDocument *doc, G_CALLBACK (document_saver_saving), doc); + g_object_set (G_OBJECT (doc->priv->saver), + "add-trailing-newline", doc->priv->hide_trailing_newline, + NULL); + doc->priv->requested_encoding = encoding; pluma_document_saver_save (doc->priv->saver, diff --git a/pluma/pluma-settings.h b/pluma/pluma-settings.h index a429c0930..508371680 100644 --- a/pluma/pluma-settings.h +++ b/pluma/pluma-settings.h @@ -103,6 +103,7 @@ GSList * pluma_settings_get_writable_vfs_schemes (GSettings *sett #define PLUMA_SETTINGS_CREATE_BACKUP_COPY "create-backup-copy" #define PLUMA_SETTINGS_AUTO_SAVE "auto-save" #define PLUMA_SETTINGS_AUTO_SAVE_INTERVAL "auto-save-interval" +#define PLUMA_SETTINGS_HIDE_TRAILING_NEWLINE "hide-trailing-newline" #define PLUMA_SETTINGS_MAX_UNDO_ACTIONS "max-undo-actions" #define PLUMA_SETTINGS_WRAP_MODE "wrap-mode" #define PLUMA_SETTINGS_TABS_SIZE "tabs-size"