diff --git a/Cabal/doc/cabaldomain.py b/Cabal/doc/cabaldomain.py
index 4f9a1bf4956d41f1e613798fdf06a203c5418980..18976e7bd494658a1ec2c407a7ed4b718ec1a5f1 100644
--- a/Cabal/doc/cabaldomain.py
+++ b/Cabal/doc/cabaldomain.py
@@ -6,14 +6,26 @@ from docutils.parsers.rst import Directive, directives, roles
 import pygments.lexer as lexer
 import pygments.token as token
 
+from distutils.version import StrictVersion
+
 from sphinx import addnodes
 from sphinx.directives import ObjectDescription
 from sphinx.domains import ObjType, Domain
 from sphinx.domains.std import StandardDomain
 from sphinx.locale import l_, _
 from sphinx.roles import XRefRole
+from sphinx.util.docfields import Field, DocFieldTransformer
 from sphinx.util.nodes import make_refnode
 
+def parse_deprecated(txt):
+    if txt is None:
+        return True
+    try:
+        return StrictVersion(txt)
+    except ValueError:
+        return True
+
+
 class CabalPackageSection(Directive):
     """
     Directive marks a package.cabal section described next
@@ -24,7 +36,10 @@ class CabalPackageSection(Directive):
     required_arguments = 1
     optional_arguments = 0
     final_argument_whitespace = True
-    option_spec = {}
+    option_spec = {
+        'deprecated': parse_deprecated,
+        'since' : StrictVersion
+    }
 
     def run(self):
         env = self.state.document.settings.env
@@ -43,27 +58,80 @@ class CabalPackageSection(Directive):
         inode = addnodes.index(entries=[('pair', indexentry,
                                          targetname, '', None)])
 
+        meta = Meta(since=self.options.get('since'),
+                    deprecated=self.options.get('deprecated'))
+
         env.domaindata['cabal']['pkg-sections'][section] = \
-            env.docname, targetname
+            env.docname, targetname, meta
 
         return [inode, node]
 
-class CabalPackageField(ObjectDescription):
+class Meta(object):
+    def __init__(self, since=None, deprecated=None):
+        self.since = since
+        self.deprecated = deprecated
+
+class CabalField(ObjectDescription):
+    option_spec = {
+        'noindex': directives.flag,
+        'deprecated': parse_deprecated,
+        'since' : StrictVersion
+    }
+
+    doc_field_types = [
+        Field('default', label='Default value', names=['default'], has_arg=False)
+    ]
+
+    def get_meta(self):
+        return Meta(since=self.options.get('since'),
+                    deprecated=self.options.get('deprecated'))
+
+    def get_index_entry(self, env, name):
+        return name, self.objtype + '-' + name
+
+    def get_env_key(self, env, name):
+        return self.name
+
     def handle_signature(self, sig, signode):
-        sig.strip()
+        sig = sig.strip()
         parts = sig.split(':',1)
         name = parts[0]
-        signode += addnodes.desc_name(name+':', name+':')
+        signode += addnodes.desc_name(name, name)
+        signode += addnodes.desc_name(':', ':')
 
         if len(parts) > 1:
-            rest = parts[1]
-            rest.strip()
-            signode += addnodes.desc_annotation(rest, rest)
+            rest = parts[1].strip()
+            signode += addnodes.desc_addname(rest, rest)
+
+        meta = self.get_meta()
+
+        rendered = render_meta(meta)
+        if rendered != '':
+            signode += addnodes.desc_annotation(' ' + rendered, ' '+rendered)
+
         return name
 
     def add_target_and_index(self, name, sig, signode):
         env = self.state.document.settings.env
 
+        indexentry, targetname = self.get_index_entry(self, name)
+
+        signode['ids'].append(targetname)
+        self.state.document.note_explicit_target(signode)
+
+        inode = addnodes.index(
+            entries=[('pair', indexentry, targetname, '', None)])
+        signode.insert(0, inode)
+
+        meta = Meta(since=self.options.get('since'),
+                    deprecated=self.options.get('deprecated'))
+         #for ref finding
+        key = self.get_env_key(env, name)
+        store = CabalDomain.types[self.objtype]
+        env.domaindata['cabal'][store][key] = env.docname, targetname, meta
+
+class CabalPackageField(CabalField):
+    def get_index_entry(self, env, name):
         section = self.env.ref_context.get('cabal:section')
 
         if section is not None:
@@ -74,29 +142,25 @@ class CabalPackageField(ObjectDescription):
             indexentry = name + '; package.cabal field'
 
         targetname = '-'.join(parts)
-        signode['ids'].append(targetname)
-        self.state.document.note_explicit_target(signode)
+        return indexentry, targetname
 
-        inode = addnodes.index(entries=[('pair', indexentry,
-                                         targetname, '', None)])
-        signode.insert(0, inode)
-
-        #for ref finding
-        env.domaindata['cabal']['pkg-fields'][section,name] = \
-            env.docname, targetname
+    def get_env_key(self, env, name):
+        section = env.ref_context.get('cabal:section')
+        return section, name
 
 class CabalPackageFieldXRef(XRefRole):
     def process_link(self, env, refnode, has_explicit_title, title, target):
         parts = target.split(':',1)
         if len(parts) == 2:
             section, target = parts
-            section.strip()
-            target.strip()
+            section = section.strip()
+            target = target.strip()
             refnode['cabal:section'] = section
         else:
             refnode['cabal:section'] = env.ref_context.get('cabal:section')
         return title, target
 
+
 def make_data_keys(typ, target, node):
     if typ == 'pkg-field':
         section = node.get('cabal:section')
@@ -104,18 +168,31 @@ def make_data_keys(typ, target, node):
     else:
         return [target]
 
-def make_title(typ, key):
+def render_meta(meta):
+    if meta.deprecated is not None:
+        if isinstance(meta.deprecated, StrictVersion):
+            return ' (deprecated since:'+str(meta.deprecated) + ')'
+        else:
+            return '(deprecated)'
+    elif meta.since is not None:
+        return ' (since version: ' + str(meta.since) + ')'
+    else:
+        return ''
+
+def make_title(typ, key, meta):
     if typ == 'pkg-section':
-        return "package.cabal " + key + "section"
+        return "package.cabal " + key + "section" + render_meta(meta)
 
     if typ == 'pkg-field':
         section, name = key
         if section is not None:
-            return "package.cabal " + section + " section " + name + " field"
+            base = "package.cabal " + section + " section " + name + " field"
         else:
-            return "package.cabal " + name + " field"
+            base = "package.cabal " + name + " field"
+
+        return base + render_meta(meta)
 
-def make_full_name(typ, key):
+def make_full_name(typ, key, meta):
     if typ == 'pkg-section':
         return 'pkg-section-' + key
 
@@ -142,7 +219,6 @@ class CabalDomain(Domain):
         'pkg-field'  : CabalPackageFieldXRef(warn_dangling=True),
     }
     initial_data = {
-        'objects': {},
         'pkg-sections': {},
         'pkg-fields': {},
     }
@@ -154,8 +230,8 @@ class CabalDomain(Domain):
         'pkg-field'  : 'pkg-fields'
     }
     def clear_doc(self, docname):
-        for k in ['objects', 'pkg-sections', 'pkg-fields']:
-            for name, (fn, _) in self.data[k].items():
+        for k in ['pkg-sections', 'pkg-fields']:
+            for name, (fn, _, _) in self.data[k].items():
                 if fn == docname:
                     del self.data[k][comname]
 
@@ -167,15 +243,15 @@ class CabalDomain(Domain):
                 data = env.domaindata['cabal'][self.types[typ]][key]
             except KeyError:
                 continue
-            doc, ref = data
-            title = make_title(typ, key)
+            doc, ref, meta = data
+            title = make_title(typ, key, meta)
             return make_refnode(builder, fromdocname, doc, ref, contnode, title)
 
     def get_objects(self):
         for typ in ['pkg-section', 'pkg-field']:
             key = self.types[typ]
-            for name, (fn, target) in self.data[key].items():
-                title = make_title(typ, name)
+            for name, (fn, target, meta) in self.data[key].items():
+                title = make_title(typ, name, meta)
                 yield title, title, typ, fn, target, 0
 
 class CabalLexer(lexer.RegexLexer):
@@ -186,15 +262,13 @@ class CabalLexer(lexer.RegexLexer):
 
     tokens = {
       'root' : [
-          (r'\n', token.Text),
-          (r'^\s*(--.*)$', token.Comment.Single),
+          (r'^(\s*)(--.*)$', lexer.bygroups(token.Whitespace, token.Comment.Single)),
           # key: value
           (r'^(\s*)([\w\-_]+)(:)',
            lexer.bygroups(token.Whitespace, token.Keyword, token.Punctuation)),
           (r'^([\w\-_]+)', token.Keyword), # library, executable, flag etc.
           (r'[^\S\n]+', token.Text),
-          (r'(\n\s*|\t)', token.Whitespace),
-          (r'&&|\|\||==|<=|>=|<|>|^>=', token.Operator),
+          (r'&&|\|\||==|<=|\^>=|>=|<|>', token.Operator),
           (r',|:|{|}', token.Punctuation),
           (r'.', token.Text)
       ],
diff --git a/Cabal/doc/developing-packages.rst b/Cabal/doc/developing-packages.rst
index 36f32fe492bf205d9df06dd444302412d942a0e8..825239d4a5db81600fd3d4f6f841d632f5bad694 100644
--- a/Cabal/doc/developing-packages.rst
+++ b/Cabal/doc/developing-packages.rst
@@ -2171,6 +2171,7 @@ The ``get`` command supports the following options:
     repository kind.
 
 .. pkg-section:: custom-setup
+   :since: 1.24
 
 Custom setup scripts
 --------------------
@@ -2186,10 +2187,11 @@ the compilation of custom ``Setup.hs`` scripts,
         Cabal < 1.25
 
 .. pkg-field:: setup-depends: package list
+    :since: 1.24
 
     The dependencies needed to compile ``Setup.hs``. See the
-    ```build-depends`` <#build-information>`__ section for a description
-    of the syntax expected by this field.
+    :pkg-field:`build-depends` field for a description of the syntax expected by
+    this field.
 
 Autogenerated modules
 ---------------------