diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -11,10 +11,6 @@
 
 [the pragmas section]: #pragmas
 
-To run Gild in CI, consider using [cabal-gild-setup-action][].
-
-[cabal-gild-setup-action]: https://github.com/tfausak/cabal-gild-setup-action
-
 Gild started as a fork of [phadej/cabal-fmt][], but is now totally separate.
 For a brief summary of the differences between Gild and `cabal-fmt`, read [the
 announcement post][].
@@ -96,6 +92,10 @@
 Go to [the latest release page][] and download the binary for your platform.
 
 [the latest release page]: https://github.com/tfausak/cabal-gild/releases/latest
+
+To run Gild in a GitHub Actions workflow, consider using [cabal-gild-setup-action][].
+
+[cabal-gild-setup-action]: https://github.com/marketplace/actions/setup-gild
 
 ### From Source
 
diff --git a/cabal-gild.cabal b/cabal-gild.cabal
--- a/cabal-gild.cabal
+++ b/cabal-gild.cabal
@@ -11,7 +11,7 @@
 maintainer: Taylor Fausak
 name: cabal-gild
 synopsis: Formats package descriptions.
-version: 1.0.2.1
+version: 1.0.2.2
 
 source-repository head
   type: git
@@ -102,6 +102,7 @@
     CabalGild.Type.Config
     CabalGild.Type.Dependency
     CabalGild.Type.ExeDependency
+    CabalGild.Type.Extension
     CabalGild.Type.Flag
     CabalGild.Type.ForeignLibOption
     CabalGild.Type.Language
diff --git a/source/library/CabalGild/Action/FormatFields.hs b/source/library/CabalGild/Action/FormatFields.hs
--- a/source/library/CabalGild/Action/FormatFields.hs
+++ b/source/library/CabalGild/Action/FormatFields.hs
@@ -7,6 +7,7 @@
 import qualified CabalGild.Extra.String as String
 import qualified CabalGild.Type.Dependency as Dependency
 import qualified CabalGild.Type.ExeDependency as ExeDependency
+import qualified CabalGild.Type.Extension as Extension
 import qualified CabalGild.Type.ForeignLibOption as ForeignLibOption
 import qualified CabalGild.Type.Language as Language
 import qualified CabalGild.Type.LegacyExeDependency as LegacyExeDependency
@@ -22,7 +23,6 @@
 import qualified Distribution.ModuleName as ModuleName
 import qualified Distribution.Parsec as Parsec
 import qualified Distribution.Types.Mixin as Mixin
-import qualified Language.Haskell.Extension as Extension
 import qualified Text.PrettyPrint as PrettyPrint
 
 -- | A wrapper around 'field' to allow this to be composed with other actions.
diff --git a/source/library/CabalGild/Type/Extension.hs b/source/library/CabalGild/Type/Extension.hs
new file mode 100644
--- /dev/null
+++ b/source/library/CabalGild/Type/Extension.hs
@@ -0,0 +1,36 @@
+module CabalGild.Type.Extension where
+
+import qualified Data.Char as Char
+import qualified Data.Ord as Ord
+import qualified Distribution.Parsec as Parsec
+import qualified Distribution.Pretty as Pretty
+import qualified Language.Haskell.Extension as Extension
+
+-- | This type exists to provide a different 'Ord' instance for
+-- 'Extension.Extension'. The instance provided by @Cabal-syntax@ sorts things
+-- in a surprising order. This one sorts things alphabetically with "enable"
+-- extensions before "disable" ones.
+newtype Extension = Extension
+  { unwrap :: Extension.Extension
+  }
+  deriving (Eq, Show)
+
+instance Ord Extension where
+  compare = Ord.comparing $ \e -> (isDisable $ unwrap e, Pretty.prettyShow e)
+
+instance Parsec.Parsec Extension where
+  parsec = Extension <$> Parsec.parsec
+
+instance Pretty.Pretty Extension where
+  pretty = Pretty.pretty . unwrap
+
+-- | Returns 'True' if the given extension is either a
+-- 'Extension.DisableExtension' or it's an 'Extension.UnknownExtension' that
+-- starts with @"No"@ followed by an uppercase letter.
+isDisable :: Extension.Extension -> Bool
+isDisable e = case e of
+  Extension.EnableExtension _ -> False
+  Extension.DisableExtension _ -> True
+  Extension.UnknownExtension s -> case s of
+    'N' : 'o' : c : _ -> Char.isUpper c
+    _ -> False
diff --git a/source/test-suite/Main.hs b/source/test-suite/Main.hs
--- a/source/test-suite/Main.hs
+++ b/source/test-suite/Main.hs
@@ -563,6 +563,31 @@
       "library\n default-extensions: b a"
       "library\n  default-extensions:\n    a\n    b\n"
 
+  Hspec.it "sorts known extensions by name" $ do
+    expectGilded
+      "library\n default-extensions: DerivingVia BlockArguments"
+      "library\n  default-extensions:\n    BlockArguments\n    DerivingVia\n"
+
+  Hspec.it "sorts disabling extensions after enabling ones" $ do
+    expectGilded
+      "library\n default-extensions: NoStrictData StrictData"
+      "library\n  default-extensions:\n    StrictData\n    NoStrictData\n"
+
+  Hspec.it "sorts unknown extensions with known ones" $ do
+    expectGilded
+      "library\n default-extensions: LambdaCase Imaginary"
+      "library\n  default-extensions:\n    Imaginary\n    LambdaCase\n"
+
+  Hspec.it "sorts unknown disabling extensions with known ones" $ do
+    expectGilded
+      "library\n default-extensions: NoLambdaCase NoImaginary"
+      "library\n  default-extensions:\n    NoImaginary\n    NoLambdaCase\n"
+
+  Hspec.it "sorts extensions (issue 29)" $ do
+    expectGilded
+      "library\n default-extensions: Arrows Imaginary1 NoCPP NoImaginary2 NoUnboxedTuples UnicodeSyntax"
+      "library\n  default-extensions:\n    Arrows\n    Imaginary1\n    UnicodeSyntax\n    NoCPP\n    NoImaginary2\n    NoUnboxedTuples\n"
+
   Hspec.it "sorts other-extensions" $ do
     expectGilded
       "library\n other-extensions: b a"
