[geany/geany] 322fa6: Maintain undo stack when reloading a document
Arthur Rosenstein
git-noreply at xxxxx
Wed Jan 28 14:38:48 UTC 2015
Branch: refs/heads/master
Author: Arthur Rosenstein <artros.misc at gmail.com>
Committer: Arthur Rosenstein <artros.misc at gmail.com>
Date: Sun, 10 Nov 2013 09:11:37 UTC
Commit: 322fa65ff555be84dee05761665fe87d0daa9432
https://github.com/geany/geany/commit/322fa65ff555be84dee05761665fe87d0daa9432
Log Message:
-----------
Maintain undo stack when reloading a document
Modified Paths:
--------------
src/document.c
Modified: src/document.c
75 lines changed, 72 insertions(+), 3 deletions(-)
===================================================================
@@ -1100,6 +1100,8 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename
gchar *locale_filename = NULL;
GeanyFiletype *use_ft;
FileData filedata;
+ UndoReloadData *undo_reload_data;
+ gboolean add_undo_reload_action;
if (reload)
{
@@ -1157,8 +1159,31 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename
monitor_file_setup(doc);
}
- sci_set_undo_collection(doc->editor->sci, FALSE); /* avoid creation of an undo action */
- sci_empty_undo_buffer(doc->editor->sci);
+ if (! reload || ! file_prefs.keep_edit_history_on_reload)
+ {
+ sci_set_undo_collection(doc->editor->sci, FALSE); /* avoid creation of an undo action */
+ sci_empty_undo_buffer(doc->editor->sci);
+ undo_reload_data = NULL;
+ }
+ else
+ {
+ undo_reload_data = (UndoReloadData*) g_malloc(sizeof(UndoReloadData));
+
+ /* We will be adding a UNDO_RELOAD action to the undo stack that undoes
+ * this reload. To do that, we keep collecting undo actions during
+ * reloading, and at the end add an UNDO_RELOAD action that performs
+ * all these actions in bulk. To keep track of how many undo actions
+ * were added during this time, we compare the current undo-stack height
+ * with its height at the end of the process. Note that g_trash_stack_height()
+ * is O(N), which is a little ugly, but this seems like the most maintainable
+ * option. */
+ undo_reload_data->actions_count = g_trash_stack_height(&doc->priv->undo_actions);
+
+ /* We use add_undo_reload_action to track any changes to the document that
+ * require adding an undo action to revert the reload, but that do not
+ * generate an undo action themselves. */
+ add_undo_reload_action = FALSE;
+ }
/* add the text to the ScintillaObject */
sci_set_readonly(doc->editor->sci, FALSE); /* to allow replacing text */
@@ -1167,11 +1192,28 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename
/* detect & set line endings */
editor_mode = utils_get_line_endings(filedata.data, filedata.len);
+ if (undo_reload_data)
+ {
+ undo_reload_data->eol_mode = editor_get_eol_char_mode(doc->editor);
+ /* Force adding an undo-reload action if the EOL mode changed. */
+ if (editor_mode != undo_reload_data->eol_mode)
+ add_undo_reload_action = TRUE;
+ }
sci_set_eol_mode(doc->editor->sci, editor_mode);
g_free(filedata.data);
sci_set_undo_collection(doc->editor->sci, TRUE);
+ /* If reloading and the current and new encodings or BOM states differ,
+ * add appropriate undo actions. */
+ if (undo_reload_data)
+ {
+ if (! utils_str_equal(doc->encoding, filedata.enc))
+ document_undo_add(doc, UNDO_ENCODING, g_strdup(doc->encoding));
+ if (doc->has_bom != filedata.bom)
+ document_undo_add(doc, UNDO_BOM, GINT_TO_POINTER(doc->has_bom));
+ }
+
doc->priv->mtime = filedata.mtime; /* get the modification time from file and keep it */
g_free(doc->encoding); /* if reloading, free old encoding */
doc->encoding = filedata.enc;
@@ -1196,7 +1238,34 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename
}
else
{ /* reloading */
- document_undo_clear(doc);
+ if (undo_reload_data)
+ {
+ /* Calculate the number of undo actions that are part of the reloading
+ * process, and add the UNDO_RELOAD action. */
+ undo_reload_data->actions_count =
+ g_trash_stack_height(&doc->priv->undo_actions) - undo_reload_data->actions_count;
+
+ /* We only add an undo-reload action if the document has actually changed.
+ * At the time of writing, this condition is moot because sci_set_text
+ * generates an undo action even when the text hasn't really changed, so
+ * actions_count is always greater than zero. In the future this might change.
+ * It's arguable whether we should add an undo-reload action unconditionally,
+ * especially since it's possible (if unlikely) that there had only
+ * been "invisible" changes to the document, such as changes in encoding and
+ * EOL mode, but for the time being that's how we roll. */
+ if (undo_reload_data->actions_count > 0 || add_undo_reload_action)
+ document_undo_add(doc, UNDO_RELOAD, undo_reload_data);
+ else
+ g_free(undo_reload_data);
+
+ /* We didn't save the document per-se, but its contents are now
+ * synchronized with the file on disk, hence set a save point here.
+ * We need to do this in this case only, because we don't clear
+ * Scintilla's undo stack. */
+ sci_set_savepoint(doc->editor->sci);
+ }
+ else
+ document_undo_clear(doc);
use_ft = ft;
}
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list