diff --git a/Cargo.toml b/Cargo.toml
index 28a773b..55a45f8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,6 +16,7 @@ coveralls = { repository = "rust-lang/annotate-snippets-rs", branch = "master",
 maintenance = { status = "actively-developed" }
 
 [dependencies]
+unicode-width = "0.1"
 yansi-term = { version = "0.1", optional = true }
 
 [dev-dependencies]
diff --git a/README.md b/README.md
index 592a51e..f80d659 100644
--- a/README.md
+++ b/README.md
@@ -35,49 +35,47 @@ Usage
 
 ```rust
 use annotate_snippets::{
-    display_list::DisplayList,
-    formatter::DisplayListFormatter,
+    display_list::{DisplayList, FormatOptions},
     snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
 };
 
 fn main() {
     let snippet = Snippet {
         title: Some(Annotation {
-            label: Some("expected type, found `22`".to_string()),
+            label: Some("expected type, found `22`"),
             id: None,
             annotation_type: AnnotationType::Error,
         }),
         footer: vec![],
-        slices: vec![
-            Slice {
-                source: r#"
-This is an example
-content of the slice
-which will be annotated
-with the list of annotations below.
-                "#.to_string(),
-                line_start: 26,
-                origin: Some("examples/example.txt".to_string()),
-                fold: false,
-                annotations: vec![
-                    SourceAnnotation {
-                        label: "Example error annotation".to_string(),
-                        annotation_type: AnnotationType::Error,
-                        range: (13, 18),
-                    },
-                    SourceAnnotation {
-                        label: "and here's a warning".to_string(),
-                        annotation_type: AnnotationType::Warning,
-                        range: (34, 50),
-                    },
-                ],
-            },
-        ],
+        slices: vec![Slice {
+            source: r#"                annotations: vec![SourceAnnotation {
+                label: "expected struct `annotate_snippets::snippet::Slice`, found reference"
+                    ,
+                range: <22, 25>,"#,
+            line_start: 26,
+            origin: Some("examples/footer.rs"),
+            fold: true,
+            annotations: vec![
+                SourceAnnotation {
+                    label: "",
+                    annotation_type: AnnotationType::Error,
+                    range: (205, 207),
+                },
+                SourceAnnotation {
+                    label: "while parsing this struct",
+                    annotation_type: AnnotationType::Info,
+                    range: (34, 50),
+                },
+            ],
+        }],
+        opt: FormatOptions {
+            color: true,
+            ..Default::default()
+        },
     };
 
     let dl = DisplayList::from(snippet);
-    let dlf = DisplayListFormatter::new(true, false);
-    println!("{}", dlf.format(&dl));
+    println!("{}", dl);
 }
 ```
 
diff --git a/src/display_list/from_snippet.rs b/src/display_list/from_snippet.rs
index da0deea..d32d1e0 100644
--- a/src/display_list/from_snippet.rs
+++ b/src/display_list/from_snippet.rs
@@ -107,12 +107,13 @@ fn format_slice(
     slice: snippet::Slice<'_>,
     is_first: bool,
     has_footer: bool,
+    margin: Option<Margin>,
 ) -> Vec<DisplayLine<'_>> {
     let main_range = slice.annotations.get(0).map(|x| x.range.0);
     let origin = slice.origin;
     let line_start = slice.line_start;
     let need_empty_header = origin.is_some() || is_first;
-    let mut body = format_body(slice, need_empty_header, has_footer);
+    let mut body = format_body(slice, need_empty_header, has_footer, margin);
     let header = format_header(origin, main_range, line_start, &body, is_first);
     let mut result = vec![];
 
@@ -273,6 +274,7 @@ fn format_body(
     slice: snippet::Slice<'_>,
     need_empty_header: bool,
     has_footer: bool,
+    margin: Option<Margin>,
 ) -> Vec<DisplayLine<'_>> {
     let source_len = slice.source.chars().count();
     if let Some(bigger) = slice.annotations.iter().find_map(|x| {
@@ -312,6 +314,9 @@ fn format_body(
     let mut annotation_line_count = 0;
     let mut annotations = slice.annotations;
     for (idx, (line_start, line_end)) in line_index_ranges.into_iter().enumerate() {
+        let margin_left = margin
+            .map(|m| m.left(line_end - line_start))
+            .unwrap_or_default();
         // It would be nice to use filter_drain here once it's stable.
         annotations = annotations
             .into_iter()
@@ -328,7 +333,10 @@ fn format_body(
                         if start >= line_start && end <= line_end
                             || start == line_end && end - start <= 1 =>
                     {
-                        let range = (start - line_start, end - line_start);
+                        let range = (
+                            (start - line_start) - margin_left,
+                            (end - line_start) - margin_left,
+                        );
                         body.insert(
                             body_idx + 1,
                             DisplayLine::Source {
@@ -419,7 +427,10 @@ fn format_body(
                             });
                         }
 
-                        let range = (end - line_start, end - line_start + 1);
+                        let range = (
+                            (end - line_start) - margin_left,
+                            (end - line_start + 1) - margin_left,
+                        );
                         body.insert(
                             body_idx + 1,
                             DisplayLine::Source {
@@ -499,7 +510,12 @@ impl<'a> From<snippet::Snippet<'a>> for DisplayList<'a> {
         }
 
         for (idx, slice) in slices.into_iter().enumerate() {
-            body.append(&mut format_slice(slice, idx == 0, !footer.is_empty()));
+            body.append(&mut format_slice(
+                slice,
+                idx == 0,
+                !footer.is_empty(),
+                opt.margin,
+            ));
         }
 
         for annotation in footer {
@@ -509,12 +525,14 @@ impl<'a> From<snippet::Snippet<'a>> for DisplayList<'a> {
         let FormatOptions {
             color,
             anonymized_line_numbers,
+            margin,
         } = opt;
 
         Self {
             body,
             stylesheet: get_term_style(color),
             anonymized_line_numbers,
+            margin,
         }
     }
 }
diff --git a/src/display_list/structs.rs b/src/display_list/structs.rs
index 8f6d8fc..7941d5f 100644
--- a/src/display_list/structs.rs
+++ b/src/display_list/structs.rs
@@ -1,3 +1,4 @@
+use std::cmp::{max, min};
 use std::fmt;
 
 use crate::formatter::{get_term_style, style::Stylesheet};
@@ -7,6 +8,7 @@ pub struct DisplayList<'a> {
     pub body: Vec<DisplayLine<'a>>,
     pub stylesheet: Box<dyn Stylesheet>,
     pub anonymized_line_numbers: bool,
+    pub margin: Option<Margin>,
 }
 
 impl<'a> From<Vec<DisplayLine<'a>>> for DisplayList<'a> {
@@ -15,6 +17,7 @@ impl<'a> From<Vec<DisplayLine<'a>>> for DisplayList<'a> {
             body,
             anonymized_line_numbers: false,
             stylesheet: get_term_style(false),
+            margin: None,
         }
     }
 }
@@ -38,6 +41,121 @@ impl<'a> fmt::Debug for DisplayList<'a> {
 pub struct FormatOptions {
     pub color: bool,
     pub anonymized_line_numbers: bool,
+    pub margin: Option<Margin>,
+}
+
+#[derive(Clone, Copy, Debug)]
+pub struct Margin {
+    /// The available whitespace in the left that can be consumed when centering.
+    whitespace_left: usize,
+    /// The column of the beginning of left-most span.
+    span_left: usize,
+    /// The column of the end of right-most span.
+    span_right: usize,
+    /// The beginning of the line to be displayed.
+    computed_left: usize,
+    /// The end of the line to be displayed.
+    computed_right: usize,
+    /// The current width of the terminal. 140 by default and in tests.
+    column_width: usize,
+    /// The end column of a span label, including the span. Doesn't account for labels not in the
+    /// same line as the span.
+    label_right: usize,
+}
+
+impl Margin {
+    pub fn new(
+        whitespace_left: usize,
+        span_left: usize,
+        span_right: usize,
+        label_right: usize,
+        column_width: usize,
+        max_line_len: usize,
+    ) -> Self {
+        // The 6 is padding to give a bit of room for `...` when displaying:
+        // ```
+        // error: message
+        //   --> file.rs:16:58
+        //    |
+        // 16 | ... fn foo(self) -> Self::Bar {
+        //    |                     ^^^^^^^^^
+        // ```
+
+        let mut m = Margin {
+            whitespace_left: whitespace_left.saturating_sub(6),
+            span_left: span_left.saturating_sub(6),
+            span_right: span_right + 6,
+            computed_left: 0,
+            computed_right: 0,
+            column_width,
+            label_right: label_right + 6,
+        };
+        m.compute(max_line_len);
+        m
+    }
+
+    pub(crate) fn was_cut_left(&self) -> bool {
+        self.computed_left > 0
+    }
+
+    pub(crate) fn was_cut_right(&self, line_len: usize) -> bool {
+        let right =
+            if self.computed_right == self.span_right || self.computed_right == self.label_right {
+                // Account for the "..." padding given above. Otherwise we end up with code lines that
+                // do fit but end in "..." as if they were trimmed.
+                self.computed_right - 6
+            } else {
+                self.computed_right
+            };
+        right < line_len && self.computed_left + self.column_width < line_len
+    }
+
+    fn compute(&mut self, max_line_len: usize) {
+        // When there's a lot of whitespace (>20), we want to trim it as it is useless.
+        self.computed_left = if self.whitespace_left > 20 {
+            self.whitespace_left - 16 // We want some padding.
+        } else {
+            0
+        };
+        // We want to show as much as possible, max_line_len is the right-most boundary for the
+        // relevant code.
+        self.computed_right = max(max_line_len, self.computed_left);
+
+        if self.computed_right - self.computed_left > self.column_width {
+            // Trimming only whitespace isn't enough, let's get craftier.
+            if self.label_right - self.whitespace_left <= self.column_width {
+                // Attempt to fit the code window only trimming whitespace.
+                self.computed_left = self.whitespace_left;
+                self.computed_right = self.computed_left + self.column_width;
+            } else if self.label_right - self.span_left <= self.column_width {
+                // Attempt to fit the code window considering only the spans and labels.
+                let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2;
+                self.computed_left = self.span_left.saturating_sub(padding_left);
+                self.computed_right = self.computed_left + self.column_width;
+            } else if self.span_right - self.span_left <= self.column_width {
+                // Attempt to fit the code window considering the spans and labels plus padding.
+                let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2;
+                self.computed_left = self.span_left.saturating_sub(padding_left);
+                self.computed_right = self.computed_left + self.column_width;
+            } else {
+                // Mostly give up but still don't show the full line.
+                self.computed_left = self.span_left;
+                self.computed_right = self.span_right;
+            }
+        }
+    }
+
+    pub(crate) fn left(&self, line_len: usize) -> usize {
+        min(self.computed_left, line_len)
+    }
+
+    pub(crate) fn right(&self, line_len: usize) -> usize {
+        if line_len.saturating_sub(self.computed_left) <= self.column_width {
+            line_len
+        } else {
+            min(line_len, self.computed_right)
+        }
+    }
 }
 
 /// Inline annotation which can be used in either Raw or Source line.
@@ -162,8 +280,7 @@ pub enum DisplayMarkType {
 
 /// A type of the `Annotation` which may impact the sigils, style or text displayed.
 ///
-/// There are several ways in which the `DisplayListFormatter` uses this information
-/// when formatting the `DisplayList`:
+/// There are several ways to uses this information when formatting the `DisplayList`:
 ///
 /// * An annotation may display the name of the type like `error` or `info`.
 /// * An underline for `Error` may be `^^^` while for `Warning` it coule be `---`.
diff --git a/src/formatter/mod.rs b/src/formatter/mod.rs
index e93aeb3..ed31b86 100644
--- a/src/formatter/mod.rs
+++ b/src/formatter/mod.rs
@@ -198,7 +198,56 @@ impl<'a> DisplayList<'a> {
             DisplaySourceLine::Empty => Ok(()),
             DisplaySourceLine::Content { text, .. } => {
                 f.write_char(' ')?;
-                text.fmt(f)
+                if let Some(margin) = self.margin {
+                    let line_len = text.chars().count();
+                    let mut left = margin.left(line_len);
+                    let right = margin.right(line_len);
+
+                    if margin.was_cut_left() {
+                        // We have stripped some code/whitespace from the beginning, make it clear.
+                        "...".fmt(f)?;
+                        left += 3;
+                    }
+
+                    // On long lines, we strip the source line, accounting for unicode.
+                    let mut taken = 0;
+                    let cut_right = if margin.was_cut_right(line_len) {
+                        taken += 3;
+                        true
+                    } else {
+                        false
+                    };
+                    let range = text
+                        .char_indices()
+                        .skip(left)
+                        .take_while(|(_, ch)| {
+                            // Make sure that the trimming on the right will fall within the terminal width.
+                            // FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` is.
+                            // For now, just accept that sometimes the code line will be longer than desired.
+                            taken += unicode_width::UnicodeWidthChar::width(*ch).unwrap_or(1);
+                            if taken > right - left {
+                                return false;
+                            }
+                            true
+                        })
+                        .fold((None, 0), |acc, (i, _)| {
+                            if acc.0.is_some() {
+                                (acc.0, i)
+                            } else {
+                                (Some(i), i)
+                            }
+                        });
+
+                    text[range.0.expect("One character at line")..=range.1].fmt(f)?;
+
+                    if cut_right {
+                        // We have stripped some code after the right-most span end, make it clear we did so.
+                        "...".fmt(f)?;
+                    }
+                    Ok(())
+                } else {
+                    text.fmt(f)
+                }
             }
             DisplaySourceLine::Annotation {
                 range,
diff --git a/src/formatter/style.rs b/src/formatter/style.rs
index f76e6b0..3fc01c1 100644
--- a/src/formatter/style.rs
+++ b/src/formatter/style.rs
@@ -39,8 +39,7 @@ pub trait Style {
         c: Box<dyn FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result + 'a>,
         f: &mut fmt::Formatter<'_>,
     ) -> fmt::Result;
-    /// The method used by the DisplayListFormatter to display the message
-    /// in bold font.
+    /// The method used by the `Formatter` to display the message in bold font.
     fn bold(&self) -> Box<dyn Style>;
 }
 
diff --git a/src/lib.rs b/src/lib.rs
index 46b25e1..d581367 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -38,8 +38,7 @@
 //! of lines containing semantic information about each line.
 //! This structure is the easiest to manipulate and organize.
 //!
-//! Finally, [DisplayListFormatter](self::formatter::DisplayListFormatter) is
-//! used to format the `DisplayList` using a `Stylesheet` into a final `String` output.
+//! Finally, `impl Display` into a final `String` output.
 //!
 //! A user of the crate may choose to provide their own equivalent of the input
 //! structure with an `Into<DisplayList>` trait.
@@ -47,6 +46,7 @@
 //! A user of the crate may also choose to provide their own formatter logic,
 //! to convert a `DisplayList` into a `String`, or just a `Stylesheet` to
 //! use the crate's formatting logic, but with a custom stylesheet.
+// TODO: check documentation
 
 pub mod display_list;
 pub mod formatter;
diff --git a/src/stylesheets/mod.rs b/src/stylesheets/mod.rs
index 49f6ea0..4648852 100644
--- a/src/stylesheets/mod.rs
+++ b/src/stylesheets/mod.rs
@@ -1,4 +1,4 @@
-//! List of stylesheets that can be used by the `DisplayListFormatter`.
+//! List of stylesheets
 //!
 //! The list depends on what optional dependencies the crate has been
 //! compiled with.
diff --git a/tests/dl_from_snippet.rs b/tests/dl_from_snippet.rs
index 2ed9902..0dcfcfa 100644
--- a/tests/dl_from_snippet.rs
+++ b/tests/dl_from_snippet.rs
@@ -28,6 +28,7 @@ fn test_format_title() {
         })],
         stylesheet: get_term_style(input.opt.color),
         anonymized_line_numbers: input.opt.anonymized_line_numbers,
+        margin: None,
     };
     assert_eq!(dl::DisplayList::from(input), output);
 }
@@ -80,6 +81,7 @@ fn test_format_slice() {
         ],
         stylesheet: get_term_style(input.opt.color),
         anonymized_line_numbers: input.opt.anonymized_line_numbers,
+        margin: None,
     };
     assert_eq!(dl::DisplayList::from(input), output);
 }
@@ -162,6 +164,7 @@ fn test_format_slices_continuation() {
         ],
         stylesheet: get_term_style(input.opt.color),
         anonymized_line_numbers: input.opt.anonymized_line_numbers,
+        margin: None,
     };
     assert_eq!(dl::DisplayList::from(input), output);
 }
@@ -237,6 +240,7 @@ fn test_format_slice_annotation_standalone() {
         ],
         stylesheet: get_term_style(input.opt.color),
         anonymized_line_numbers: input.opt.anonymized_line_numbers,
+        margin: None,
     };
     assert_eq!(dl::DisplayList::from(input), output);
 }
@@ -278,6 +282,7 @@ fn test_format_label() {
         })],
         stylesheet: get_term_style(input.opt.color),
         anonymized_line_numbers: input.opt.anonymized_line_numbers,
+        margin: None,
     };
     assert_eq!(dl::DisplayList::from(input), output);
 }
@@ -395,6 +400,7 @@ fn test_i_29() {
         ],
         stylesheet: get_term_style(false),
         anonymized_line_numbers: false,
+        margin: None,
     };
 
     assert_eq!(DisplayList::from(snippets), expected);
diff --git a/tests/fixtures/no-color/strip_line.toml b/tests/fixtures/no-color/strip_line.toml
new file mode 100644
index 0000000..76d9519
--- /dev/null
+++ b/tests/fixtures/no-color/strip_line.toml
@@ -0,0 +1,25 @@
+[title]
+id = "E0308"
+label = "mismatched types"
+annotation_type = "Error"
+
+[[slices]]
+source = "                                                                                                                                                                                    let _: () = 42;"
+line_start = 4
+origin = "$DIR/whitespace-trimming.rs"
+
+[[slices.annotations]]
+label = "expected (), found integer"
+annotation_type = "Error"
+range = [192, 194]
+
+[opt]
+color = false
+anonymized_line_numbers = true
+[opt.margin]
+whitespace_left = 180
+span_left = 192
+span_right = 194
+label_right = 221
+column_width = 140
+max_line_len = 195
diff --git a/tests/fixtures/no-color/strip_line.txt b/tests/fixtures/no-color/strip_line.txt
new file mode 100644
index 0000000..65b0538
--- /dev/null
+++ b/tests/fixtures/no-color/strip_line.txt
@@ -0,0 +1,6 @@
+error[E0308]: mismatched types
+  --> $DIR/whitespace-trimming.rs:4:193
+   |
+LL | ...                   let _: () = 42;
+   |                                   ^^ expected (), found integer
+   |
diff --git a/tests/fixtures/no-color/strip_line_non_ws.toml b/tests/fixtures/no-color/strip_line_non_ws.toml
new file mode 100644
index 0000000..5129f5c
--- /dev/null
+++ b/tests/fixtures/no-color/strip_line_non_ws.toml
@@ -0,0 +1,25 @@
+[title]
+id = "E0308"
+label = "mismatched types"
+annotation_type = "Error"
+
+[[slices]]
+source = "    let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();"
+line_start = 4
+origin = "$DIR/non-whitespace-trimming.rs"
+
+[[slices.annotations]]
+label = "expected (), found integer"
+annotation_type = "Error"
+range = [240, 242]
+
+[opt]
+color = false
+anonymized_line_numbers = true
+[opt.margin]
+whitespace_left = 4
+span_left = 240
+span_right = 242
+label_right = 271
+column_width = 140
+max_line_len = 371
diff --git a/tests/fixtures/no-color/strip_line_non_ws.txt b/tests/fixtures/no-color/strip_line_non_ws.txt
new file mode 100644
index 0000000..850619a
--- /dev/null
+++ b/tests/fixtures/no-color/strip_line_non_ws.txt
@@ -0,0 +1,6 @@
+error[E0308]: mismatched types
+  --> $DIR/non-whitespace-trimming.rs:4:241
+   |
+LL | ... = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();...
+   |                                                       ^^ expected (), found integer
+   |
diff --git a/tests/snippet/mod.rs b/tests/snippet/mod.rs
index cc747a4..247c26d 100644
--- a/tests/snippet/mod.rs
+++ b/tests/snippet/mod.rs
@@ -1,7 +1,7 @@
 use serde::{Deserialize, Deserializer, Serialize};
 
 use annotate_snippets::{
-    display_list::FormatOptions,
+    display_list::{FormatOptions, Margin},
     snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
 };
 
@@ -57,6 +57,45 @@ pub struct FormatOptionsDef {
     pub color: bool,
     #[serde(default)]
     pub anonymized_line_numbers: bool,
+    #[serde(deserialize_with = "deserialize_margin")]
+    #[serde(default)]
+    pub margin: Option<Margin>,
+}
+
+fn deserialize_margin<'de, D>(deserializer: D) -> Result<Option<Margin>, D::Error>
+where
+    D: Deserializer<'de>,
+{
+    #[derive(Deserialize)]
+    struct Wrapper {
+        whitespace_left: usize,
+        span_left: usize,
+        span_right: usize,
+        label_right: usize,
+        column_width: usize,
+        max_line_len: usize,
+    };
+
+    Option::<Wrapper>::deserialize(deserializer).map(|opt_wrapped: Option<Wrapper>| {
+        opt_wrapped.map(|wrapped: Wrapper| {
+            let Wrapper {
+                whitespace_left,
+                span_left,
+                span_right,
+                label_right,
+                column_width,
+                max_line_len,
+            } = wrapped;
+            Margin::new(
+                whitespace_left,
+                span_left,
+                span_right,
+                label_right,
+                column_width,
+                max_line_len,
+            )
+        })
+    })
 }
 
 fn deserialize_slices<'de, D>(deserializer: D) -> Result<Vec<Slice<'de>>, D::Error>