diff --git a/examples/every_option.rs b/examples/every_option.rs
index 83385a4d6aeca2e1d0ef7cd9d130715a18e90ec0..3020213771d60d3e09d76e3f4bd4099ec7fbf58f 100644
--- a/examples/every_option.rs
+++ b/examples/every_option.rs
@@ -1,10 +1,10 @@
 use bevy::{prelude::*, ui::FocusPolicy, window::PrimaryWindow};
 use bevy_cosmic_edit::{
-    change_active_editor_sprite, change_active_editor_ui, ActiveEditor, CosmicAttrs,
-    CosmicBackground, CosmicEditPlugin, CosmicEditUiBundle, CosmicMaxChars, CosmicMaxLines,
-    CosmicMetrics, CosmicText, CosmicTextPosition,
+    change_active_editor_sprite, change_active_editor_ui, get_x_offset, ActiveEditor, CosmicAttrs,
+    CosmicBackground, CosmicEditPlugin, CosmicEditUiBundle, CosmicEditor, CosmicMaxChars,
+    CosmicMaxLines, CosmicMetrics, CosmicText, CosmicTextPosition,
 };
-use cosmic_text::{Attrs, AttrsOwned};
+use cosmic_text::{Attrs, AttrsOwned, Edit};
 
 #[derive(Resource)]
 struct TextChangeTimer(pub Timer);
@@ -25,7 +25,6 @@ fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) {
             image: UiImage::default(),
             transform: Transform::default(),
             interaction: Interaction::default(),
-            cosmic_edit_history: bevy_cosmic_edit::CosmicEditHistory::default(),
             focus_policy: FocusPolicy::default(),
             text_position: CosmicTextPosition::default(),
             background_color: BackgroundColor::default(),
@@ -69,6 +68,7 @@ fn text_swapper(
     time: Res<Time>,
     mut cosmic_q: Query<&mut CosmicText>,
     mut count: Local<usize>,
+    editor_q: Query<&CosmicEditor>,
 ) {
     timer.0.tick(time.delta());
     if !timer.0.just_finished() {
@@ -79,6 +79,9 @@ fn text_swapper(
     for mut text in cosmic_q.iter_mut() {
         text.set_if_neq(CosmicText::OneStyle(format!("TIMER {}", *count)));
     }
+
+    let editor = editor_q.single();
+    println!("X OFFSET: {}", get_x_offset(editor.0.buffer()));
 }
 
 fn main() {
diff --git a/src/lib.rs b/src/lib.rs
index 4ffbc8523b4d4254f3e504f0bf86456301f68cae..ced2651f147c03f37964bf085ce87dc7c3794457 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -187,6 +187,9 @@ fn cosmic_editor_builder(
         editor_component.set_text(text, attrs.0.clone(), &mut font_system.0);
 
         commands.entity(entity).insert(editor_component);
+
+        // Add edit history
+        commands.entity(entity).insert(CosmicEditHistory::default());
     }
 }
 
@@ -269,8 +272,6 @@ pub struct CosmicEditUiBundle {
     pub text_position: CosmicTextPosition,
     /// text metrics
     pub cosmic_metrics: CosmicMetrics,
-    /// edit history
-    pub cosmic_edit_history: CosmicEditHistory,
     /// text attributes
     pub cosmic_attrs: CosmicAttrs,
     /// bg img
@@ -284,87 +285,6 @@ pub struct CosmicEditUiBundle {
     pub set_text: CosmicText,
 }
 
-fn trim_text(text: CosmicText, max_chars: usize, max_lines: usize) -> CosmicText {
-    if max_chars == 0 && max_lines == 0 {
-        // no limits, no work to do
-        return text;
-    }
-
-    match text {
-        CosmicText::OneStyle(mut string) => {
-            string.truncate(max_chars);
-
-            if max_lines == 0 {
-                return CosmicText::OneStyle(string);
-            }
-
-            let mut line_acc = 0;
-            let mut char_pos = 0;
-            for c in string.chars() {
-                char_pos += 1;
-                if c == 0xA as char {
-                    line_acc += 1;
-                    if line_acc >= max_lines {
-                        // break text to pos
-                        string.truncate(char_pos);
-                        break;
-                    }
-                }
-            }
-
-            CosmicText::OneStyle(string)
-        }
-        CosmicText::MultiStyle(lines) => {
-            let mut char_acc = 0;
-            let mut line_acc = 0;
-
-            let mut trimmed_styles = vec![];
-
-            for line in lines.iter() {
-                line_acc += 1;
-                char_acc += 1; // count newlines for consistent behaviour
-
-                if (line_acc >= max_lines && max_lines > 0)
-                    || (char_acc >= max_chars && max_chars > 0)
-                {
-                    break;
-                }
-
-                let mut strs = vec![];
-
-                for (string, attrs) in line.iter() {
-                    if char_acc >= max_chars && max_chars > 0 {
-                        break;
-                    }
-
-                    let mut string = string.clone();
-
-                    if max_chars > 0 {
-                        string.truncate(max_chars - char_acc);
-                        char_acc += string.len();
-                    }
-
-                    if max_lines > 0 {
-                        for c in string.chars() {
-                            if c == 0xA as char {
-                                line_acc += 1;
-                                char_acc += 1; // count newlines for consistent behaviour
-                                if line_acc >= max_lines {
-                                    break;
-                                }
-                            }
-                        }
-                    }
-
-                    strs.push((string, attrs.clone()));
-                }
-                trimmed_styles.push(strs);
-            }
-            CosmicText::MultiStyle(trimmed_styles)
-        }
-    }
-}
-
 impl Default for CosmicEditUiBundle {
     fn default() -> Self {
         Self {
@@ -383,7 +303,6 @@ impl Default for CosmicEditUiBundle {
             z_index: Default::default(),
             text_position: Default::default(),
             cosmic_metrics: Default::default(),
-            cosmic_edit_history: Default::default(),
             cosmic_attrs: Default::default(),
             background_image: Default::default(),
             max_lines: Default::default(),
@@ -411,8 +330,6 @@ pub struct CosmicEditSpriteBundle {
     pub text_position: CosmicTextPosition,
     /// text metrics
     pub cosmic_metrics: CosmicMetrics,
-    /// edit history
-    pub cosmic_edit_history: CosmicEditHistory,
     /// text attributes
     pub cosmic_attrs: CosmicAttrs,
     /// bg img
@@ -436,7 +353,6 @@ impl Default for CosmicEditSpriteBundle {
             background_color: Default::default(),
             text_position: Default::default(),
             cosmic_metrics: Default::default(),
-            cosmic_edit_history: Default::default(),
             cosmic_attrs: Default::default(),
             background_image: Default::default(),
             max_lines: Default::default(),
@@ -447,13 +363,13 @@ impl Default for CosmicEditSpriteBundle {
 }
 
 #[derive(Clone)]
-pub struct EditHistoryItem {
+struct EditHistoryItem {
     pub cursor: Cursor,
     pub lines: Vec<Vec<(String, AttrsOwned)>>,
 }
 
 #[derive(Component, Default)]
-pub struct CosmicEditHistory {
+struct CosmicEditHistory {
     pub edits: VecDeque<EditHistoryItem>,
     pub current_edit: usize,
 }
@@ -523,6 +439,87 @@ struct SwashCacheState {
     swash_cache: SwashCache,
 }
 
+fn trim_text(text: CosmicText, max_chars: usize, max_lines: usize) -> CosmicText {
+    if max_chars == 0 && max_lines == 0 {
+        // no limits, no work to do
+        return text;
+    }
+
+    match text {
+        CosmicText::OneStyle(mut string) => {
+            string.truncate(max_chars);
+
+            if max_lines == 0 {
+                return CosmicText::OneStyle(string);
+            }
+
+            let mut line_acc = 0;
+            let mut char_pos = 0;
+            for c in string.chars() {
+                char_pos += 1;
+                if c == 0xA as char {
+                    line_acc += 1;
+                    if line_acc >= max_lines {
+                        // break text to pos
+                        string.truncate(char_pos);
+                        break;
+                    }
+                }
+            }
+
+            CosmicText::OneStyle(string)
+        }
+        CosmicText::MultiStyle(lines) => {
+            let mut char_acc = 0;
+            let mut line_acc = 0;
+
+            let mut trimmed_styles = vec![];
+
+            for line in lines.iter() {
+                line_acc += 1;
+                char_acc += 1; // count newlines for consistent behaviour
+
+                if (line_acc >= max_lines && max_lines > 0)
+                    || (char_acc >= max_chars && max_chars > 0)
+                {
+                    break;
+                }
+
+                let mut strs = vec![];
+
+                for (string, attrs) in line.iter() {
+                    if char_acc >= max_chars && max_chars > 0 {
+                        break;
+                    }
+
+                    let mut string = string.clone();
+
+                    if max_chars > 0 {
+                        string.truncate(max_chars - char_acc);
+                        char_acc += string.len();
+                    }
+
+                    if max_lines > 0 {
+                        for c in string.chars() {
+                            if c == 0xA as char {
+                                line_acc += 1;
+                                char_acc += 1; // count newlines for consistent behaviour
+                                if line_acc >= max_lines {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    strs.push((string, attrs.clone()));
+                }
+                trimmed_styles.push(strs);
+            }
+            CosmicText::MultiStyle(trimmed_styles)
+        }
+    }
+}
+
 fn create_cosmic_font_system(cosmic_font_config: CosmicFontConfig) -> FontSystem {
     let locale = sys_locale::get_locale().unwrap_or_else(|| String::from("en-US"));
     let mut db = cosmic_text::fontdb::Database::new();
@@ -688,7 +685,7 @@ pub fn get_x_offset(buffer: &Buffer) -> i32 {
 
 #[allow(clippy::too_many_arguments, clippy::type_complexity)]
 // the meat of the input management
-pub fn cosmic_edit_bevy_events(
+fn cosmic_edit_bevy_events(
     windows: Query<&Window, With<PrimaryWindow>>,
     active_editor: Res<ActiveEditor>,
     keys: Res<Input<KeyCode>>,