diff --git a/Cargo.lock b/Cargo.lock
index e5277dd5a04bff65b61eaa76d7a9c5c1d8b4f6cf..134884de6bea4639b3960509fcdf388e1b76ebdb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -505,9 +505,6 @@ dependencies = [
  "image",
  "insta",
  "js-sys",
- "num",
- "num-derive",
- "num-traits",
  "sys-locale",
  "unicode-segmentation",
  "wasm-bindgen",
@@ -2676,20 +2673,6 @@ dependencies = [
  "winapi",
 ]
 
-[[package]]
-name = "num"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
-dependencies = [
- "num-bigint",
- "num-complex",
- "num-integer",
- "num-iter",
- "num-rational",
- "num-traits",
-]
-
 [[package]]
 name = "num-bigint"
 version = "0.4.6"
@@ -2700,15 +2683,6 @@ dependencies = [
  "num-traits",
 ]
 
-[[package]]
-name = "num-complex"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
-dependencies = [
- "num-traits",
-]
-
 [[package]]
 name = "num-derive"
 version = "0.4.2"
@@ -2729,17 +2703,6 @@ dependencies = [
  "num-traits",
 ]
 
-[[package]]
-name = "num-iter"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
 [[package]]
 name = "num-rational"
 version = "0.4.2"
diff --git a/Cargo.toml b/Cargo.toml
index f9f9d3459daf91a414ce262395cbed47e02790be..d7ad78586e125f7d07489649a0898cdcb869808d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,18 +18,18 @@ internal-debugging = ["bevy/track_change_detection"]
 
 [dependencies]
 bevy = { version = "0.15", default-features = false, features = [
-    "bevy_asset",
-    "bevy_core_pipeline",
-    "bevy_render",
-    "bevy_scene",
-    "bevy_sprite",
-    "bevy_text",
-    "bevy_ui",
-    "bevy_winit",
-    "bevy_window",
-    "png",
-    "x11",
-    "webgl2",
+  "bevy_asset",
+  "bevy_core_pipeline",
+  "bevy_render",
+  "bevy_scene",
+  "bevy_sprite",
+  "bevy_text",
+  "bevy_ui",
+  "bevy_winit",
+  "bevy_window",
+  "png",
+  "x11",
+  "webgl2",
 ] }
 unicode-segmentation = { version = "1.11.0" }
 # TODO: move crossbeam to wasm32, once input.rs has separate wasm copy/paste fn
@@ -37,9 +37,6 @@ crossbeam-channel = "0.5.8"
 image = "0.25.1"
 sys-locale = "0.3.0"
 document-features = "0.2.8"
-num = "0.4.3"
-num-derive = "0.4.2"
-num-traits = "0.2.19"
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 arboard = "3.2.0"
@@ -49,9 +46,9 @@ js-sys = "0.3.70"
 wasm-bindgen = "0.2.93"
 wasm-bindgen-futures = "0.4.42"
 web-sys = { version = "0.3.70", features = [
-    "Clipboard",
-    "Navigator",
-    "Window",
+  "Clipboard",
+  "Navigator",
+  "Window",
 ] }
 
 [dev-dependencies]
diff --git a/examples/multiple_sprites.rs b/examples/multiple_sprites.rs
index b5174a6437f066bf8768e9119581a123b503a008..0782ae7c994f8493fd8c09135a5613600627975b 100644
--- a/examples/multiple_sprites.rs
+++ b/examples/multiple_sprites.rs
@@ -24,23 +24,25 @@ fn setup(
     attrs = attrs.family(Family::Name("Victor Mono"));
     attrs = attrs.color(bevy::color::palettes::basic::PURPLE.to_cosmic());
 
-    commands.spawn((
-        TextEdit2d,
-        CosmicEditBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text(
-            &mut font_system,
-            "πŸ˜€πŸ˜€πŸ˜€ x => y",
-            attrs,
-        ),
-        CosmicBackgroundColor(bevy::color::palettes::css::ALICE_BLUE.into()),
-        Sprite {
-            custom_size: Some(Vec2 {
-                x: primary_window.width() / 2.,
-                y: primary_window.height(),
-            }),
-            ..default()
-        },
-        Transform::from_translation(Vec3::new(-primary_window.width() / 4., 0., 1.)),
-    ));
+    commands
+        .spawn((
+            TextEdit2d,
+            CosmicEditBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text(
+                &mut font_system,
+                "πŸ˜€πŸ˜€πŸ˜€ x => y",
+                attrs,
+            ),
+            CosmicBackgroundColor(bevy::color::palettes::css::ALICE_BLUE.into()),
+            Sprite {
+                custom_size: Some(Vec2 {
+                    x: primary_window.width() / 2.,
+                    y: primary_window.height(),
+                }),
+                ..default()
+            },
+            Transform::from_translation(Vec3::new(-primary_window.width() / 4., 0., 1.)),
+        ))
+        .observe(focus_on_click);
 
     commands
         .spawn((
diff --git a/examples/password.rs b/examples/password.rs
index 90c2b62456c10b0a90fb8038d862392ab3b13b2d..33c6fd263e1b1d8aa9cb3bf17c2ffc065a496835 100644
--- a/examples/password.rs
+++ b/examples/password.rs
@@ -1,7 +1,7 @@
 use bevy::prelude::*;
 use bevy_cosmic_edit::{
-    cosmic_text::Attrs, password::Password, placeholder::Placeholder, prelude::*, CosmicWrap,
-    MaxLines,
+    cosmic_text::Attrs, password::Password, placeholder::Placeholder, prelude::*, CosmicTextAlign,
+    CosmicWrap, MaxLines,
 };
 
 fn setup(mut commands: Commands) {
@@ -14,6 +14,7 @@ fn setup(mut commands: Commands) {
             CosmicEditBuffer::default(),
             MaxLines(1),
             CosmicWrap::InfiniteLine,
+            CosmicTextAlign::left_center(),
             // Sets size of text box
             Sprite {
                 custom_size: Some(Vec2::new(300., 100.)),
diff --git a/examples/scroll.rs b/examples/scroll.rs
index 47d8e00f9888c70bf8287cd9627be36982bf083c..b98ece572176b4bd1843931faed687d79a46655f 100644
--- a/examples/scroll.rs
+++ b/examples/scroll.rs
@@ -25,7 +25,7 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) {
                 .as_str(),
                 attrs,
             ),
-            ScrollEnabled::Enabled,
+            ScrollEnabled(true),
             CosmicTextAlign::top_left(),
             DefaultAttrs(AttrsOwned::new(
                 Attrs::new().color(bevy::color::palettes::css::LIMEGREEN.to_cosmic()),
diff --git a/src/cosmic_edit.rs b/src/cosmic_edit.rs
index 0de3284b7483433571f3dce284eafdfff9907ff8..403a31de4142fe3ddd604648e096191f02551e00 100644
--- a/src/cosmic_edit.rs
+++ b/src/cosmic_edit.rs
@@ -112,11 +112,9 @@ pub enum VerticalAlign {
     /// If [bevy_cosmic_edit] made no manual calcualtions, this would
     /// effecively be the default
     Top,
-
     /// Default
     #[default]
     Center,
-
     Bottom,
 }
 
@@ -202,16 +200,12 @@ pub struct MaxLines(pub usize);
 pub struct MaxChars(pub usize);
 
 /// Should [`CosmicEditBuffer`] respond to scroll events?
-#[derive(Component, Reflect, Default)]
-pub enum ScrollEnabled {
-    #[default]
-    Enabled,
-    Disabled,
-}
+#[derive(Component, Reflect, Deref)]
+pub struct ScrollEnabled(pub bool);
 
-impl ScrollEnabled {
-    pub fn should_scroll(&self) -> bool {
-        matches!(self, ScrollEnabled::Enabled)
+impl Default for ScrollEnabled {
+    fn default() -> Self {
+        Self(true)
     }
 }
 
diff --git a/src/editor_buffer.rs b/src/editor_buffer.rs
index abedefc0f2b63b4b1eb10b29991dfac4d664086b..df5da0ed563f12c8d7f1e62dc3204e60c21d863f 100644
--- a/src/editor_buffer.rs
+++ b/src/editor_buffer.rs
@@ -8,13 +8,9 @@ use cosmic_text::{Attrs, BufferRef, FontSystem, Shaping};
 
 use crate::prelude::*;
 
-pub(crate) struct EditorBufferPlugin;
-
-impl Plugin for EditorBufferPlugin {
-    fn build(&self, app: &mut App) {
-        app.add_systems(First, (buffer::set_initial_scale, buffer::add_font_system))
-            .add_systems(Update, editor::blink_cursor);
-    }
+pub(crate) fn plugin(app: &mut App) {
+    app.add_systems(First, (buffer::set_initial_scale, buffer::add_font_system))
+        .add_systems(Update, editor::blink_cursor);
 }
 
 pub mod buffer;
diff --git a/src/focus.rs b/src/focus.rs
index e61fbd0896ee8e245c96b59e318a0cfe27990f97..2fa4d2d9bf1fa3ac8a4fb77b1812c0f7afe0b359 100644
--- a/src/focus.rs
+++ b/src/focus.rs
@@ -9,19 +9,15 @@ use crate::prelude::*;
 #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
 pub(crate) struct FocusSet;
 
-pub(crate) struct FocusPlugin;
-
-impl Plugin for FocusPlugin {
-    fn build(&self, app: &mut App) {
-        app.add_systems(
-            PostUpdate,
-            (drop_editor_unfocused, add_editor_to_focused)
-                .chain()
-                .in_set(FocusSet),
-        )
-        .init_resource::<FocusedWidget>()
-        .register_type::<FocusedWidget>();
-    }
+pub(crate) fn plugin(app: &mut App) {
+    app.add_systems(
+        PostUpdate,
+        (drop_editor_unfocused, add_editor_to_focused)
+            .chain()
+            .in_set(FocusSet),
+    )
+    .init_resource::<FocusedWidget>()
+    .register_type::<FocusedWidget>();
 }
 
 /// Resource struct that keeps track of the currently active editor entity.
@@ -57,8 +53,6 @@ pub(crate) fn drop_editor_unfocused(
     match active_editor.0 {
         None => {
             for (e, mut buffer, editor) in q.iter_mut() {
-                // buffer.lines = editor.with_buffer(|buf| buf.lines.clone());
-                // buffer.set_redraw(true);
                 *buffer = CosmicEditBuffer::from_downgrading_editor(editor);
                 trace!("Removing editor from all entities as there is no focussed widget",);
                 commands.entity(e).remove::<CosmicEditor>();
diff --git a/src/input.rs b/src/input.rs
index 0d97a143da0059002841cf6975ce26a955af9bd3..bed303d104727672ca3b7d92eab829c6bff89873 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -16,38 +16,34 @@ pub mod scroll;
 #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
 pub struct InputSet;
 
-pub(crate) struct InputPlugin;
-
-impl Plugin for InputPlugin {
-    fn build(&self, app: &mut App) {
-        app.add_systems(PreUpdate, scroll::scroll.in_set(InputSet))
-            .add_systems(
-                Update,
+pub(crate) fn plugin(app: &mut App) {
+    app.add_systems(PreUpdate, scroll::scroll.in_set(InputSet))
+        .add_systems(
+            Update,
+            (
+                keyboard::kb_move_cursor,
+                keyboard::kb_input_text,
+                clipboard::kb_clipboard,
                 (
-                    keyboard::kb_move_cursor,
-                    keyboard::kb_input_text,
-                    clipboard::kb_clipboard,
-                    (
-                        cursor_icon::update_cursor_icon,
-                        cursor_visibility::update_cursor_visibility,
-                    ),
-                )
-                    .chain()
-                    .in_set(InputSet),
+                    cursor_icon::update_cursor_icon,
+                    cursor_visibility::update_cursor_visibility,
+                ),
             )
-            .add_event::<hover::TextHoverIn>()
-            .add_event::<hover::TextHoverOut>()
-            .add_event::<CosmicTextChanged>()
-            .register_type::<hover::TextHoverIn>()
-            .register_type::<hover::TextHoverOut>()
-            .register_type::<CosmicTextChanged>();
+                .chain()
+                .in_set(InputSet),
+        )
+        .add_event::<hover::TextHoverIn>()
+        .add_event::<hover::TextHoverOut>()
+        .add_event::<CosmicTextChanged>()
+        .register_type::<hover::TextHoverIn>()
+        .register_type::<hover::TextHoverOut>()
+        .register_type::<CosmicTextChanged>();
 
-        #[cfg(target_arch = "wasm32")]
-        {
-            let (tx, rx) = crossbeam_channel::bounded::<clipboard::WasmPaste>(1);
-            app.insert_resource(clipboard::WasmPasteAsyncChannel { tx, rx })
-                .add_systems(Update, clipboard::poll_wasm_paste);
-        }
+    #[cfg(target_arch = "wasm32")]
+    {
+        let (tx, rx) = crossbeam_channel::bounded::<clipboard::WasmPaste>(1);
+        app.insert_resource(clipboard::WasmPasteAsyncChannel { tx, rx })
+            .add_systems(Update, clipboard::poll_wasm_paste);
     }
 }
 
@@ -77,7 +73,7 @@ fn add_event_handlers(
     _component_id: ComponentId,
 ) {
     let mut observers = [
-        Observer::new(click::handle_focussed_click.pipe(render_implementations::debug_error)),
+        Observer::new(click::handle_focused_click.pipe(render_implementations::debug_error)),
         Observer::new(drag::handle_dragstart.pipe(render_implementations::debug_error)),
         Observer::new(drag::handle_drag_continue),
         Observer::new(drag::handle_dragend),
diff --git a/src/input/click.rs b/src/input/click.rs
index c056212e5c3c5bd601ff839e4f58b59052f8faef..6a5c2130da4b9f826f94a5b1ff2d68f2000d0989 100644
--- a/src/input/click.rs
+++ b/src/input/click.rs
@@ -56,7 +56,7 @@ pub fn focus_on_click(
 }
 
 /// Handles [`CosmicEditor`] widgets that are already focussed
-pub(super) fn handle_focussed_click(
+pub(super) fn handle_focused_click(
     trigger: Trigger<Pointer<Click>>,
     focused: Res<FocusedWidget>,
     mut editor: Query<(&mut InputState, &mut CosmicEditor, RelativeQuery)>,
@@ -113,11 +113,6 @@ pub(super) fn handle_focussed_click(
                 x: buffer_coord.x as i32,
                 y: buffer_coord.y as i32,
             });
-            // // select word
-            // editor.action(Action::Motion(Motion::LeftWord));
-            // let cursor = editor.cursor();
-            // editor.set_selection(Selection::Normal(cursor));
-            // editor.action(Action::Motion(Motion::RightWord));
         }
         ClickCount::Triple => {
             // selects line
@@ -125,11 +120,6 @@ pub(super) fn handle_focussed_click(
                 x: buffer_coord.x as i32,
                 y: buffer_coord.y as i32,
             });
-            // // select paragraph
-            // editor.action(Action::Motion(Motion::ParagraphStart));
-            // let cursor = editor.cursor();
-            // editor.set_selection(Selection::Normal(cursor));
-            // editor.action(Action::Motion(Motion::ParagraphEnd));
         }
         ClickCount::MoreThanTriple => {
             // select all
diff --git a/src/input/cursor_visibility.rs b/src/input/cursor_visibility.rs
index ee23f30b7d5c1dc61009ebca9ddf6fdcf9260840..cee24764c357b1669b44fa3b6d8cb3f3b06673d8 100644
--- a/src/input/cursor_visibility.rs
+++ b/src/input/cursor_visibility.rs
@@ -7,17 +7,6 @@ use crate::prelude::*;
 
 use crate::input::CosmicTextChanged;
 
-// if text changedd
-// if !evr_text_changed.is_empty() {
-//     window.cursor_options.visible = false;
-// }
-
-// if pressing or moving mouse
-// if mouse_buttons.get_just_pressed().len() != 0 || !evr_mouse_motion.is_empty() {
-//     window.cursor_options.visible = true;
-// }
-//
-
 #[derive(SystemParam)]
 pub(crate) struct CursorVisibility<'w> {
     window: Single<'w, &'static mut Window, With<PrimaryWindow>>,
diff --git a/src/input/scroll.rs b/src/input/scroll.rs
index 5d77adf921aa7ce66a6bbad845b76c6554fe7800..6c676841ad0635685c336025d152e084a2daadb3 100644
--- a/src/input/scroll.rs
+++ b/src/input/scroll.rs
@@ -12,7 +12,7 @@ pub(crate) fn scroll(
     for (mut editor, scroll_enabled) in editor.iter_mut() {
         let mut editor = editor.borrow_with(font_system);
 
-        if scroll_enabled.should_scroll() {
+        if **scroll_enabled {
             for ev in scroll_evr.read() {
                 match ev.unit {
                     MouseScrollUnit::Line => {
diff --git a/src/password.rs b/src/password.rs
index 7aec85da6c606be6a07cd1b3aed80dc384076219..cbd93735a4818fa4ca1184401c51a5b49123fc15 100644
--- a/src/password.rs
+++ b/src/password.rs
@@ -5,32 +5,28 @@ use crate::{
 use cosmic_text::{Cursor, Edit, Selection, Shaping};
 use unicode_segmentation::UnicodeSegmentation;
 
-pub(crate) struct PasswordPlugin;
-
 /// System set for password blocking systems. Runs in [`PostUpdate`]
 #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
 pub(crate) struct PasswordSet;
 
-impl Plugin for PasswordPlugin {
-    fn build(&self, app: &mut App) {
-        app.add_systems(
-            PreUpdate,
-            (hide_password_text.before(crate::input::InputSet),),
-        )
-        .add_systems(
-            Update,
-            (restore_password_text
-                .before(crate::input::keyboard::kb_input_text)
-                .after(crate::input::keyboard::kb_move_cursor),),
-        )
-        .add_systems(
-            PostUpdate,
-            (
-                hide_password_text.before(RenderSet).in_set(PasswordSet),
-                restore_password_text.before(FocusSet).after(RenderSet),
-            ),
-        );
-    }
+pub(crate) fn plugin(app: &mut App) {
+    app.add_systems(
+        PreUpdate,
+        (hide_password_text.before(crate::input::InputSet),),
+    )
+    .add_systems(
+        Update,
+        (restore_password_text
+            .before(crate::input::keyboard::kb_input_text)
+            .after(crate::input::keyboard::kb_move_cursor),),
+    )
+    .add_systems(
+        PostUpdate,
+        (
+            hide_password_text.before(RenderSet).in_set(PasswordSet),
+            restore_password_text.before(FocusSet).after(RenderSet),
+        ),
+    );
 }
 
 /// Component to be added to an entity with a [`CosmicEditBuffer`] to block contents with a
diff --git a/src/placeholder.rs b/src/placeholder.rs
index 2aca3412523df4c79c5a93998da81388a14b6a43..2038b7cfb3e5529d7e84ddd741542c2d29cc1d6e 100644
--- a/src/placeholder.rs
+++ b/src/placeholder.rs
@@ -52,23 +52,19 @@ impl Placeholder {
     }
 }
 
-pub(crate) struct PlaceholderPlugin;
-
-impl Plugin for PlaceholderPlugin {
-    fn build(&self, app: &mut App) {
-        app.add_systems(
-            Update,
-            (
-                add_placeholder_to_buffer,
-                add_placeholder_to_editor,
-                move_cursor_to_start_of_placeholder,
-                remove_placeholder_on_input,
-            )
-                .chain()
-                .after(InputSet)
-                .before(RenderSet),
-        );
-    }
+pub(crate) fn plugin(app: &mut App) {
+    app.add_systems(
+        Update,
+        (
+            add_placeholder_to_buffer,
+            add_placeholder_to_editor,
+            move_cursor_to_start_of_placeholder,
+            remove_placeholder_on_input,
+        )
+            .chain()
+            .after(InputSet)
+            .before(RenderSet),
+    );
 }
 
 fn add_placeholder_to_buffer(
diff --git a/src/primary.rs b/src/primary.rs
index 502591fcbd5c22c9906738c8e9f8cd3509bb2bcd..1838ec6120315eec9cf70f2b40d3992e1843f2e7 100644
--- a/src/primary.rs
+++ b/src/primary.rs
@@ -17,14 +17,13 @@ impl Plugin for CosmicEditPlugin {
 
         app.add_plugins((
             crate::cosmic_edit::plugin,
-            // crate::buffer::BufferPlugin,
-            crate::editor_buffer::EditorBufferPlugin,
-            crate::render::RenderPlugin,
-            crate::input::InputPlugin,
-            crate::focus::FocusPlugin,
-            crate::placeholder::PlaceholderPlugin,
-            crate::password::PasswordPlugin,
-            crate::user_select::UserSelectPlugin,
+            crate::editor_buffer::plugin,
+            crate::render::plugin,
+            crate::input::plugin,
+            crate::focus::plugin,
+            crate::placeholder::plugin,
+            crate::password::plugin,
+            crate::user_select::plugin,
             crate::double_click::plugin,
         ))
         // TODO: Use the builtin bevy CosmicFontSystem
@@ -42,7 +41,7 @@ impl Plugin for CosmicEditPlugin {
 pub struct CosmicFontConfig {
     pub fonts_dir_path: Option<PathBuf>,
     pub font_bytes: Option<Vec<&'static [u8]>>,
-    /// If [false], some characters (esspecially Unicode emojies) might not load properly
+    /// If [false], some characters (esspecially Unicode emoji) might not load properly
     /// Caution: this can be relatively slow
     pub load_system_fonts: bool,
 }
@@ -64,7 +63,7 @@ impl Default for CosmicFontConfig {
 pub(crate) struct CosmicRenderOutput(pub(crate) Handle<Image>);
 
 /// Without this, multiple buffers will show the same image
-/// as the focussed editor. IDK why
+/// as the focused editor.
 fn new_image_from_default(
     mut world: DeferredWorld,
     entity: Entity,
diff --git a/src/render.rs b/src/render.rs
index 9bb245d00823777e3765b028881ecb3ce798f2d6..0fc27e3c886ccdd3e8cf33496114882bfad14bd5 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -8,23 +8,12 @@ use render_implementations::CosmicWidgetSize;
 #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
 pub(crate) struct RenderSet;
 
-pub(crate) struct RenderPlugin;
-
-impl Plugin for RenderPlugin {
-    fn build(&self, app: &mut App) {
-        if !app.world().contains_resource::<SwashCache>() {
-            app.insert_resource(SwashCache::default());
-        } else {
-            debug!(
-                "Skipping inserting `SwashCache` resource as bevy has already inserted it for us"
-            );
-        }
-        app.add_systems(
-            First,
-            update_internal_target_handles.pipe(render_implementations::debug_error),
-        )
-        .add_systems(PostUpdate, (render_texture,).in_set(RenderSet));
-    }
+pub(crate) fn plugin(app: &mut App) {
+    app.add_systems(
+        First,
+        update_internal_target_handles.pipe(render_implementations::debug_error),
+    )
+    .add_systems(PostUpdate, (render_texture,).in_set(RenderSet));
 }
 
 /// Every frame updates the output (in [`CosmicRenderOutput`]) to its receiver
@@ -256,6 +245,7 @@ fn render_texture(
             }
         };
 
+        // BUG: overflow when using center/right/end aligned infinite wrap
         editor.set_size(
             font_system,
             Some(match wrap {
@@ -340,8 +330,7 @@ fn render_texture(
             //     );
             // }
 
-            // TODO: Performance optimization, read all possible render-input
-            // changes and only redraw if necessary
+            // PERF: Read all possible render-input changes and only redraw if necessary
             // editor.set_redraw(false);
         } else {
             // todo: performance optimizations (see comments above/below)
@@ -359,8 +348,7 @@ fn render_texture(
                 draw_closure,
             );
 
-            // TODO: Performance optimization, read all possible render-input
-            // changes and only redraw if necessary
+            // PERF: Read all possible render-input changes and only redraw if necessary
             // buffer.set_redraw(false);
         }
 
diff --git a/src/user_select.rs b/src/user_select.rs
index af9e69e215d6043b5e61f67b2e2c38bf5e236cf5..7e0471770988f9ac28a567bcf7bc3180223fda7d 100644
--- a/src/user_select.rs
+++ b/src/user_select.rs
@@ -1,12 +1,8 @@
 use crate::{input::InputSet, prelude::*};
 use cosmic_text::Edit;
 
-pub(crate) struct UserSelectPlugin;
-
-impl Plugin for UserSelectPlugin {
-    fn build(&self, app: &mut App) {
-        app.add_systems(Update, clear_selection.after(InputSet));
-    }
+pub(crate) fn plugin(app: &mut App) {
+    app.add_systems(Update, clear_selection.after(InputSet));
 }
 
 /// Tag component to disable user selection
diff --git a/src/utils.rs b/src/utils.rs
index 440407cb6f0ff8cba3b9ad0650b04b7da8914e64..8c13bd23dc39bc880024ba4030f92977474883a5 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -51,7 +51,7 @@ pub fn print_editor_text(
             return;
         }
         previous_value.clone_from(&current_text);
-        info!("Widget text: {:?}", current_text);
+        debug!("Widget text: {:?}", current_text);
     }
 }