[gnome-builder] libide-code: port IdeBuffer to GTK 4
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide-code: port IdeBuffer to GTK 4
- Date: Tue, 12 Jul 2022 06:39:07 +0000 (UTC)
commit 1f9c60a47a9398c46906753e8c5766f9bc830ddb
Author: Christian Hergert <chergert redhat com>
Date: Mon Jul 11 16:17:32 2022 -0700
libide-code: port IdeBuffer to GTK 4
* Allow setting charset for a buffer to allow for alternative encoding
when saving.
* Allow setting newline type for buffer.
* Introduce "commit funcs" to hook into buffer tracking components.
* Update availability macros.
* Cleanup buffer flags naming and remove unused features.
src/libide/code/ide-buffer-addin.c | 20 -
src/libide/code/ide-buffer-addin.h | 24 +-
src/libide/code/ide-buffer-change-monitor.c | 4 -
src/libide/code/ide-buffer-change-monitor.h | 12 +-
src/libide/code/ide-buffer-manager.c | 53 +--
src/libide/code/ide-buffer-manager.h | 56 ++-
src/libide/code/ide-buffer.c | 600 ++++++++++++++++------------
src/libide/code/ide-buffer.h | 122 +++---
8 files changed, 470 insertions(+), 421 deletions(-)
---
diff --git a/src/libide/code/ide-buffer-addin.c b/src/libide/code/ide-buffer-addin.c
index d9b78b887..756f8db6f 100644
--- a/src/libide/code/ide-buffer-addin.c
+++ b/src/libide/code/ide-buffer-addin.c
@@ -43,8 +43,6 @@
* may be used by views to show the misspelled words. This is preferrable
* to adding a spellchecker in each view because it allows for multiple
* views to share one spellcheker on the underlying buffer.
- *
- * Since: 3.32
*/
G_DEFINE_INTERFACE (IdeBufferAddin, ide_buffer_addin, G_TYPE_OBJECT)
@@ -85,8 +83,6 @@ ide_buffer_addin_default_init (IdeBufferAddinInterface *iface)
*
* This calls the load virtual function of #IdeBufferAddin to request
* that the addin load itself.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_load (IdeBufferAddin *self,
@@ -110,8 +106,6 @@ ide_buffer_addin_load (IdeBufferAddin *self,
*
* The addin should cancel any in-flight operations and attempt to drop
* references to the buffer or any other machinery as soon as possible.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_unload (IdeBufferAddin *self,
@@ -135,8 +129,6 @@ ide_buffer_addin_unload (IdeBufferAddin *self,
*
* It is not guaranteed that this function will be called for addins that were
* loaded after the buffer already loaded a file.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_file_loaded (IdeBufferAddin *self,
@@ -160,8 +152,6 @@ ide_buffer_addin_file_loaded (IdeBufferAddin *self,
*
* This function gives a chance for plugins to modify the buffer right before
* writing to disk.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_save_file (IdeBufferAddin *self,
@@ -184,8 +174,6 @@ ide_buffer_addin_save_file (IdeBufferAddin *self,
* @file: a #GFile
*
* This function is called for an addin after a file has been saved to disk.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_file_saved (IdeBufferAddin *self,
@@ -209,8 +197,6 @@ ide_buffer_addin_file_saved (IdeBufferAddin *self,
*
* This vfunc is called when the source language in the buffer changes. This
* will only be delivered to addins that support multiple languages.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_language_set (IdeBufferAddin *self,
@@ -233,8 +219,6 @@ ide_buffer_addin_language_set (IdeBufferAddin *self,
* changes provided by the user. It is a convenient way to know when you
* should perform more background work without having to coalesce work
* yourself.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_change_settled (IdeBufferAddin *self,
@@ -254,8 +238,6 @@ ide_buffer_addin_change_settled (IdeBufferAddin *self,
*
* This function is called when the #GtkSourceStyleScheme of the #IdeBuffer
* has changed.
- *
- * Since: 3.32
*/
void
ide_buffer_addin_style_scheme_changed (IdeBufferAddin *self,
@@ -277,8 +259,6 @@ ide_buffer_addin_style_scheme_changed (IdeBufferAddin *self,
* that provides the addin.
*
* Returns: (transfer none) (nullable): An #IdeBufferAddin or %NULL
- *
- * Since: 3.32
*/
IdeBufferAddin *
ide_buffer_addin_find_by_module_name (IdeBuffer *buffer,
diff --git a/src/libide/code/ide-buffer-addin.h b/src/libide/code/ide-buffer-addin.h
index df84afe42..e0e779f6f 100644
--- a/src/libide/code/ide-buffer-addin.h
+++ b/src/libide/code/ide-buffer-addin.h
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
#define IDE_TYPE_BUFFER_ADDIN (ide_buffer_addin_get_type())
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
G_DECLARE_INTERFACE (IdeBufferAddin, ide_buffer_addin, IDE, BUFFER_ADDIN, GObject)
struct _IdeBufferAddinInterface
@@ -68,44 +68,44 @@ struct _IdeBufferAddinInterface
GError **error);
};
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_load (IdeBufferAddin *self,
IdeBuffer *buffer);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_unload (IdeBufferAddin *self,
IdeBuffer *buffer);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_file_loaded (IdeBufferAddin *self,
IdeBuffer *buffer,
GFile *file);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_save_file (IdeBufferAddin *self,
IdeBuffer *buffer,
GFile *file);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_file_saved (IdeBufferAddin *self,
IdeBuffer *buffer,
GFile *file);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_language_set (IdeBufferAddin *self,
IdeBuffer *buffer,
const gchar *language_id);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_change_settled (IdeBufferAddin *self,
IdeBuffer *buffer);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_style_scheme_changed (IdeBufferAddin *self,
IdeBuffer *buffer);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_addin_settle_async (IdeBufferAddin *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_addin_settle_finish (IdeBufferAddin *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBufferAddin *ide_buffer_addin_find_by_module_name (IdeBuffer *buffer,
const gchar *module_name);
diff --git a/src/libide/code/ide-buffer-change-monitor.c b/src/libide/code/ide-buffer-change-monitor.c
index b812bfb65..ae5b7759e 100644
--- a/src/libide/code/ide-buffer-change-monitor.c
+++ b/src/libide/code/ide-buffer-change-monitor.c
@@ -194,8 +194,6 @@ ide_buffer_change_monitor_reload (IdeBufferChangeMonitor *self)
*
* Calls @callback for every line between @line_begin and @line_end that have
* an addition, deletion, or change.
- *
- * Since: 3.32
*/
void
ide_buffer_change_monitor_foreach_change (IdeBufferChangeMonitor *self,
@@ -219,8 +217,6 @@ ide_buffer_change_monitor_foreach_change (IdeBufferChangeMonitor *sel
* Gets the #IdeBufferChangeMonitor:buffer property.
*
* Returns: (transfer none): an #IdeBuffer
- *
- * Since: 3.32
*/
IdeBuffer *
ide_buffer_change_monitor_get_buffer (IdeBufferChangeMonitor *self)
diff --git a/src/libide/code/ide-buffer-change-monitor.h b/src/libide/code/ide-buffer-change-monitor.h
index da6ed9b48..8febcb95d 100644
--- a/src/libide/code/ide-buffer-change-monitor.h
+++ b/src/libide/code/ide-buffer-change-monitor.h
@@ -33,7 +33,7 @@ G_BEGIN_DECLS
#define IDE_TYPE_BUFFER_CHANGE_MONITOR (ide_buffer_change_monitor_get_type())
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
G_DECLARE_DERIVABLE_TYPE (IdeBufferChangeMonitor, ide_buffer_change_monitor, IDE, BUFFER_CHANGE_MONITOR,
IdeObject)
typedef enum
@@ -68,20 +68,20 @@ struct _IdeBufferChangeMonitorClass
gpointer _reserved[8];
};
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBuffer *ide_buffer_change_monitor_get_buffer (IdeBufferChangeMonitor *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_change_monitor_emit_changed (IdeBufferChangeMonitor *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_change_monitor_foreach_change (IdeBufferChangeMonitor *self,
guint line_begin,
guint line_end,
IdeBufferChangeMonitorForeachFunc callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBufferLineChange ide_buffer_change_monitor_get_change (IdeBufferChangeMonitor *self,
guint line);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_change_monitor_reload (IdeBufferChangeMonitor *self);
G_END_DECLS
diff --git a/src/libide/code/ide-buffer-manager.c b/src/libide/code/ide-buffer-manager.c
index 2f2935d7a..525af6522 100644
--- a/src/libide/code/ide-buffer-manager.c
+++ b/src/libide/code/ide-buffer-manager.c
@@ -73,7 +73,7 @@ typedef struct
static void list_model_iface_init (GListModelInterface *iface);
G_DEFINE_FINAL_TYPE_WITH_CODE (IdeBufferManager, ide_buffer_manager, IDE_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
enum {
PROP_0,
@@ -253,8 +253,6 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* Builder will attempt to load. Larger files will fail to load to help
* ensure that Builder's buffer manager does not attempt to load files that
* will slow the buffer management beyond usefulness.
- *
- * Since: 3.32
*/
properties [PROP_MAX_FILE_SIZE] =
g_param_spec_int64 ("max-file-size",
@@ -271,11 +269,8 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* IdeBufferManager:load-buffer:
* @self: an #IdeBufferManager
* @buffer: an #IdeBuffer
- * @create_new_view: if the buffer requires a view to be created
*
* The "load-buffer" signal is emitted before a buffer is (re)loaded.
- *
- * Since: 3.32
*/
signals [LOAD_BUFFER] =
g_signal_new ("load-buffer",
@@ -285,7 +280,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
NULL,
NULL,
NULL,
- G_TYPE_NONE, 2, IDE_TYPE_BUFFER, G_TYPE_BOOLEAN);
+ G_TYPE_NONE, 1, IDE_TYPE_BUFFER);
/**
* IdeBufferManager::buffer-loaded:
@@ -294,8 +289,6 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
*
* The "buffer-loaded" signal is emitted when an #IdeBuffer has loaded
* a file from storage.
- *
- * Since: 3.32
*/
signals [BUFFER_LOADED] =
g_signal_new ("buffer-loaded",
@@ -317,8 +310,6 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
*
* The "buffer-saved" signal is emitted when an #IdeBuffer has been saved
* to storage.
- *
- * Since: 3.32
*/
signals [BUFFER_SAVED] =
g_signal_new ("buffer-saved",
@@ -340,8 +331,6 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
*
* The "buffer-unloaded" signal is emitted when an #IdeBuffer has been
* unloaded from the buffer manager.
- *
- * Since: 3.32
*/
signals [BUFFER_UNLOADED] =
g_signal_new ("buffer-unloaded",
@@ -402,8 +391,6 @@ ide_buffer_manager_next_temp_file (IdeBufferManager *self)
* Gets the #IdeBufferManager for the #IdeContext.
*
* Returns: (transfer none): an #IdeBufferManager
- *
- * Since: 3.32
*/
IdeBufferManager *
ide_buffer_manager_from_context (IdeContext *context)
@@ -427,8 +414,6 @@ ide_buffer_manager_from_context (IdeContext *context)
* of @file.
*
* Returns: %TRUE if a buffer exists for @file
- *
- * Since: 3.32
*/
gboolean
ide_buffer_manager_has_file (IdeBufferManager *self,
@@ -469,8 +454,6 @@ ide_buffer_manager_find_buffer_cb (IdeObject *object,
* Locates the #IdeBuffer that matches #GFile, if any.
*
* Returns: (transfer full): an #IdeBuffer or %NULL
- *
- * Since: 3.32
*/
IdeBuffer *
ide_buffer_manager_find_buffer (IdeBufferManager *self,
@@ -500,8 +483,6 @@ ide_buffer_manager_find_buffer (IdeBufferManager *self,
* various subsystems.
*
* Returns: the max file size in bytes or -1 for unlimited
- *
- * Since: 3.32
*/
gssize
ide_buffer_manager_get_max_file_size (IdeBufferManager *self)
@@ -520,8 +501,6 @@ ide_buffer_manager_get_max_file_size (IdeBufferManager *self)
* Sets the max file size that will be allowed to be loaded from disk.
* This is useful to protect Builder from files that would overload the
* various subsystems.
- *
- * Since: 3.32
*/
void
ide_buffer_manager_set_max_file_size (IdeBufferManager *self,
@@ -598,8 +577,6 @@ ide_buffer_manager_load_file_cb (GObject *object,
*
* If @notif is non-NULL, it will be updated with status information while
* loading the document.
- *
- * Since: 3.32
*/
void
ide_buffer_manager_load_file_async (IdeBufferManager *self,
@@ -614,8 +591,6 @@ ide_buffer_manager_load_file_async (IdeBufferManager *self,
g_autoptr(IdeTask) task = NULL;
g_autoptr(GFile) temp_file = NULL;
IdeBuffer *existing;
- gboolean create_new_view = FALSE;
- gboolean is_new = FALSE;
IDE_ENTRY;
@@ -665,7 +640,6 @@ ide_buffer_manager_load_file_async (IdeBufferManager *self,
buffer = ide_buffer_manager_create_buffer (self, file,
(flags & IDE_BUFFER_OPEN_FLAGS_DISABLE_ADDINS) == 0,
temp_file != NULL);
- is_new = TRUE;
}
/* Save this task for later in case we get in a second request to open
@@ -673,14 +647,10 @@ ide_buffer_manager_load_file_async (IdeBufferManager *self,
*/
g_hash_table_insert (self->loading_tasks, g_file_dup (file), g_object_ref (task));
- /* We might have listeners tracking new buffers. Apply some rules to
- * determine if we need the UI to create a new view for the buffer.
- */
+ /* Notify any listeners of new buffers */
g_assert (buffer != NULL);
g_assert (IDE_IS_BUFFER (buffer));
- create_new_view = !(flags & IDE_BUFFER_OPEN_FLAGS_NO_VIEW) &&
- (is_new || (flags & IDE_BUFFER_OPEN_FLAGS_BACKGROUND) == 0);
- g_signal_emit (self, signals [LOAD_BUFFER], 0, buffer, create_new_view);
+ g_signal_emit (self, signals [LOAD_BUFFER], 0, buffer);
/* Now we can load the buffer asynchronously */
_ide_buffer_load_file_async (buffer,
@@ -701,8 +671,6 @@ ide_buffer_manager_load_file_async (IdeBufferManager *self,
* Completes an asynchronous request to ide_buffer_manager_laod_file_async().
*
* Returns: (transfer full): an #IdeBuffer
- *
- * Since: 3.32
*/
IdeBuffer *
ide_buffer_manager_load_file_finish (IdeBufferManager *self,
@@ -826,8 +794,6 @@ ide_buffer_manager_save_all_foreach_cb (IdeObject *object,
* buffers to disk.
*
* @callback will be executed after all the buffers have been saved.
- *
- * Since: 3.32
*/
void
ide_buffer_manager_save_all_async (IdeBufferManager *self,
@@ -870,8 +836,6 @@ ide_buffer_manager_save_all_async (IdeBufferManager *self,
* Completes an asynchronous request to save all buffers.
*
* Returns: %TRUE if all the buffers were saved successfully
- *
- * Since: 3.32
*/
gboolean
ide_buffer_manager_save_all_finish (IdeBufferManager *self,
@@ -1110,8 +1074,6 @@ ide_buffer_manager_apply_edits_completed_cb (IdeBufferManager *self,
*
* @callback should call ide_buffer_manager_apply_edits_finish() to get the
* result of this operation.
- *
- * Since: 3.32
*/
void
ide_buffer_manager_apply_edits_async (IdeBufferManager *self,
@@ -1184,11 +1146,6 @@ ide_buffer_manager_apply_edits_async (IdeBufferManager *self,
*/
ide_buffer_manager_load_file_async (self,
file,
- IDE_BUFFER_OPEN_FLAGS_NO_VIEW |
- /* We are only temporary loading the buffer to replace text
- * there, so let's avoid any heavy useless work that the
- * buffer addins might do.
- */
IDE_BUFFER_OPEN_FLAGS_DISABLE_ADDINS,
NULL,
cancellable,
@@ -1318,8 +1275,6 @@ ide_buffer_manager_foreach_cb (IdeObject *object,
* @user_data: closure data for @foreach_func
*
* Calls @foreach_func for every buffer registered.
- *
- * Since: 3.32
*/
void
ide_buffer_manager_foreach (IdeBufferManager *self,
diff --git a/src/libide/code/ide-buffer-manager.h b/src/libide/code/ide-buffer-manager.h
index 8c7fd28c8..1423ef956 100644
--- a/src/libide/code/ide-buffer-manager.h
+++ b/src/libide/code/ide-buffer-manager.h
@@ -32,24 +32,20 @@ G_BEGIN_DECLS
/**
* IdeBufferOpenFlags:
- * @IDE_BUFFER_OPEN_FLAGS_NONE: No special processing will be performed
- * @IDE_BUFFER_OPEN_FLAGS_BACKGROUND: Open the document in the background (behind current view)
- * @IDE_BUFFER_OPEN_FLAGS_NO_VIEW: Open the document but do not create a new view for it
- * @IDE_BUFFER_OPEN_FLAGS_DISABLE_ADDINS: Disables any buffer addin for this buffer.
+ * @IDE_BUFFER_OPEN_FLAGS_NONE: No special processing will be performed.
+ * @IDE_BUFFER_OPEN_FLAGS_FORCE_RELOAD: Reload the buffer if already loaded.
+ * @IDE_BUFFER_OPEN_FLAGS_DISABLE_ADDINS: Disables any buffer addin for this
+ * buffer.
*
- * The #IdeBufferOpenFlags enumeration is used to specify how a document should
- * be opened by the workbench. Plugins may want to have a bit of control over
- * where the document is opened, and this provides a some control over that.
- *
- * Since: 3.32
+ * The #IdeBufferOpenFlags enumeration is used to specify how the buffer
+ * manager should handle loading the buffer and if certain features should
+ * be enabled or disabled.
*/
typedef enum
{
- IDE_BUFFER_OPEN_FLAGS_NONE = 0,
- IDE_BUFFER_OPEN_FLAGS_BACKGROUND = 1 << 0,
- IDE_BUFFER_OPEN_FLAGS_NO_VIEW = 1 << 1,
- IDE_BUFFER_OPEN_FLAGS_FORCE_RELOAD = 1 << 2,
- IDE_BUFFER_OPEN_FLAGS_DISABLE_ADDINS = 1 << 3,
+ IDE_BUFFER_OPEN_FLAGS_NONE = 0,
+ IDE_BUFFER_OPEN_FLAGS_FORCE_RELOAD = 1 << 1,
+ IDE_BUFFER_OPEN_FLAGS_DISABLE_ADDINS = 1 << 2,
} IdeBufferOpenFlags;
/**
@@ -58,24 +54,22 @@ typedef enum
* @user_data: closure data
*
* Callback prototype for ide_buffer_manager_foreach().
- *
- * Since: 3.32
*/
typedef void (*IdeBufferForeachFunc) (IdeBuffer *buffer,
gpointer user_data);
#define IDE_TYPE_BUFFER_MANAGER (ide_buffer_manager_get_type())
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (IdeBufferManager, ide_buffer_manager, IDE, BUFFER_MANAGER, IdeObject)
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBufferManager *ide_buffer_manager_from_context (IdeContext *context);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_manager_foreach (IdeBufferManager *self,
IdeBufferForeachFunc foreach_func,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_manager_load_file_async (IdeBufferManager *self,
GFile *file,
IdeBufferOpenFlags flags,
@@ -83,46 +77,46 @@ void ide_buffer_manager_load_file_async (IdeBufferManager *
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBuffer *ide_buffer_manager_load_file_finish (IdeBufferManager *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_manager_save_all_async (IdeBufferManager *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_manager_save_all_finish (IdeBufferManager *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_3_36
+IDE_AVAILABLE_IN_ALL
void ide_buffer_manager_reload_all_async (IdeBufferManager *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_36
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_manager_reload_all_finish (IdeBufferManager *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_manager_has_file (IdeBufferManager *self,
GFile *file);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBuffer *ide_buffer_manager_find_buffer (IdeBufferManager *self,
GFile *file);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gssize ide_buffer_manager_get_max_file_size (IdeBufferManager *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_manager_set_max_file_size (IdeBufferManager *self,
gssize max_file_size);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_manager_apply_edits_async (IdeBufferManager *self,
GPtrArray *edits,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_manager_apply_edits_finish (IdeBufferManager *self,
GAsyncResult *result,
GError **error);
diff --git a/src/libide/code/ide-buffer.c b/src/libide/code/ide-buffer.c
index 44a2c8c4c..899290472 100644
--- a/src/libide/code/ide-buffer.c
+++ b/src/libide/code/ide-buffer.c
@@ -22,7 +22,6 @@
#include "config.h"
-#include <dazzle.h>
#include <glib/gi18n.h>
#include <libide-io.h>
#include <libide-plugins.h>
@@ -51,14 +50,14 @@
#define SETTLING_DELAY_MSEC 333
-#define TAG_ERROR "diagnostician::error"
-#define TAG_WARNING "diagnostician::warning"
-#define TAG_DEPRECATED "diagnostician::deprecated"
-#define TAG_UNUSED "diagnostician::unused"
-#define TAG_NOTE "diagnostician::note"
-#define TAG_SNIPPET_TAB_STOP "snippet::tab-stop"
-#define TAG_DEFINITION "action::hover-definition"
-#define TAG_CURRENT_BKPT "debugger::current-breakpoint"
+#define TAG_ERROR "-Builder:error"
+#define TAG_WARNING "-Builder:warning"
+#define TAG_DEPRECATED "-Builder:deprecated"
+#define TAG_UNUSED "-Builder:unused"
+#define TAG_NOTE "-Builder:note"
+#define TAG_SNIPPET_TAB_STOP "-Builder:tab-stop"
+#define TAG_DEFINITION "-Builder:hover-definition"
+#define TAG_CURRENT_BKPT "-Builder:current-breakpoint"
#define DEPRECATED_COLOR "#babdb6"
#define UNUSED_COLOR "#c17d11"
@@ -72,6 +71,8 @@ struct _IdeBuffer
{
GtkSourceBuffer parent_instance;
+ const GtkSourceEncoding *encoding;
+
/* Owned references */
IdeExtensionSetAdapter *addins;
IdeExtensionSetAdapter *symbol_resolvers;
@@ -89,12 +90,15 @@ struct _IdeBuffer
GFile *readlink_file;
IdeTask *in_flight_symbol_at_location;
- gint in_flight_symbol_at_location_pos;
+ int in_flight_symbol_at_location_pos;
- /* Scalars */
guint change_count;
guint settling_source;
- gint hold;
+ int hold;
+ guint release_in_idle;
+
+ GArray *commit_funcs;
+ guint next_commit_handler;
/* Bit-fields */
IdeBufferState state : 3;
@@ -104,8 +108,20 @@ struct _IdeBuffer
guint changed_on_volume : 1;
guint read_only : 1;
guint highlight_diagnostics : 1;
+ GtkSourceNewlineType newline_type : 2;
};
+typedef struct
+{
+ IdeBufferCommitFunc before_insert_text;
+ IdeBufferCommitFunc after_insert_text;
+ IdeBufferCommitFunc before_delete_range;
+ IdeBufferCommitFunc after_delete_range;
+ gpointer user_data;
+ GDestroyNotify user_data_destroy;
+ guint handler_id;
+} CommitHooks;
+
typedef struct
{
IdeNotification *notif;
@@ -134,6 +150,7 @@ enum {
PROP_BUFFER_MANAGER,
PROP_CHANGE_MONITOR,
PROP_CHANGED_ON_VOLUME,
+ PROP_CHARSET,
PROP_ENABLE_ADDINS,
PROP_DIAGNOSTICS,
PROP_FAILED,
@@ -144,6 +161,7 @@ enum {
PROP_HIGHLIGHT_DIAGNOSTICS,
PROP_IS_TEMPORARY,
PROP_LANGUAGE_ID,
+ PROP_NEWLINE_TYPE,
PROP_READ_ONLY,
PROP_STATE,
PROP_STYLE_SCHEME_NAME,
@@ -197,7 +215,6 @@ static void ide_buffer_notify_style_scheme (IdeBuffer *self
static void ide_buffer_reload_file_settings (IdeBuffer *self);
static void ide_buffer_set_file_settings (IdeBuffer *self,
IdeFileSettings *file_settings);
-static void ide_buffer_emit_cursor_moved (IdeBuffer *self);
static void ide_buffer_changed (GtkTextBuffer *buffer);
static void ide_buffer_delete_range (GtkTextBuffer *buffer,
GtkTextIter *start,
@@ -206,9 +223,6 @@ static void ide_buffer_insert_text (GtkTextBuffer *buff
GtkTextIter *location,
const gchar *text,
gint len);
-static void ide_buffer_mark_set (GtkTextBuffer *buffer,
- const GtkTextIter *iter,
- GtkTextMark *mark);
static void ide_buffer_delay_settling (IdeBuffer *self);
static gboolean ide_buffer_settled_cb (gpointer user_data);
static void ide_buffer_apply_diagnostics (IdeBuffer *self);
@@ -277,6 +291,15 @@ lookup_symbol_data_free (LookUpSymbolData *data)
g_slice_free (LookUpSymbolData, data);
}
+static void
+clear_commit_func (gpointer data)
+{
+ CommitHooks *hooks = data;
+
+ if (hooks->user_data_destroy)
+ hooks->user_data_destroy (hooks->user_data);
+}
+
IdeBuffer *
_ide_buffer_new (IdeBufferManager *buffer_manager,
GFile *file,
@@ -293,6 +316,7 @@ _ide_buffer_new (IdeBufferManager *buffer_manager,
"enable-addins", enable_addins,
"is-temporary", is_temporary,
"implicit-trailing-newline", FALSE,
+ "style-scheme-name", "Adwaita",
NULL);
}
@@ -467,6 +491,8 @@ ide_buffer_notify_language (IdeBuffer *self,
if (self->code_action_provider)
ide_extension_adapter_set_value (self->code_action_provider, lang_id);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_LANGUAGE_ID]);
}
static void
@@ -491,24 +517,30 @@ ide_buffer_dispose (GObject *object)
g_assert (IDE_IS_MAIN_THREAD ());
g_clear_handle_id (&self->settling_source, g_source_remove);
-
- /* Remove ourselves from the object-tree if necessary */
- if ((box = ide_object_box_from_object (object)) &&
- !ide_object_in_destruction (IDE_OBJECT (box)))
- ide_object_destroy (IDE_OBJECT (box));
+ g_clear_handle_id (&self->release_in_idle, g_source_remove);
ide_clear_and_destroy_object (&self->addins);
+
ide_clear_and_destroy_object (&self->rename_provider);
ide_clear_and_destroy_object (&self->symbol_resolvers);
ide_clear_and_destroy_object (&self->formatter);
ide_clear_and_destroy_object (&self->code_action_provider);
ide_clear_and_destroy_object (&self->highlight_engine);
- g_clear_object (&self->buffer_manager);
ide_clear_and_destroy_object (&self->change_monitor);
- g_clear_pointer (&self->content, g_bytes_unref);
- g_clear_object (&self->diagnostics);
ide_clear_and_destroy_object (&self->file_settings);
+ g_clear_pointer (&self->commit_funcs, g_array_unref);
+
+ g_clear_object (&self->diagnostics);
+ g_clear_object (&self->buffer_manager);
+
+ /* Remove ourselves from the object-tree if necessary */
+ if ((box = ide_object_box_from_object (object)) &&
+ !ide_object_in_destruction (IDE_OBJECT (box)))
+ ide_object_destroy (IDE_OBJECT (box));
+
+ g_clear_pointer (&self->content, g_bytes_unref);
+
G_OBJECT_CLASS (ide_buffer_parent_class)->dispose (object);
}
@@ -542,6 +574,10 @@ ide_buffer_get_property (GObject *object,
g_value_set_boolean (value, ide_buffer_get_changed_on_volume (self));
break;
+ case PROP_CHARSET:
+ g_value_set_string (value, ide_buffer_get_charset (self));
+ break;
+
case PROP_ENABLE_ADDINS:
g_value_set_boolean (value, self->enable_addins);
break;
@@ -578,6 +614,10 @@ ide_buffer_get_property (GObject *object,
g_value_set_string (value, ide_buffer_get_language_id (self));
break;
+ case PROP_NEWLINE_TYPE:
+ g_value_set_enum (value, ide_buffer_get_newline_type (self));
+ break;
+
case PROP_IS_TEMPORARY:
g_value_set_boolean (value, ide_buffer_get_is_temporary (self));
break;
@@ -621,6 +661,10 @@ ide_buffer_set_property (GObject *object,
ide_buffer_set_change_monitor (self, g_value_get_object (value));
break;
+ case PROP_CHARSET:
+ ide_buffer_set_charset (self, g_value_get_string (value));
+ break;
+
case PROP_ENABLE_ADDINS:
self->enable_addins = g_value_get_boolean (value);
break;
@@ -641,6 +685,10 @@ ide_buffer_set_property (GObject *object,
ide_buffer_set_language_id (self, g_value_get_string (value));
break;
+ case PROP_NEWLINE_TYPE:
+ ide_buffer_set_newline_type (self, g_value_get_enum (value));
+ break;
+
case PROP_IS_TEMPORARY:
self->is_temporary = g_value_get_boolean (value);
break;
@@ -669,15 +717,12 @@ ide_buffer_class_init (IdeBufferClass *klass)
buffer_class->changed = ide_buffer_changed;
buffer_class->delete_range = ide_buffer_delete_range;
buffer_class->insert_text = ide_buffer_insert_text;
- buffer_class->mark_set = ide_buffer_mark_set;
/**
* IdeBuffer:buffer-manager:
*
* Sets the "buffer-manager" property, which is used by the buffer to
* clean-up state when the buffer is no longer in use.
- *
- * Since: 3.32
*/
properties [PROP_BUFFER_MANAGER] =
g_param_spec_object ("buffer-manager",
@@ -692,8 +737,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* The "change-monitor" property is an #IdeBufferChangeMonitor that will be
* used to track changes in the #IdeBuffer. This can be used to show line
* changes in the editor gutter.
- *
- * Since: 3.32
*/
properties [PROP_CHANGE_MONITOR] =
g_param_spec_object ("change-monitor",
@@ -702,14 +745,26 @@ ide_buffer_class_init (IdeBufferClass *klass)
IDE_TYPE_BUFFER_CHANGE_MONITOR,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+ /**
+ * IdeBuffer:charset:
+ *
+ * Sets the encoding to use for the buffer based on the "charset"
+ * specified. This is useful to ensure that characters may not be
+ * lost from the original encoding.
+ */
+ properties [PROP_CHARSET] =
+ g_param_spec_string ("charset",
+ "Character Set",
+ "The encoding character set",
+ "UTF-8",
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
/**
* IdeBuffer:changed-on-volume:
*
* The "changed-on-volume" property is set to %TRUE when it has been
* discovered that the file represented by the #IdeBuffer has changed
* externally to Builder.
- *
- * Since: 3.32
*/
properties [PROP_CHANGED_ON_VOLUME] =
g_param_spec_boolean ("changed-on-volume",
@@ -724,8 +779,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* The "enable-addins" property determines whether addins will be aware of
* this buffer. When set to %FALSE no ide_buffer_addin_*() functions will be
* called on this buffer.
- *
- * Since: 41.0
*/
properties [PROP_ENABLE_ADDINS] =
g_param_spec_boolean ("enable-addins",
@@ -739,8 +792,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* The "diagnostics" property contains an #IdeDiagnostics that represent
* the diagnostics found in the buffer.
- *
- * Since: 3.32
*/
properties [PROP_DIAGNOSTICS] =
g_param_spec_object ("diagnostics",
@@ -754,8 +805,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* The "failed" property is %TRUE when the buffer has entered a failed
* state such as when loading or saving the buffer to disk.
- *
- * Since: 3.32
*/
properties [PROP_FAILED] =
g_param_spec_boolean ("failed",
@@ -768,8 +817,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* IdeBuffer:file:
*
* The "file" property is the underlying file represented by the buffer.
- *
- * Since: 3.32
*/
properties [PROP_FILE] =
g_param_spec_object ("file",
@@ -786,8 +833,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* These are automatically discovered and kept up to date based on the
* #IdeFileSettings extension points.
- *
- * Since: 3.32
*/
properties [PROP_FILE_SETTINGS] =
g_param_spec_object ("file-settings",
@@ -801,8 +846,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* The "has-diagnostics" property denotes that there are a non-zero number
* of diangostics registered for the buffer.
- *
- * Since: 3.32
*/
properties [PROP_HAS_DIAGNOSTICS] =
g_param_spec_boolean ("has-diagnostics",
@@ -816,8 +859,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* The "has-symbol-resolvers" property is %TRUE if there are any symbol
* resolvers loaded.
- *
- * Since: 3.32
*/
properties [PROP_HAS_SYMBOL_RESOLVERS] =
g_param_spec_boolean ("has-symbol-resolvers",
@@ -831,8 +872,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* The "highlight-diagnostics" property indicates that diagnostics which
* are discovered should be styled.
- *
- * Since: 3.32
*/
properties [PROP_HIGHLIGHT_DIAGNOSTICS] =
g_param_spec_boolean ("highlight-diagnostics",
@@ -850,8 +889,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* to select the destination file.
*
* Upon saving the file, the property will change to %FALSE.
- *
- * Since: 3.32
*/
properties [PROP_IS_TEMPORARY] =
g_param_spec_boolean ("is-temporary",
@@ -865,8 +902,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* The "language-id" property is a convenience property to set the
* #GtkSourceBuffer:langauge property using a string name.
- *
- * Since: 3.32
*/
properties [PROP_LANGUAGE_ID] =
g_param_spec_string ("language-id",
@@ -875,14 +910,34 @@ ide_buffer_class_init (IdeBufferClass *klass)
NULL,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+ /**
+ * IdeBuffer:newline-type:
+ *
+ * Sets the style of newline to append to each line.
+ *
+ * This sets the style of newlines to use within the file. Generally,
+ * only LF should be used (\n) as it is common on Unix, Linux, and most
+ * editors at this point.
+ *
+ * Older Windows editors might prefer CR+LF (\r\n) which is similar to what
+ * is displayed in a raw terminal without a \n line discipline.
+ *
+ * Really old Mac Classic systems use just a \r.
+ */
+ properties [PROP_NEWLINE_TYPE] =
+ g_param_spec_enum ("newline-type",
+ "Newline Type",
+ "The style of newlines to append at the end of each line",
+ GTK_SOURCE_TYPE_NEWLINE_TYPE,
+ GTK_SOURCE_NEWLINE_TYPE_LF,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
/**
* IdeBuffer:read-only:
*
* The "read-only" property is set to %TRUE when it has been
* discovered that the file represented by the #IdeBuffer is read-only
* on the underlying storage.
- *
- * Since: 3.32
*/
properties [PROP_READ_ONLY] =
g_param_spec_boolean ("read-only",
@@ -897,8 +952,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* The "state" property can be used to determine if the buffer is
* currently performing any specific background work, such as loading
* from or saving a buffer to storage.
- *
- * Since: 3.32
*/
properties [PROP_STATE] =
g_param_spec_enum ("state",
@@ -914,8 +967,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* The "style-scheme-name" is the name of the style scheme that is used.
* It is a convenience property so that you do not need to use the
* #GtkSourceStyleSchemeManager to lookup style schemes.
- *
- * Since: 3.32
*/
properties [PROP_STYLE_SCHEME_NAME] =
g_param_spec_string ("style-scheme-name",
@@ -929,8 +980,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* The "title" for the buffer which includes some variant of the path
* to the underlying file.
- *
- * Since: 3.32
*/
properties [PROP_TITLE] =
g_param_spec_string ("title",
@@ -949,8 +998,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* being edited for a short period of time. This is useful to connect
* to when you want to perform work as the user is editing, but you
* don't want to get in the way of their editing.
- *
- * Since: 3.32
*/
signals [CHANGE_SETTLED] =
g_signal_new ("change-settled",
@@ -964,32 +1011,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
G_TYPE_FROM_CLASS (klass),
g_cclosure_marshal_VOID__VOIDv);
- /**
- * IdeBuffer::cursor-moved:
- * @self: an #IdeBuffer
- * @location: a #GtkTextIter
- *
- * This signal is emitted when the insertion location has moved. You might
- * want to attach to this signal to update the location of the insert mark in
- * the display.
- *
- * Since: 3.32
- */
- signals [CURSOR_MOVED] =
- g_signal_new ("cursor-moved",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE,
- 1,
- GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
- g_signal_set_va_marshaller (signals [CURSOR_MOVED],
- G_TYPE_FROM_CLASS (klass),
- g_cclosure_marshal_VOID__BOXEDv);
-
/**
* IdeBuffer::line-flags-changed:
* @self: an #IdeBuffer
@@ -997,8 +1018,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* The "line-flags-changed" signal is emitted when the buffer has detected
* ancillary information has changed for lines in the buffer. Such information
* might include diagnostics or version control information.
- *
- * Since: 3.32
*/
signals [LINE_FLAGS_CHANGED] =
g_signal_new_class_handler ("line-flags-changed",
@@ -1020,8 +1039,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
*
* This is useful to watch if you want to perform a given action but do
* not want to interfere with buffer loading.
- *
- * Since: 3.32
*/
signals [LOADED] =
g_signal_new_class_handler ("loaded",
@@ -1041,8 +1058,6 @@ ide_buffer_class_init (IdeBufferClass *klass)
* Requests that attached views scroll to insert location.
*
* This is generally only used when loading a buffer.
- *
- * Since: 3.32
*/
signals [REQUEST_SCROLL_TO_INSERT] =
g_signal_new_class_handler ("request-scroll-to-insert",
@@ -1060,13 +1075,17 @@ ide_buffer_class_init (IdeBufferClass *klass)
static void
ide_buffer_init (IdeBuffer *self)
{
+ g_assert (IDE_IS_MAIN_THREAD ());
+
self->in_flight_symbol_at_location_pos = -1;
self->source_file = gtk_source_file_new ();
self->can_restore_cursor = TRUE;
self->highlight_diagnostics = TRUE;
self->enable_addins = TRUE;
+ self->newline_type = GTK_SOURCE_NEWLINE_TYPE_LF;
- g_assert (IDE_IS_MAIN_THREAD ());
+ self->commit_funcs = g_array_new (FALSE, FALSE, sizeof (CommitHooks));
+ g_array_set_clear_func (self->commit_funcs, clear_commit_func);
g_signal_connect (self,
"notify::language",
@@ -1183,6 +1202,8 @@ void
_ide_buffer_attach (IdeBuffer *self,
IdeObject *parent)
{
+ const char *language_id;
+
g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_OBJECT_BOX (parent));
g_return_if_fail (ide_object_box_contains (IDE_OBJECT_BOX (parent), self));
@@ -1192,6 +1213,10 @@ _ide_buffer_attach (IdeBuffer *self,
g_return_if_fail (self->formatter == NULL);
g_return_if_fail (self->rename_provider == NULL);
+ /* We use "--disabled--" just like sourceview does */
+ if (!(language_id = ide_buffer_get_language_id (self)))
+ language_id = "--disabled--";
+
/* Setup the semantic highlight engine */
self->highlight_engine = ide_highlight_engine_new (self);
@@ -1200,7 +1225,7 @@ _ide_buffer_attach (IdeBuffer *self,
peas_engine_get_default (),
IDE_TYPE_BUFFER_ADDIN,
"Buffer-Addin-Languages",
- ide_buffer_get_language_id (self));
+ language_id);
g_signal_connect (self->addins,
"extension-added",
G_CALLBACK (_ide_buffer_addin_load_cb),
@@ -1218,7 +1243,7 @@ _ide_buffer_attach (IdeBuffer *self,
peas_engine_get_default (),
IDE_TYPE_RENAME_PROVIDER,
"Rename-Provider-Languages",
- ide_buffer_get_language_id (self));
+ language_id);
g_signal_connect_object (self->rename_provider,
"notify::extension",
G_CALLBACK (ide_buffer_rename_provider_notify_extension),
@@ -1231,7 +1256,7 @@ _ide_buffer_attach (IdeBuffer *self,
peas_engine_get_default (),
IDE_TYPE_FORMATTER,
"Formatter-Languages",
- ide_buffer_get_language_id (self));
+ language_id);
g_signal_connect_object (self->formatter,
"notify::extension",
G_CALLBACK (ide_buffer_formatter_notify_extension),
@@ -1244,7 +1269,7 @@ _ide_buffer_attach (IdeBuffer *self,
peas_engine_get_default (),
IDE_TYPE_CODE_ACTION_PROVIDER,
"Code-Action-Languages",
- ide_buffer_get_language_id (self));
+ language_id);
g_signal_connect_object (self->code_action_provider,
"notify::extension",
@@ -1258,7 +1283,7 @@ _ide_buffer_attach (IdeBuffer *self,
peas_engine_get_default (),
IDE_TYPE_SYMBOL_RESOLVER,
"Symbol-Resolver-Languages",
- ide_buffer_get_language_id (self));
+ language_id);
g_signal_connect_object (self->symbol_resolvers,
"extension-added",
G_CALLBACK (ide_buffer_symbol_resolver_added),
@@ -1281,8 +1306,6 @@ _ide_buffer_attach (IdeBuffer *self,
* Gets the #IdeBuffer:file property.
*
* Returns: (transfer none): a #GFile
- *
- * Since: 3.32
*/
GFile *
ide_buffer_get_file (IdeBuffer *self)
@@ -1306,8 +1329,6 @@ ide_buffer_get_file (IdeBuffer *self)
* Gets the URI for the underlying file and returns a copy of it.
*
* Returns: (transfer full): a new string
- *
- * Since: 3.32
*/
gchar *
ide_buffer_dup_uri (IdeBuffer *self)
@@ -1326,8 +1347,6 @@ ide_buffer_dup_uri (IdeBuffer *self)
* when the user requests to save the buffer.
*
* Returns: %TRUE if the buffer is for a temporary file
- *
- * Since: 3.32
*/
gboolean
ide_buffer_get_is_temporary (IdeBuffer *self)
@@ -1347,8 +1366,6 @@ ide_buffer_get_is_temporary (IdeBuffer *self)
* This will changed while files are loaded or saved to disk.
*
* Returns: an #IdeBufferState
- *
- * Since: 3.32
*/
IdeBufferState
ide_buffer_get_state (IdeBuffer *self)
@@ -1510,8 +1527,6 @@ _ide_buffer_load_file_async (IdeBuffer *self,
* that the completion of signals and addins may be notified.
*
* Returns: %TRUE if the file was successfully loaded
- *
- * Since: 3.32
*/
gboolean
_ide_buffer_load_file_finish (IdeBuffer *self,
@@ -1645,12 +1660,21 @@ ide_buffer_save_file_settle_cb (GObject *object,
}
saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (self), state->source_file);
+
/* At this point, we've notified the user of changes to the underlying file using
* the infobar, so just save the file knowing that we are overwriting things.
*/
gtk_source_file_saver_set_flags (saver,
(GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS |
GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME));
+
+ /* Propagate the requested encoding, if necessary */
+ if (self->encoding != NULL)
+ gtk_source_file_saver_set_encoding (saver, self->encoding);
+
+ /* Same for newlines */
+ gtk_source_file_saver_set_newline_type (saver, self->newline_type);
+
gtk_source_file_saver_save_async (saver,
G_PRIORITY_DEFAULT,
ide_task_get_cancellable (task),
@@ -1667,6 +1691,7 @@ ide_buffer_save_file_settle_cb (GObject *object,
* @self: an #IdeBuffer
* @file: (nullable): a #GFile or %NULL
* @cancellable: (nullable): a #GCancellable
+ * @notif: (out) (optional) (transfer full): a location for an #IdeNotification or %NULL
* @callback: a #GAsyncReadyCallback to execute upon completion
* @user_data: closure data for @callback
*
@@ -1679,8 +1704,6 @@ ide_buffer_save_file_settle_cb (GObject *object,
*
* @callback is executed upon completion and should call
* ide_buffer_save_file_finish() to get the result of the operation.
- *
- * Since: 3.32
*/
void
ide_buffer_save_file_async (IdeBuffer *self,
@@ -1805,8 +1828,6 @@ set_out_param:
* ide_buffer_save_file_async().
*
* Returns: %TRUE if successful; otherwise %FALSE and @error is set.
- *
- * Since: 3.32
*/
gboolean
ide_buffer_save_file_finish (IdeBuffer *self,
@@ -1827,8 +1848,6 @@ ide_buffer_save_file_finish (IdeBuffer *self,
* A helper to get the language identifier of the buffers current language.
*
* Returns: (nullable): a string containing the language id, or %NULL
- *
- * Since: 3.32
*/
const gchar *
ide_buffer_get_language_id (IdeBuffer *self)
@@ -1897,8 +1916,6 @@ _ide_buffer_set_failure (IdeBuffer *self,
* buffer.
*
* Returns: (transfer none): a #GError, or %NULL
- *
- * Since: 3.32
*/
const GError *
ide_buffer_get_failure (IdeBuffer *self)
@@ -1917,8 +1934,6 @@ ide_buffer_get_failure (IdeBuffer *self)
* in some aspect such as loading or saving.
*
* Returns: %TRUE if the buffer is in a failed state
- *
- * Since: 3.32
*/
gboolean
ide_buffer_get_failed (IdeBuffer *self)
@@ -1978,23 +1993,6 @@ ide_buffer_reload_file_settings (IdeBuffer *self)
}
}
-static void
-ide_buffer_emit_cursor_moved (IdeBuffer *self)
-{
- g_assert (IDE_IS_MAIN_THREAD ());
- g_assert (IDE_IS_BUFFER (self));
-
- if (!ide_buffer_get_loading (self))
- {
- GtkTextMark *mark;
- GtkTextIter iter;
-
- mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (self));
- gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self), &iter, mark);
- g_signal_emit (self, signals [CURSOR_MOVED], 0, &iter);
- }
-}
-
/**
* ide_buffer_get_loading:
* @self: an #IdeBuffer
@@ -2003,8 +2001,6 @@ ide_buffer_emit_cursor_moved (IdeBuffer *self)
* to calling ide_buffer_get_state() and checking for %IDE_BUFFER_STATE_LOADING.
*
* Returns: %TRUE if the buffer is loading; otherwise %FALSE.
- *
- * Since: 3.32
*/
gboolean
ide_buffer_get_loading (IdeBuffer *self)
@@ -2037,10 +2033,14 @@ ide_buffer_delete_range (GtkTextBuffer *buffer,
GtkTextIter *begin,
GtkTextIter *end)
{
+ IdeBuffer *self = (IdeBuffer *)buffer;
+ guint position;
+ guint length;
+
IDE_ENTRY;
g_assert (IDE_IS_MAIN_THREAD ());
- g_assert (IDE_IS_BUFFER (buffer));
+ g_assert (IDE_IS_BUFFER (self));
g_assert (begin != NULL);
g_assert (end != NULL);
@@ -2060,9 +2060,26 @@ ide_buffer_delete_range (GtkTextBuffer *buffer,
}
#endif
+ position = gtk_text_iter_get_offset (begin);
+ length = gtk_text_iter_get_offset (end) - position;
+
+ for (guint i = 0; i < self->commit_funcs->len; i++)
+ {
+ const CommitHooks *hooks = &g_array_index (self->commit_funcs, CommitHooks, i);
+
+ if (hooks->before_delete_range != NULL)
+ hooks->before_delete_range (self, position, length, hooks->user_data);
+ }
+
GTK_TEXT_BUFFER_CLASS (ide_buffer_parent_class)->delete_range (buffer, begin, end);
- ide_buffer_emit_cursor_moved (IDE_BUFFER (buffer));
+ for (guint i = 0; i < self->commit_funcs->len; i++)
+ {
+ const CommitHooks *hooks = &g_array_index (self->commit_funcs, CommitHooks, i);
+
+ if (hooks->after_delete_range != NULL)
+ hooks->after_delete_range (self, position, length, hooks->user_data);
+ }
IDE_EXIT;
}
@@ -2073,12 +2090,15 @@ ide_buffer_insert_text (GtkTextBuffer *buffer,
const gchar *text,
gint len)
{
+ IdeBuffer *self = (IdeBuffer *)buffer;
gboolean recheck_language = FALSE;
+ guint position;
+ guint length;
IDE_ENTRY;
g_assert (IDE_IS_MAIN_THREAD ());
- g_assert (IDE_IS_BUFFER (buffer));
+ g_assert (IDE_IS_BUFFER (self));
g_assert (location != NULL);
g_assert (text != NULL);
@@ -2092,33 +2112,31 @@ ide_buffer_insert_text (GtkTextBuffer *buffer,
((text [0] == '\n') || ((len > 1) && (strchr (text, '\n') != NULL))))
recheck_language = TRUE;
- GTK_TEXT_BUFFER_CLASS (ide_buffer_parent_class)->insert_text (buffer, location, text, len);
+ position = gtk_text_iter_get_offset (location);
+ length = g_utf8_strlen (text, len);
- ide_buffer_emit_cursor_moved (IDE_BUFFER (buffer));
+ for (guint i = 0; i < self->commit_funcs->len; i++)
+ {
+ const CommitHooks *hooks = &g_array_index (self->commit_funcs, CommitHooks, i);
- if G_UNLIKELY (recheck_language)
- ide_buffer_guess_language (IDE_BUFFER (buffer));
+ if (hooks->before_insert_text != NULL)
+ hooks->before_insert_text (self, position, length, hooks->user_data);
+ }
- IDE_EXIT;
-}
+ GTK_TEXT_BUFFER_CLASS (ide_buffer_parent_class)->insert_text (buffer, location, text, len);
-static void
-ide_buffer_mark_set (GtkTextBuffer *buffer,
- const GtkTextIter *iter,
- GtkTextMark *mark)
-{
- IdeBuffer *self = (IdeBuffer *)buffer;
+ for (guint i = 0; i < self->commit_funcs->len; i++)
+ {
+ const CommitHooks *hooks = &g_array_index (self->commit_funcs, CommitHooks, i);
- g_assert (IDE_IS_MAIN_THREAD ());
- g_assert (IDE_IS_BUFFER (self));
+ if (hooks->after_insert_text != NULL)
+ hooks->after_insert_text (self, position, length, hooks->user_data);
+ }
- GTK_TEXT_BUFFER_CLASS (ide_buffer_parent_class)->mark_set (buffer, iter, mark);
+ if G_UNLIKELY (recheck_language)
+ ide_buffer_guess_language (IDE_BUFFER (buffer));
- if (!ide_buffer_get_loading (self))
- {
- if (mark == gtk_text_buffer_get_insert (buffer))
- ide_buffer_emit_cursor_moved (IDE_BUFFER (buffer));
- }
+ IDE_EXIT;
}
/**
@@ -2129,8 +2147,6 @@ ide_buffer_mark_set (GtkTextBuffer *buffer,
* externally from this #IdeBuffer.
*
* Returns: %TRUE if @self is known to be modified on storage
- *
- * Since: 3.32
*/
gboolean
ide_buffer_get_changed_on_volume (IdeBuffer *self)
@@ -2150,8 +2166,6 @@ ide_buffer_get_changed_on_volume (IdeBuffer *self)
*
* Set this to %TRUE if the buffer has been discovered to have changed
* outside of this buffer.
- *
- * Since: 3.32
*/
void
_ide_buffer_set_changed_on_volume (IdeBuffer *self,
@@ -2179,8 +2193,6 @@ _ide_buffer_set_changed_on_volume (IdeBuffer *self,
* the user about saving the file.
*
* Returns: %TRUE if the underlying file is read-only
- *
- * Since: 3.32
*/
gboolean
ide_buffer_get_read_only (IdeBuffer *self)
@@ -2198,8 +2210,6 @@ ide_buffer_get_read_only (IdeBuffer *self)
*
* Sets the #IdeBuffer:read-only property, which should be set when the buffer
* has been discovered to be read-only on disk.
- *
- * Since: 3.32
*/
void
_ide_buffer_set_read_only (IdeBuffer *self,
@@ -2225,8 +2235,6 @@ _ide_buffer_set_read_only (IdeBuffer *self,
* property.
*
* Returns: (nullable): a string containing the style scheme or %NULL
- *
- * Since: 3.32
*/
const gchar *
ide_buffer_get_style_scheme_name (IdeBuffer *self)
@@ -2249,8 +2257,6 @@ ide_buffer_get_style_scheme_name (IdeBuffer *self)
*
* Sets the #IdeBuffer:style-scheme property by locating the style scheme
* matching @style_scheme_name.
- *
- * Since: 3.32
*/
void
ide_buffer_set_style_scheme_name (IdeBuffer *self,
@@ -2277,8 +2283,6 @@ ide_buffer_set_style_scheme_name (IdeBuffer *self,
* make this relative to the project workdir if possible.
*
* Returns: (transfer full): a string containing a title
- *
- * Since: 3.32
*/
gchar *
ide_buffer_dup_title (IdeBuffer *self)
@@ -2326,8 +2330,6 @@ ide_buffer_dup_title (IdeBuffer *self)
* Checks if diagnostics should be highlighted.
*
* Returns: %TRUE if diagnostics should be highlighted
- *
- * Since: 3.32
*/
gboolean
ide_buffer_get_highlight_diagnostics (IdeBuffer *self)
@@ -2345,8 +2347,6 @@ ide_buffer_get_highlight_diagnostics (IdeBuffer *self)
* Sets the #IdeBuffer:highlight-diagnostics property.
*
* If set to %TRUE, diagnostics will be styled in the buffer.
- *
- * Since: 3.32
*/
void
ide_buffer_set_highlight_diagnostics (IdeBuffer *self,
@@ -2374,8 +2374,6 @@ ide_buffer_set_highlight_diagnostics (IdeBuffer *self,
* Gets an #IdeLocation for the position represented by @iter.
*
* Returns: (transfer full): an #IdeLocation
- *
- * Since: 3.32
*/
IdeLocation *
ide_buffer_get_iter_location (IdeBuffer *self,
@@ -2397,8 +2395,6 @@ ide_buffer_get_iter_location (IdeBuffer *self,
* Gets an #IdeRange to represent the current buffer selection.
*
* Returns: (transfer full): an #IdeRange
- *
- * Since: 3.32
*/
IdeRange *
ide_buffer_get_selection_range (IdeBuffer *self)
@@ -2426,8 +2422,6 @@ ide_buffer_get_selection_range (IdeBuffer *self)
* Gets the monotonic change count for the buffer.
*
* Returns: the change count for the buffer
- *
- * Since: 3.32
*/
guint
ide_buffer_get_change_count (IdeBuffer *self)
@@ -2464,9 +2458,9 @@ ide_buffer_delay_settling (IdeBuffer *self)
g_assert (IDE_IS_BUFFER (self));
g_clear_handle_id (&self->settling_source, g_source_remove);
- self->settling_source = gdk_threads_add_timeout (SETTLING_DELAY_MSEC,
- ide_buffer_settled_cb,
- self);
+ self->settling_source = g_timeout_add (SETTLING_DELAY_MSEC,
+ ide_buffer_settled_cb,
+ self);
}
/**
@@ -2477,8 +2471,6 @@ ide_buffer_delay_settling (IdeBuffer *self)
* Sets the #IdeDiagnostics for the buffer. These will be used to highlight
* the buffer for errors and warnings if #IdeBuffer:highlight-diagnostics
* is %TRUE.
- *
- * Since: 3.32
*/
void
ide_buffer_set_diagnostics (IdeBuffer *self,
@@ -2520,8 +2512,6 @@ ide_buffer_set_diagnostics (IdeBuffer *self,
* Gets the #IdeDiagnostics for the buffer if any have been registered.
*
* Returns: (transfer none) (nullable): an #IdeDiagnostics or %NULL
- *
- * Since: 3.32
*/
IdeDiagnostics *
ide_buffer_get_diagnostics (IdeBuffer *self)
@@ -2539,8 +2529,6 @@ ide_buffer_get_diagnostics (IdeBuffer *self)
* Returns %TRUE if any diagnostics have been registered for the buffer.
*
* Returns: %TRUE if there are a non-zero number of diagnostics.
- *
- * Since: 3.32
*/
gboolean
ide_buffer_has_diagnostics (IdeBuffer *self)
@@ -2573,19 +2561,19 @@ ide_buffer_clear_diagnostics (IdeBuffer *self)
table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (self));
if (NULL != (tag = gtk_text_tag_table_lookup (table, TAG_NOTE)))
- dzl_gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end, TRUE);
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end);
if (NULL != (tag = gtk_text_tag_table_lookup (table, TAG_WARNING)))
- dzl_gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end, TRUE);
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end);
if (NULL != (tag = gtk_text_tag_table_lookup (table, TAG_DEPRECATED)))
- dzl_gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end, TRUE);
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end);
if (NULL != (tag = gtk_text_tag_table_lookup (table, TAG_UNUSED)))
- dzl_gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end, TRUE);
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end);
if (NULL != (tag = gtk_text_tag_table_lookup (table, TAG_ERROR)))
- dzl_gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end, TRUE);
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (self), tag, &begin, &end);
}
static void
@@ -2727,8 +2715,6 @@ ide_buffer_apply_diagnostics (IdeBuffer *self)
* @location: a #IdeLocation
*
* Set @iter to the position designated by @location.
- *
- * Since: 3.32
*/
void
ide_buffer_get_iter_at_location (IdeBuffer *self,
@@ -2770,8 +2756,6 @@ ide_buffer_get_iter_at_location (IdeBuffer *self,
* Gets the #IdeBuffer:change-monitor for the buffer.
*
* Returns: (transfer none) (nullable): an #IdeBufferChangeMonitor or %NULL
- *
- * Since: 3.32
*/
IdeBufferChangeMonitor *
ide_buffer_get_change_monitor (IdeBuffer *self)
@@ -2787,8 +2771,6 @@ ide_buffer_get_change_monitor (IdeBuffer *self)
* @change_monitor: (nullable): an #IdeBufferChangeMonitor or %NULL
*
* Sets an #IdeBufferChangeMonitor to use for the buffer.
- *
- * Since: 3.32
*/
void
ide_buffer_set_change_monitor (IdeBuffer *self,
@@ -2859,8 +2841,6 @@ ide_buffer_can_do_newline_hack (IdeBuffer *self,
* if the content is out of sync.
*
* Returns: (transfer full): a #GBytes containing the buffer content.
- *
- * Since: 3.32
*/
GBytes *
ide_buffer_dup_content (IdeBuffer *self)
@@ -2889,8 +2869,7 @@ ide_buffer_dup_content (IdeBuffer *self)
* files will restore to a buffer, for which \n is acceptable.
*/
len = strlen (text);
- if (gtk_source_buffer_get_implicit_trailing_newline (GTK_SOURCE_BUFFER (self)) &&
- (len == 0 || text[len - 1] != '\n'))
+ if (gtk_source_buffer_get_implicit_trailing_newline (GTK_SOURCE_BUFFER (self)))
{
if (!ide_buffer_can_do_newline_hack (self, len))
{
@@ -2975,8 +2954,6 @@ ide_buffer_format_selection_range_cb (GObject *object,
* @user_data: user data for @callback
*
* Formats the selection using an available #IdeFormatter for the buffer.
- *
- * Since: 3.32
*/
void
ide_buffer_format_selection_async (IdeBuffer *self,
@@ -3050,8 +3027,6 @@ ide_buffer_format_selection_async (IdeBuffer *self,
* Completes an asynchronous request to ide_buffer_format_selection_async().
*
* Returns: %TRUE if successful; otherwise %FALSE and @error is set.
- *
- * Since: 3.32
*/
gboolean
ide_buffer_format_selection_finish (IdeBuffer *self,
@@ -3102,8 +3077,6 @@ ide_buffer_query_code_action_cb(GObject *object,
* @user_data: user data for @callback
*
* Queries for code actions in the current buffer.
- *
- * Since: 42.0
*/
void
ide_buffer_code_action_query_async(IdeBuffer *self,
@@ -3157,8 +3130,6 @@ ide_buffer_code_action_query_async(IdeBuffer *self,
* Completes an asynchronous request to ide_buffer_query_code_action_async().
*
* Returns: (transfer full) (element-type IdeCodeAction): a #GPtrArray of #IdeCodeAction.
- *
- * Since: 42.0
*/
GPtrArray*
ide_buffer_code_action_query_finish(IdeBuffer *self,
@@ -3184,8 +3155,6 @@ ide_buffer_code_action_query_finish(IdeBuffer *self,
* Gets the location of the insert mark as an #IdeLocation.
*
* Returns: (transfer full): An #IdeLocation
- *
- * Since: 3.32
*/
IdeLocation *
ide_buffer_get_insert_location (IdeBuffer *self)
@@ -3210,8 +3179,6 @@ ide_buffer_get_insert_location (IdeBuffer *self)
* Gets the word found under the position denoted by @iter.
*
* Returns: (transfer full): A newly allocated string.
- *
- * Since: 3.32
*/
gchar *
ide_buffer_get_word_at_iter (IdeBuffer *self,
@@ -3243,8 +3210,6 @@ ide_buffer_get_word_at_iter (IdeBuffer *self,
*
* Returns: (nullable) (transfer none): An #IdeRenameProvider or %NULL if
* there is no #IdeRenameProvider that can statisfy the buffer.
- *
- * Since: 3.32
*/
IdeRenameProvider *
ide_buffer_get_rename_provider (IdeBuffer *self)
@@ -3268,8 +3233,6 @@ ide_buffer_get_rename_provider (IdeBuffer *self)
* syntax are chnaged.
*
* Returns: (transfer none) (nullable): an #IdeFileSettings or %NULL
- *
- * Since: 3.32
*/
IdeFileSettings *
ide_buffer_get_file_settings (IdeBuffer *self)
@@ -3286,8 +3249,6 @@ ide_buffer_get_file_settings (IdeBuffer *self)
* Locates the #IdeContext for the buffer and returns it.
*
* Returns: (transfer full): an #IdeContext
- *
- * Since: 3.32
*/
IdeContext *
ide_buffer_ref_context (IdeBuffer *self)
@@ -3550,8 +3511,6 @@ ide_buffer_init_tags (IdeBuffer *self)
* Gets an #IdeFormatter for the buffer, if any.
*
* Returns: (transfer none) (nullable): an #IdeFormatter or %NULL
- *
- * Since: 3.32
*/
IdeFormatter *
ide_buffer_get_formatter (IdeBuffer *self)
@@ -3581,8 +3540,6 @@ _ide_buffer_sync_to_unsaved_files (IdeBuffer *self)
* @self: an #IdeBuffer
*
* Force @self to rebuild the highlighted words.
- *
- * Since: 3.32
*/
void
ide_buffer_rehighlight (IdeBuffer *self)
@@ -3683,8 +3640,6 @@ ide_buffer_get_symbol_at_location_cb (GObject *object,
* @user_data: a #gpointer to hold user data
*
* Asynchronously get a possible symbol at @location.
- *
- * Since: 3.32
*/
void
ide_buffer_get_symbol_at_location_async (IdeBuffer *self,
@@ -3765,8 +3720,6 @@ ide_buffer_get_symbol_at_location_async (IdeBuffer *self,
* Completes an asynchronous request to locate a symbol at a location.
*
* Returns: (transfer full): An #IdeSymbol or %NULL.
- *
- * Since: 3.32
*/
IdeSymbol *
ide_buffer_get_symbol_at_location_finish (IdeBuffer *self,
@@ -3792,8 +3745,6 @@ ide_buffer_get_symbol_at_location_finish (IdeBuffer *self,
*
* Calling gtk_text_iter_order() with the results of this function would be
* equivalent to calling gtk_text_buffer_get_selection_bounds().
- *
- * Since: 3.32
*/
void
ide_buffer_get_selection_bounds (IdeBuffer *self,
@@ -3845,8 +3796,6 @@ ide_buffer_get_symbol_resolvers_cb (IdeExtensionSetAdapter *set,
*
* Returns: (transfer full) (element-type IdeSymbolResolver): a #GPtrArray
* of #IdeSymbolResolver.
- *
- * Since: 3.32
*/
GPtrArray *
ide_buffer_get_symbol_resolvers (IdeBuffer *self)
@@ -3875,8 +3824,6 @@ ide_buffer_get_symbol_resolvers (IdeBuffer *self)
*
* Returns: (transfer full) (nullable): a string containing the line's text
* or %NULL if the line does not exist.
- *
- * Since: 3.32
*/
gchar *
ide_buffer_get_line_text (IdeBuffer *self,
@@ -3986,8 +3933,6 @@ _ide_buffer_cancel_cursor_restore (IdeBuffer *self)
* When the hold count reaches zero, the buffer will be destroyed.
*
* Returns: (transfer full): @self
- *
- * Since: 3.32
*/
IdeBuffer *
ide_buffer_hold (IdeBuffer *self)
@@ -3997,9 +3942,27 @@ ide_buffer_hold (IdeBuffer *self)
self->hold++;
+ g_clear_handle_id (&self->release_in_idle, g_source_remove);
+
return g_object_ref (self);
}
+static gboolean
+ide_buffer_release_in_idle (gpointer data)
+{
+ IdeBuffer *self = data;
+ IdeObjectBox *box;
+
+ g_assert (IDE_IS_BUFFER (self));
+
+ self->release_in_idle = 0;
+
+ if ((box = ide_object_box_from_object (G_OBJECT (self))))
+ ide_object_destroy (IDE_OBJECT (box));
+
+ return G_SOURCE_REMOVE;
+}
+
/**
* ide_buffer_release:
* @self: a #IdeBuffer
@@ -4008,8 +3971,6 @@ ide_buffer_hold (IdeBuffer *self)
*
* The buffer will be destroyed and unloaded when the hold count
* reaches zero.
- *
- * Since: 3.32
*/
void
ide_buffer_release (IdeBuffer *self)
@@ -4022,10 +3983,13 @@ ide_buffer_release (IdeBuffer *self)
if (self->hold == 0)
{
- IdeObjectBox *box = ide_object_box_from_object (G_OBJECT (self));
-
- if (box != NULL)
- ide_object_destroy (IDE_OBJECT (box));
+ g_assert (self->release_in_idle == 0);
+ self->release_in_idle =
+ g_idle_add_full (G_PRIORITY_DEFAULT,
+ ide_buffer_release_in_idle,
+ self,
+ g_object_unref);
+ return;
}
g_object_unref (self);
@@ -4056,8 +4020,6 @@ _ide_buffer_line_flags_changed (IdeBuffer *self)
* Checks if any symbol resolvers are available.
*
* Returns: %TRUE if at least one symbol resolvers is available
- *
- * Since: 3.32
*/
gboolean
ide_buffer_has_symbol_resolvers (IdeBuffer *self)
@@ -4190,3 +4152,139 @@ _ide_buffer_is_file (IdeBuffer *self,
return g_file_equal (nolink_file, ide_buffer_get_file (self)) ||
g_file_equal (nolink_file, self->readlink_file);
}
+
+/**
+ * ide_buffer_add_commit_funcs:
+ * @self: a #IdeBuffer
+ * @before_insert_text: (nullable) (scope async): function for before inserting text
+ * @after_insert_text: (nullable) (scope async): function for after inserting text
+ * @before_delete_range: (nullable) (scope async): function for before deleting a range
+ * @after_delete_range: (nullable) (scope async): function for after deleting a range
+ * @user_data: closure data
+ * @user_data_destroy: destroy notify for @user_data
+ *
+ * Adds function callbacks to handle important changes to text
+ * internally within the GtkTextBuffer. You can use these instead
+ * of signals like #GtkTextBuffer::insert-text or
+ * #GtkTextBuffer::delete-range when you want to be sure you're
+ * getting unprocessed changes right before they are commited to
+ * underlying GTK data structures.
+ *
+ * However, this has the requirement that you do not change this
+ * content in any way, only access the information that these events
+ * occurred.
+ *
+ * Returns: a handler-id which can be used with
+ * ide_buffer_remove_commit_funcs().
+ */
+guint
+ide_buffer_add_commit_funcs (IdeBuffer *self,
+ IdeBufferCommitFunc before_insert_text,
+ IdeBufferCommitFunc after_insert_text,
+ IdeBufferCommitFunc before_delete_range,
+ IdeBufferCommitFunc after_delete_range,
+ gpointer user_data,
+ GDestroyNotify user_data_destroy)
+{
+ CommitHooks hooks;
+
+ g_return_val_if_fail (IDE_IS_BUFFER (self), 0);
+
+ hooks.before_insert_text = before_insert_text;
+ hooks.after_insert_text = after_insert_text;
+ hooks.after_delete_range = after_delete_range;
+ hooks.before_delete_range = before_delete_range;
+ hooks.user_data = user_data;
+ hooks.user_data_destroy = user_data_destroy;
+ hooks.handler_id = ++self->next_commit_handler;
+
+ g_array_append_val (self->commit_funcs, hooks);
+
+ return hooks.handler_id;
+}
+
+void
+ide_buffer_remove_commit_funcs (IdeBuffer *self,
+ guint commit_funcs_handler)
+{
+ g_return_if_fail (IDE_IS_BUFFER (self));
+ g_return_if_fail (commit_funcs_handler > 0);
+
+ for (guint i = 0; i < self->commit_funcs->len; i++)
+ {
+ const CommitHooks *hooks = &g_array_index (self->commit_funcs, CommitHooks, i);
+
+ if (hooks->handler_id == commit_funcs_handler)
+ {
+ g_array_remove_index (self->commit_funcs, i);
+ return;
+ }
+ }
+
+ g_warning ("Failed to locate commit handler %u", commit_funcs_handler);
+}
+
+const char *
+ide_buffer_get_charset (IdeBuffer *self)
+{
+ g_return_val_if_fail (IDE_IS_BUFFER (self), NULL);
+
+ return self->encoding
+ ? gtk_source_encoding_get_charset (self->encoding)
+ : "UTF-8";
+}
+
+void
+ide_buffer_set_charset (IdeBuffer *self,
+ const char *charset)
+{
+ GSList *all;
+
+ g_return_if_fail (IDE_IS_BUFFER (self));
+
+ if (charset == NULL || charset[0] == 0)
+ charset = "UTF-8";
+
+ all = gtk_source_encoding_get_all ();
+
+ for (const GSList *iter = all; iter; iter = iter->next)
+ {
+ const GtkSourceEncoding *encoding = iter->data;
+
+ if (g_strcmp0 (charset, gtk_source_encoding_get_charset (encoding)) == 0)
+ {
+ if (self->encoding != encoding)
+ {
+ self->encoding = encoding;
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CHARSET]);
+ break;
+ }
+ }
+ }
+
+ g_slist_free (all);
+}
+
+GtkSourceNewlineType
+ide_buffer_get_newline_type (IdeBuffer *self)
+{
+ g_return_val_if_fail (IDE_IS_BUFFER (self), GTK_SOURCE_NEWLINE_TYPE_LF);
+
+ return self->newline_type;
+}
+
+void
+ide_buffer_set_newline_type (IdeBuffer *self,
+ GtkSourceNewlineType newline_type)
+{
+ g_return_if_fail (IDE_IS_BUFFER (self));
+ g_return_if_fail (newline_type == GTK_SOURCE_NEWLINE_TYPE_LF ||
+ newline_type == GTK_SOURCE_NEWLINE_TYPE_CR ||
+ newline_type == GTK_SOURCE_NEWLINE_TYPE_CR_LF);
+
+ if (newline_type == self->newline_type)
+ return;
+
+ self->newline_type = newline_type;
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_NEWLINE_TYPE]);
+}
diff --git a/src/libide/code/ide-buffer.h b/src/libide/code/ide-buffer.h
index 7c186076f..b4a938a88 100644
--- a/src/libide/code/ide-buffer.h
+++ b/src/libide/code/ide-buffer.h
@@ -48,139 +48,165 @@ typedef enum
IDE_BUFFER_STATE_FAILED,
} IdeBufferState;
-IDE_AVAILABLE_IN_3_32
+typedef void (*IdeBufferCommitFunc) (IdeBuffer *buffer,
+ guint position,
+ guint length,
+ gpointer user_data);
+
+IDE_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (IdeBuffer, ide_buffer, IDE, BUFFER, GtkSourceBuffer)
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
GBytes *ide_buffer_dup_content (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gchar *ide_buffer_dup_title (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_format_selection_async (IdeBuffer *self,
IdeFormatterOptions *options,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_format_selection_finish (IdeBuffer *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_42
+IDE_AVAILABLE_IN_ALL
void ide_buffer_code_action_query_async (IdeBuffer *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_42
+IDE_AVAILABLE_IN_ALL
GPtrArray* ide_buffer_code_action_query_finish (IdeBuffer *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
guint ide_buffer_get_change_count (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBufferChangeMonitor *ide_buffer_get_change_monitor (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_get_changed_on_volume (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeDiagnostics *ide_buffer_get_diagnostics (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeLocation *ide_buffer_get_insert_location (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_get_is_temporary (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_get_failed (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
const GError *ide_buffer_get_failure (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gchar *ide_buffer_dup_uri (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
GFile *ide_buffer_get_file (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeFileSettings *ide_buffer_get_file_settings (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeFormatter *ide_buffer_get_formatter (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_get_highlight_diagnostics (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_get_iter_at_location (IdeBuffer *self,
GtkTextIter *iter,
IdeLocation *location);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeLocation *ide_buffer_get_iter_location (IdeBuffer *self,
const GtkTextIter *iter);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
const gchar *ide_buffer_get_language_id (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_set_language_id (IdeBuffer *self,
const gchar *language_id);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gchar *ide_buffer_get_line_text (IdeBuffer *self,
guint line);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_get_loading (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_get_read_only (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeRenameProvider *ide_buffer_get_rename_provider (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_get_selection_bounds (IdeBuffer *self,
GtkTextIter *insert,
GtkTextIter *selection);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeRange *ide_buffer_get_selection_range (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBufferState ide_buffer_get_state (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
const gchar *ide_buffer_get_style_scheme_name (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_get_symbol_at_location_async (IdeBuffer *self,
const GtkTextIter *location,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeSymbol *ide_buffer_get_symbol_at_location_finish (IdeBuffer *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
GPtrArray *ide_buffer_get_symbol_resolvers (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gchar *ide_buffer_get_word_at_iter (IdeBuffer *self,
const GtkTextIter *iter);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_has_diagnostics (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_has_symbol_resolvers (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeBuffer *ide_buffer_hold (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
IdeContext *ide_buffer_ref_context (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_rehighlight (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_release (IdeBuffer *self);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_save_file_async (IdeBuffer *self,
GFile *file,
GCancellable *cancellable,
IdeNotification **notif,
GAsyncReadyCallback callback,
gpointer user_data);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
gboolean ide_buffer_save_file_finish (IdeBuffer *self,
GAsyncResult *result,
GError **error);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_set_change_monitor (IdeBuffer *self,
IdeBufferChangeMonitor *change_monitor);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_set_diagnostics (IdeBuffer *self,
IdeDiagnostics *diagnostics);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_set_highlight_diagnostics (IdeBuffer *self,
gboolean
highlight_diagnostics);
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
void ide_buffer_set_style_scheme_name (IdeBuffer *self,
const gchar
*style_scheme_name);
+IDE_AVAILABLE_IN_ALL
+guint ide_buffer_add_commit_funcs (IdeBuffer *self,
+ IdeBufferCommitFunc
before_insert_text,
+ IdeBufferCommitFunc after_insert_text,
+ IdeBufferCommitFunc
before_delete_range,
+ IdeBufferCommitFunc
after_delete_range,
+ gpointer user_data,
+ GDestroyNotify
user_data_destroy);
+IDE_AVAILABLE_IN_ALL
+void ide_buffer_remove_commit_funcs (IdeBuffer *self,
+ guint
commit_funcs_handler);
+IDE_AVAILABLE_IN_ALL
+const char *ide_buffer_get_charset (IdeBuffer *self);
+IDE_AVAILABLE_IN_ALL
+void ide_buffer_set_charset (IdeBuffer *self,
+ const char *charset);
+IDE_AVAILABLE_IN_ALL
+GtkSourceNewlineType ide_buffer_get_newline_type (IdeBuffer *self);
+IDE_AVAILABLE_IN_ALL
+void ide_buffer_set_newline_type (IdeBuffer *self,
+ GtkSourceNewlineType newline_type);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]