// This file was generated by gir (https://github.com/gtk-rs/gir)
// from
// from gir-files (https://github.com/gtk-rs/gir-files.git)
// DO NOT EDIT

use crate::{ffi, BracketMatchType, ChangeCaseType, Language, Mark, SortFlags, StyleScheme};
use glib::{
    object::ObjectType as _,
    prelude::*,
    signal::{connect_raw, SignalHandlerId},
    translate::*,
};
use std::boxed::Box as Box_;

glib::wrapper! {
    #[doc(alias = "GtkSourceBuffer")]
    pub struct Buffer(Object<ffi::GtkSourceBuffer, ffi::GtkSourceBufferClass>) @extends gtk::TextBuffer;

    match fn {
        type_ => || ffi::gtk_source_buffer_get_type(),
    }
}

impl Buffer {
    pub const NONE: Option<&'static Buffer> = None;

    #[doc(alias = "gtk_source_buffer_new")]
    pub fn new(table: Option<&gtk::TextTagTable>) -> Buffer {
        assert_initialized_main_thread!();
        unsafe { from_glib_full(ffi::gtk_source_buffer_new(table.to_glib_none().0)) }
    }

    #[doc(alias = "gtk_source_buffer_new_with_language")]
    #[doc(alias = "new_with_language")]
    pub fn with_language(language: &Language) -> Buffer {
        skip_assert_initialized!();
        unsafe {
            from_glib_full(ffi::gtk_source_buffer_new_with_language(
                language.to_glib_none().0,
            ))
        }
    }

    // rustdoc-stripper-ignore-next
    /// Creates a new builder-pattern struct instance to construct [`Buffer`] objects.
    ///
    /// This method returns an instance of [`BufferBuilder`](crate::builders::BufferBuilder) which can be used to create [`Buffer`] objects.
    pub fn builder() -> BufferBuilder {
        BufferBuilder::new()
    }
}

impl Default for Buffer {
    fn default() -> Self {
        glib::object::Object::new::<Self>()
    }
}

// rustdoc-stripper-ignore-next
/// A [builder-pattern] type to construct [`Buffer`] objects.
///
/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
#[must_use = "The builder must be built to be used"]
pub struct BufferBuilder {
    builder: glib::object::ObjectBuilder<'static, Buffer>,
}

impl BufferBuilder {
    fn new() -> Self {
        Self {
            builder: glib::object::Object::builder(),
        }
    }

    pub fn highlight_matching_brackets(self, highlight_matching_brackets: bool) -> Self {
        Self {
            builder: self
                .builder
                .property("highlight-matching-brackets", highlight_matching_brackets),
        }
    }

    pub fn highlight_syntax(self, highlight_syntax: bool) -> Self {
        Self {
            builder: self.builder.property("highlight-syntax", highlight_syntax),
        }
    }

    pub fn implicit_trailing_newline(self, implicit_trailing_newline: bool) -> Self {
        Self {
            builder: self
                .builder
                .property("implicit-trailing-newline", implicit_trailing_newline),
        }
    }

    pub fn language(self, language: &Language) -> Self {
        Self {
            builder: self.builder.property("language", language.clone()),
        }
    }

    pub fn style_scheme(self, style_scheme: &StyleScheme) -> Self {
        Self {
            builder: self.builder.property("style-scheme", style_scheme.clone()),
        }
    }

    pub fn enable_undo(self, enable_undo: bool) -> Self {
        Self {
            builder: self.builder.property("enable-undo", enable_undo),
        }
    }

    pub fn tag_table(self, tag_table: &gtk::TextTagTable) -> Self {
        Self {
            builder: self.builder.property("tag-table", tag_table.clone()),
        }
    }

    pub fn text(self, text: impl Into<glib::GString>) -> Self {
        Self {
            builder: self.builder.property("text", text.into()),
        }
    }

    // rustdoc-stripper-ignore-next
    /// Build the [`Buffer`].
    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
    pub fn build(self) -> Buffer {
        assert_initialized_main_thread!();
        self.builder.build()
    }
}

pub trait BufferExt: IsA<Buffer> + 'static {
    //#[doc(alias = "gtk_source_buffer_backward_iter_to_source_mark")]
    //fn backward_iter_to_source_mark(&self, iter: /*Unimplemented*/gtk::TextIter, category: Option<&str>) -> bool {
    //    unsafe { TODO: call ffi:gtk_source_buffer_backward_iter_to_source_mark() }
    //}

    #[doc(alias = "gtk_source_buffer_change_case")]
    fn change_case(
        &self,
        case_type: ChangeCaseType,
        start: &mut gtk::TextIter,
        end: &mut gtk::TextIter,
    ) {
        unsafe {
            ffi::gtk_source_buffer_change_case(
                self.as_ref().to_glib_none().0,
                case_type.into_glib(),
                start.to_glib_none_mut().0,
                end.to_glib_none_mut().0,
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_create_source_mark")]
    fn create_source_mark(
        &self,
        name: Option<&str>,
        category: &str,
        where_: &gtk::TextIter,
    ) -> Mark {
        unsafe {
            from_glib_none(ffi::gtk_source_buffer_create_source_mark(
                self.as_ref().to_glib_none().0,
                name.to_glib_none().0,
                category.to_glib_none().0,
                where_.to_glib_none().0,
            ))
        }
    }

    //#[doc(alias = "gtk_source_buffer_create_source_tag")]
    //fn create_source_tag(&self, tag_name: Option<&str>, first_property_name: Option<&str>, : /*Unknown conversion*//*Unimplemented*/Basic: VarArgs) -> gtk::TextTag {
    //    unsafe { TODO: call ffi:gtk_source_buffer_create_source_tag() }
    //}

    #[doc(alias = "gtk_source_buffer_ensure_highlight")]
    fn ensure_highlight(&self, start: &gtk::TextIter, end: &gtk::TextIter) {
        unsafe {
            ffi::gtk_source_buffer_ensure_highlight(
                self.as_ref().to_glib_none().0,
                start.to_glib_none().0,
                end.to_glib_none().0,
            );
        }
    }

    //#[doc(alias = "gtk_source_buffer_forward_iter_to_source_mark")]
    //fn forward_iter_to_source_mark(&self, iter: /*Unimplemented*/gtk::TextIter, category: Option<&str>) -> bool {
    //    unsafe { TODO: call ffi:gtk_source_buffer_forward_iter_to_source_mark() }
    //}

    #[doc(alias = "gtk_source_buffer_get_context_classes_at_iter")]
    #[doc(alias = "get_context_classes_at_iter")]
    fn context_classes_at_iter(&self, iter: &gtk::TextIter) -> Vec<glib::GString> {
        unsafe {
            FromGlibPtrContainer::from_glib_full(
                ffi::gtk_source_buffer_get_context_classes_at_iter(
                    self.as_ref().to_glib_none().0,
                    iter.to_glib_none().0,
                ),
            )
        }
    }

    #[doc(alias = "gtk_source_buffer_get_highlight_matching_brackets")]
    #[doc(alias = "get_highlight_matching_brackets")]
    #[doc(alias = "highlight-matching-brackets")]
    fn is_highlight_matching_brackets(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_source_buffer_get_highlight_matching_brackets(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gtk_source_buffer_get_highlight_syntax")]
    #[doc(alias = "get_highlight_syntax")]
    #[doc(alias = "highlight-syntax")]
    fn is_highlight_syntax(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_source_buffer_get_highlight_syntax(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gtk_source_buffer_get_implicit_trailing_newline")]
    #[doc(alias = "get_implicit_trailing_newline")]
    #[doc(alias = "implicit-trailing-newline")]
    fn is_implicit_trailing_newline(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_source_buffer_get_implicit_trailing_newline(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gtk_source_buffer_get_language")]
    #[doc(alias = "get_language")]
    fn language(&self) -> Option<Language> {
        unsafe {
            from_glib_none(ffi::gtk_source_buffer_get_language(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gtk_source_buffer_get_loading")]
    #[doc(alias = "get_loading")]
    #[doc(alias = "loading")]
    fn is_loading(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_source_buffer_get_loading(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    #[cfg(feature = "v5_18")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v5_18")))]
    #[doc(alias = "gtk_source_buffer_get_markup")]
    #[doc(alias = "get_markup")]
    fn markup(&self, start: &mut gtk::TextIter, end: &mut gtk::TextIter) -> glib::GString {
        unsafe {
            from_glib_full(ffi::gtk_source_buffer_get_markup(
                self.as_ref().to_glib_none().0,
                start.to_glib_none_mut().0,
                end.to_glib_none_mut().0,
            ))
        }
    }

    #[doc(alias = "gtk_source_buffer_get_source_marks_at_iter")]
    #[doc(alias = "get_source_marks_at_iter")]
    fn source_marks_at_iter(&self, iter: &mut gtk::TextIter, category: Option<&str>) -> Vec<Mark> {
        unsafe {
            FromGlibPtrContainer::from_glib_container(
                ffi::gtk_source_buffer_get_source_marks_at_iter(
                    self.as_ref().to_glib_none().0,
                    iter.to_glib_none_mut().0,
                    category.to_glib_none().0,
                ),
            )
        }
    }

    #[doc(alias = "gtk_source_buffer_get_source_marks_at_line")]
    #[doc(alias = "get_source_marks_at_line")]
    fn source_marks_at_line(&self, line: i32, category: Option<&str>) -> Vec<Mark> {
        unsafe {
            FromGlibPtrContainer::from_glib_container(
                ffi::gtk_source_buffer_get_source_marks_at_line(
                    self.as_ref().to_glib_none().0,
                    line,
                    category.to_glib_none().0,
                ),
            )
        }
    }

    #[doc(alias = "gtk_source_buffer_get_style_scheme")]
    #[doc(alias = "get_style_scheme")]
    #[doc(alias = "style-scheme")]
    fn style_scheme(&self) -> Option<StyleScheme> {
        unsafe {
            from_glib_none(ffi::gtk_source_buffer_get_style_scheme(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    //#[doc(alias = "gtk_source_buffer_iter_backward_to_context_class_toggle")]
    //fn iter_backward_to_context_class_toggle(&self, iter: /*Unimplemented*/gtk::TextIter, context_class: &str) -> bool {
    //    unsafe { TODO: call ffi:gtk_source_buffer_iter_backward_to_context_class_toggle() }
    //}

    //#[doc(alias = "gtk_source_buffer_iter_forward_to_context_class_toggle")]
    //fn iter_forward_to_context_class_toggle(&self, iter: /*Unimplemented*/gtk::TextIter, context_class: &str) -> bool {
    //    unsafe { TODO: call ffi:gtk_source_buffer_iter_forward_to_context_class_toggle() }
    //}

    #[doc(alias = "gtk_source_buffer_iter_has_context_class")]
    fn iter_has_context_class(&self, iter: &gtk::TextIter, context_class: &str) -> bool {
        unsafe {
            from_glib(ffi::gtk_source_buffer_iter_has_context_class(
                self.as_ref().to_glib_none().0,
                iter.to_glib_none().0,
                context_class.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "gtk_source_buffer_join_lines")]
    fn join_lines(&self, start: &mut gtk::TextIter, end: &mut gtk::TextIter) {
        unsafe {
            ffi::gtk_source_buffer_join_lines(
                self.as_ref().to_glib_none().0,
                start.to_glib_none_mut().0,
                end.to_glib_none_mut().0,
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_remove_source_marks")]
    fn remove_source_marks(
        &self,
        start: &gtk::TextIter,
        end: &gtk::TextIter,
        category: Option<&str>,
    ) {
        unsafe {
            ffi::gtk_source_buffer_remove_source_marks(
                self.as_ref().to_glib_none().0,
                start.to_glib_none().0,
                end.to_glib_none().0,
                category.to_glib_none().0,
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_set_highlight_matching_brackets")]
    #[doc(alias = "highlight-matching-brackets")]
    fn set_highlight_matching_brackets(&self, highlight: bool) {
        unsafe {
            ffi::gtk_source_buffer_set_highlight_matching_brackets(
                self.as_ref().to_glib_none().0,
                highlight.into_glib(),
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_set_highlight_syntax")]
    #[doc(alias = "highlight-syntax")]
    fn set_highlight_syntax(&self, highlight: bool) {
        unsafe {
            ffi::gtk_source_buffer_set_highlight_syntax(
                self.as_ref().to_glib_none().0,
                highlight.into_glib(),
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_set_implicit_trailing_newline")]
    #[doc(alias = "implicit-trailing-newline")]
    fn set_implicit_trailing_newline(&self, implicit_trailing_newline: bool) {
        unsafe {
            ffi::gtk_source_buffer_set_implicit_trailing_newline(
                self.as_ref().to_glib_none().0,
                implicit_trailing_newline.into_glib(),
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_set_language")]
    #[doc(alias = "language")]
    fn set_language(&self, language: Option<&Language>) {
        unsafe {
            ffi::gtk_source_buffer_set_language(
                self.as_ref().to_glib_none().0,
                language.to_glib_none().0,
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_set_style_scheme")]
    #[doc(alias = "style-scheme")]
    fn set_style_scheme(&self, scheme: Option<&StyleScheme>) {
        unsafe {
            ffi::gtk_source_buffer_set_style_scheme(
                self.as_ref().to_glib_none().0,
                scheme.to_glib_none().0,
            );
        }
    }

    #[doc(alias = "gtk_source_buffer_sort_lines")]
    fn sort_lines(
        &self,
        start: &mut gtk::TextIter,
        end: &mut gtk::TextIter,
        flags: SortFlags,
        column: i32,
    ) {
        unsafe {
            ffi::gtk_source_buffer_sort_lines(
                self.as_ref().to_glib_none().0,
                start.to_glib_none_mut().0,
                end.to_glib_none_mut().0,
                flags.into_glib(),
                column,
            );
        }
    }

    #[doc(alias = "bracket-matched")]
    fn connect_bracket_matched<F: Fn(&Self, Option<&gtk::TextIter>, BracketMatchType) + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn bracket_matched_trampoline<
            P: IsA<Buffer>,
            F: Fn(&P, Option<&gtk::TextIter>, BracketMatchType) + 'static,
        >(
            this: *mut ffi::GtkSourceBuffer,
            iter: *mut gtk::ffi::GtkTextIter,
            state: ffi::GtkSourceBracketMatchType,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(
                Buffer::from_glib_borrow(this).unsafe_cast_ref(),
                Option::<gtk::TextIter>::from_glib_borrow(iter)
                    .as_ref()
                    .as_ref(),
                from_glib(state),
            )
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"bracket-matched".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    bracket_matched_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "cursor-moved")]
    fn connect_cursor_moved<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn cursor_moved_trampoline<P: IsA<Buffer>, F: Fn(&P) + 'static>(
            this: *mut ffi::GtkSourceBuffer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(Buffer::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"cursor-moved".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    cursor_moved_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "highlight-updated")]
    fn connect_highlight_updated<F: Fn(&Self, &gtk::TextIter, &gtk::TextIter) + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn highlight_updated_trampoline<
            P: IsA<Buffer>,
            F: Fn(&P, &gtk::TextIter, &gtk::TextIter) + 'static,
        >(
            this: *mut ffi::GtkSourceBuffer,
            start: *mut gtk::ffi::GtkTextIter,
            end: *mut gtk::ffi::GtkTextIter,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(
                Buffer::from_glib_borrow(this).unsafe_cast_ref(),
                &from_glib_borrow(start),
                &from_glib_borrow(end),
            )
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"highlight-updated".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    highlight_updated_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "source-mark-updated")]
    fn connect_source_mark_updated<F: Fn(&Self, &gtk::TextMark) + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn source_mark_updated_trampoline<
            P: IsA<Buffer>,
            F: Fn(&P, &gtk::TextMark) + 'static,
        >(
            this: *mut ffi::GtkSourceBuffer,
            mark: *mut gtk::ffi::GtkTextMark,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(
                Buffer::from_glib_borrow(this).unsafe_cast_ref(),
                &from_glib_borrow(mark),
            )
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"source-mark-updated".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    source_mark_updated_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "highlight-matching-brackets")]
    fn connect_highlight_matching_brackets_notify<F: Fn(&Self) + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn notify_highlight_matching_brackets_trampoline<
            P: IsA<Buffer>,
            F: Fn(&P) + 'static,
        >(
            this: *mut ffi::GtkSourceBuffer,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(Buffer::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"notify::highlight-matching-brackets".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_highlight_matching_brackets_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "highlight-syntax")]
    fn connect_highlight_syntax_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_highlight_syntax_trampoline<
            P: IsA<Buffer>,
            F: Fn(&P) + 'static,
        >(
            this: *mut ffi::GtkSourceBuffer,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(Buffer::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"notify::highlight-syntax".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_highlight_syntax_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "implicit-trailing-newline")]
    fn connect_implicit_trailing_newline_notify<F: Fn(&Self) + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn notify_implicit_trailing_newline_trampoline<
            P: IsA<Buffer>,
            F: Fn(&P) + 'static,
        >(
            this: *mut ffi::GtkSourceBuffer,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(Buffer::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"notify::implicit-trailing-newline".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_implicit_trailing_newline_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "language")]
    fn connect_language_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_language_trampoline<P: IsA<Buffer>, F: Fn(&P) + 'static>(
            this: *mut ffi::GtkSourceBuffer,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(Buffer::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"notify::language".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_language_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[cfg(feature = "v5_10")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v5_10")))]
    #[doc(alias = "loading")]
    fn connect_loading_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_loading_trampoline<P: IsA<Buffer>, F: Fn(&P) + 'static>(
            this: *mut ffi::GtkSourceBuffer,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(Buffer::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"notify::loading".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_loading_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "style-scheme")]
    fn connect_style_scheme_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_style_scheme_trampoline<P: IsA<Buffer>, F: Fn(&P) + 'static>(
            this: *mut ffi::GtkSourceBuffer,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(Buffer::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"notify::style-scheme".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_style_scheme_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}

impl<O: IsA<Buffer>> BufferExt for O {}
