summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/installer.ini101
-rw-r--r--compiler/nimsuggest/nimsuggest.nim11
-rw-r--r--compiler/types.nim2
-rw-r--r--doc/lib.txt47
-rw-r--r--doc/nimsuggest.txt174
-rw-r--r--doc/tools.txt5
-rw-r--r--koch.nim27
-rw-r--r--lib/system.nim4
-rw-r--r--tests/tuples/tuple_with_nil.nim766
-rw-r--r--tools/niminst/niminst.nim68
-rw-r--r--tools/niminst/nsis.tmpl18
-rw-r--r--web/documentation.txt21
-rw-r--r--web/download.txt12
-rw-r--r--web/learn.txt6
-rw-r--r--web/news.txt734
-rw-r--r--web/ticker.txt10
-rw-r--r--web/website.ini6
17 files changed, 1570 insertions, 442 deletions
diff --git a/compiler/installer.ini b/compiler/installer.ini
index 12a8e702d..4ee50f2ff 100644
--- a/compiler/installer.ini
+++ b/compiler/installer.ini
@@ -126,12 +126,109 @@ Files: "examples/*.txt"
 Files: "examples/*.cfg"
 Files: "examples/*.tmpl"
 
+Files: "tests/actiontable/*.nim"
+Files: "tests/alias/*.nim"
+Files: "tests/ambsym/*.nim"
+Files: "tests/array/*.nim"
+Files: "tests/assign/*.nim"
+Files: "tests/astoverload/*.nim"
+Files: "tests/async/*.nim"
+Files: "tests/benchmarks/*.nim"
+Files: "tests/bind/*.nim"
+Files: "tests/borrow/*.nim"
+Files: "tests/casestmt/*.nim"
+Files: "tests/ccgbugs/*.nim"
+Files: "tests/clearmsg/*.nim"
+Files: "tests/closure/*.nim"
+Files: "tests/cnstseq/*.nim"
+Files: "tests/collections/*.nim"
+Files: "tests/compiles/*.nim"
+Files: "tests/concat/*.nim"
+Files: "tests/concepts/*.nim"
+Files: "tests/constr/*.nim"
+Files: "tests/constraints/*.nim"
+Files: "tests/controlflow/*.nim"
+Files: "tests/converter/*.nim"
+Files: "tests/cpp/*.nim"
+Files: "tests/defaultprocparam/*.nim"
+Files: "tests/deprecated/*.nim"
+Files: "tests/destructor/*.nim"
+Files: "tests/dir with space/*.nim"
+Files: "tests/discard/*.nim"
+Files: "tests/distinct/*.nim"
+Files: "tests/dll/*.nim"
+Files: "tests/effects/*.nim"
+Files: "tests/enum/*.nim"
+Files: "tests/exception/*.nim"
+Files: "tests/exprs/*.nim"
+Files: "tests/fields/*.nim"
+Files: "tests/float/*.nim"
+Files: "tests/friends/*.nim"
+Files: "tests/gc/*.nim"
+Files: "tests/generics/*.nim"
+Files: "tests/gensym/*.nim"
+Files: "tests/global/*.nim"
+Files: "tests/implicit/*.nim"
+Files: "tests/init/*.nim"
+Files: "tests/iter/*.nim"
+Files: "tests/js/*.nim"
+Files: "tests/js/*.cfg"
+Files: "tests/let/*.nim"
+Files: "tests/lexer/*.nim"
+Files: "tests/lookups/*.nim"
+Files: "tests/macros/*.nim"
+Files: "tests/magics/*.nim"
+Files: "tests/metatype/*.nim"
+Files: "tests/method/*.nim"
+Files: "tests/misc/*.nim"
+Files: "tests/modules/*.nim"
+Files: "tests/namedparams/*.nim"
+Files: "tests/notnil/*.nim"
+Files: "tests/objects/*.nim"
+Files: "tests/objvariant/*.nim"
+Files: "tests/openarray/*.nim"
+Files: "tests/osproc/*.nim"
+Files: "tests/overflw/*.nim"
+Files: "tests/overload/*.nim"
+Files: "tests/parallel/*.nim"
+Files: "tests/parallel/*.cfg"
+Files: "tests/parser/*.nim"
+Files: "tests/pragmas/*.nim"
+Files: "tests/proc/*.nim"
+Files: "tests/procvar/*.nim"
+Files: "tests/range/*.nim"
+Files: "tests/rodfiles/*.nim"
+Files: "tests/seq/*.nim"
+Files: "tests/sets/*.nim"
+Files: "tests/showoff/*.nim"
+Files: "tests/specialops/*.nim"
+Files: "tests/stdlib/*.nim"
+Files: "tests/system/*.nim"
+Files: "tests/template/*.nim"
+Files: "tests/testament/*.nim"
+Files: "tests/testdata/*.nim"
+Files: "tests/threads/*.nim"
+Files: "tests/threads/*.cfg"
+Files: "tests/trmacros/*.nim"
+Files: "tests/tuples/*.nim"
+Files: "tests/typerel/*.nim"
+Files: "tests/types/*.nim"
+Files: "tests/usingstmt/*.nim"
+Files: "tests/varres/*.nim"
+Files: "tests/varstmt/*.nim"
+Files: "tests/vm/*.nim"
+Files: "tests/readme.txt"
+Files: "tests/testament/css/*.css"
+Files: "tests/testament/*.cfg"
+Files: "lib/pure/unidecode/unidecode.dat"
 
 [Windows]
 Files: "bin/nim.exe"
-Files: "bin/nim_debug.exe"
 Files: "bin/c2nim.exe"
 Files: "bin/nimgrep.exe"
+Files: "bin/nimsuggest.exe"
+Files: "bin/nimble.exe"
+Files: "bin/*.dll"
 
 Files: "dist/*.dll"
 Files: "koch.exe"
@@ -142,7 +239,7 @@ BinPath: r"bin;dist\mingw\bin;dist"
 ;           Section | dir | zipFile | size hint (in KB) | url | exe start menu entry
 Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|overview.html"
 Download: r"C Compiler (MingW)|dist|mingw.zip|82944|http://nim-lang.org/download/${mingw}.zip"
-Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.1.3.zip|aporia\bin\aporia.exe"
+Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.3.0.zip|aporia\bin\aporia.exe"
 ; for now only NSIS supports optional downloads
 
 [UnixBin]
diff --git a/compiler/nimsuggest/nimsuggest.nim b/compiler/nimsuggest/nimsuggest.nim
index b45ca475c..8285d81d9 100644
--- a/compiler/nimsuggest/nimsuggest.nim
+++ b/compiler/nimsuggest/nimsuggest.nim
@@ -82,7 +82,8 @@ proc action(cmd: string) =
   if cmd[i] == ';':
     i = parseQuoted(cmd, dirtyfile, i+1)
   i += skipWhile(cmd, seps, i)
-  var line, col = -1
+  var line = -1
+  var col = 0
   i += parseInt(cmd, line, i)
   i += skipWhile(cmd, seps, i)
   i += parseInt(cmd, col, i)
@@ -97,7 +98,7 @@ proc action(cmd: string) =
   resetModule dirtyIdx
   if dirtyIdx != gProjectMainIdx:
     resetModule gProjectMainIdx
-  gTrackPos = newLineInfo(dirtyIdx, line, col)
+  gTrackPos = newLineInfo(dirtyIdx, line, col-1)
   #echo dirtyfile, gDirtyBufferIdx, " project ", gProjectMainIdx
   gErrorCounter = 0
   if not isKnownFile:
@@ -150,11 +151,11 @@ proc mainCommand =
 
 proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
   var p = parseopt.initOptParser(cmd)
-  while true: 
+  while true:
     parseopt.next(p)
     case p.kind
-    of cmdEnd: break 
-    of cmdLongoption, cmdShortOption: 
+    of cmdEnd: break
+    of cmdLongoption, cmdShortOption:
       case p.key.normalize
       of "port": gPort = parseInt(p.val).Port
       of "address": gAddress = p.val
diff --git a/compiler/types.nim b/compiler/types.nim
index 1b30afc76..e205f5722 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1460,7 +1460,7 @@ proc takeType*(formal, arg: PType): PType =
     let a = copyType(arg.skipTypes({tyGenericInst}), arg.owner, keepId=false)
     a.sons[ord(arg.kind in {tyArray, tyArrayConstr})] = formal.sons[0]
     result = a
-  elif formal.kind == tySet and arg.kind == tySet:
+  elif formal.kind in {tyTuple, tySet} and arg.kind == formal.kind:
     result = formal
   else:
     result = arg
diff --git a/doc/lib.txt b/doc/lib.txt
index 385e7a91a..1c0278068 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -37,7 +37,7 @@ Core
 
 * `unsigned <unsigned.html>`_
   This module implements basic arithmetic operators for unsigned integers.
-  To discourage users from using unsigned integers, it's not part 
+  To discourage users from using unsigned integers, it's not part
   of ``system``, but an extra import.
 
 * `threads <threads.html>`_
@@ -45,7 +45,7 @@ Core
   import it explicitly.
 
 * `channels <channels.html>`_
-  Nim message passing support for threads. **Note**: This is part of the 
+  Nim message passing support for threads. **Note**: This is part of the
   system module. Do not import it explicitly.
 
 * `locks <locks.html>`_
@@ -55,7 +55,7 @@ Core
   Contains the AST API and documentation of Nim for writing macros.
 
 * `typeinfo <typeinfo.html>`_
-  Provides (unsafe) access to Nim's run time type information. 
+  Provides (unsafe) access to Nim's run time type information.
 
 * `typetraits <typetraits.html>`_
   This module defines compile-time reflection procs for working with types.
@@ -110,9 +110,9 @@ String handling
 
 * `unicode <unicode.html>`_
   This module provides support to handle the Unicode UTF-8 encoding.
-  
+
 * `encodings <encodings.html>`_
-  Converts between different character encodings. On UNIX, this uses 
+  Converts between different character encodings. On UNIX, this uses
   the ``iconv`` library, on Windows the Windows API.
 
 * `pegs <pegs.html>`_
@@ -159,7 +159,7 @@ Generic Operating System Services
   may provide other implementations for this standard stream interface.
 
 * `marshal <marshal.html>`_
-  Contains procs for serialization and deseralization of arbitrary Nim 
+  Contains procs for serialization and deseralization of arbitrary Nim
   data structures.
 
 * `terminal <terminal.html>`_
@@ -168,7 +168,7 @@ Generic Operating System Services
   sequences and does not depend on any other module.
 
 * `memfiles <memfiles.html>`_
-  This module provides support for memory mapped files (Posix's ``mmap``) 
+  This module provides support for memory mapped files (Posix's ``mmap``)
   on the different operating systems.
 
 * `fsmonitor <fsmonitor.html>`_
@@ -228,7 +228,7 @@ Internet Protocols and Support
   This module implements a simple HTTP client.
 
 * `smtp <smtp.html>`_
-  This module implement a simple SMTP client. 
+  This module implement a simple SMTP client.
 
 * `ftpclient <ftpclient.html>`_
   This module implements an FTP client.
@@ -346,7 +346,7 @@ XML Processing
   This module parses an HTML document and creates its XML tree representation.
 
 * `htmlgen <htmlgen.html>`_
-  This module implements a simple XML and HTML code 
+  This module implements a simple XML and HTML code
   generator. Each commonly used HTML tag has a corresponding macro
   that generates a string with its HTML representation.
 
@@ -381,7 +381,7 @@ Miscellaneous
 
 * `oids <oids.html>`_
   An OID is a global ID that consists of a timestamp,
-  a unique counter and a random value. This combination should suffice to 
+  a unique counter and a random value. This combination should suffice to
   produce a globally distributed unique ID. This implementation was extracted
   from the Mongodb interface and it thus binary compatible with a Mongo OID.
 
@@ -453,12 +453,8 @@ Other
 * `zipfiles <zipfiles.html>`_
   This module implements a zip archive creator/reader/modifier.
 
-* `web <web.html>`_
-  This module contains simple high-level procedures for dealing with the
-  Web like loading the contents of a Web page from an URL.
-
 * `ssl <ssl.html>`_
-  This module provides an easy to use sockets-style 
+  This module provides an easy to use sockets-style
   Nim interface to the OpenSSL library.
 
 * `rdstdin <rdstdin.html>`_
@@ -513,25 +509,6 @@ Regular expressions
   Wrapper for the TRE library.
 
 
-Graphics libraries
-------------------
-
-* `sdl <sdl.html>`_
-  Part of the wrapper for SDL.
-* `sdl_gfx <sdl_gfx.html>`_
-  Part of the wrapper for SDL.
-* `sdl_image <sdl_image.html>`_
-  Part of the wrapper for SDL.
-* `sdl_mixer <sdl_mixer.html>`_
-  Part of the wrapper for SDL.
-* `sdl_net <sdl_net.html>`_
-  Part of the wrapper for SDL.
-* `sdl_ttf <sdl_ttf.html>`_
-  Part of the wrapper for SDL.
-* `smpeg <smpeg.html>`_
-  Part of the wrapper for SDL.
-
-
 GUI libraries
 -------------
 
@@ -591,7 +568,7 @@ Data Compression and Archiving
 Scientific computing
 --------------------
 
-* `libsvm <libsvm.html>`_ 
+* `libsvm <libsvm.html>`_
   Low level wrapper for `lib svm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_.
 
 Nimble
diff --git a/doc/nimsuggest.txt b/doc/nimsuggest.txt
new file mode 100644
index 000000000..2b52196b9
--- /dev/null
+++ b/doc/nimsuggest.txt
@@ -0,0 +1,174 @@
+================================
+  Nim IDE Integration Guide
+================================
+
+:Author: Unknown
+:Version: |nimversion|
+
+.. contents::
+
+
+Nim differs from many other compilers in that it is really fast,
+and being so fast makes it suited to provide external queries for
+text editors about the source code being written. Through the
+``nimsuggest`` tool, any IDE
+can query a ``.nim`` source file and obtain useful information like
+definition of symbols or suggestions for completion.
+
+This document will guide you through the available options. If you
+want to look at practical examples of nimsuggest support you can look
+at the
+`various editor integrations <https://github.com/Araq/Nim/wiki/Editor-Support>`_
+already available.
+
+
+Installation
+============
+
+Nimsuggest is available as a Nimble package but currently does not install
+properly via Nimble. As nimsuggest is part of the compiler it also doesn't make
+too much sense as a Nimble package. Instead we will do the building manually::
+
+  cd compiler/nimsuggest
+  nim c -d:release nimsuggest
+  cp nimsuggest ../../bin
+  # OR: copy the nimsuggest binary to where your 'nim' binary is
+  cd ../..
+
+
+
+Nimsuggest invocation
+=====================
+
+Run it via ``nimsuggest --stdin myproject.nim``. Nimsuggest is a server that
+takes queries that are related to ``myproject``. There is some support so that
+you can throw random ``.nim`` files which are not part of ``myproject`` at
+Nimsuggest too, but usually the query refer to modules/files that are part of
+``myproject``.
+
+``--stdin`` means that Nimsuggest reads the query from ``stdin``. This is great
+for testing things out and playing with it but for an editor communication
+via sockets is more reasonable so that is the default. It listens to port 6000
+by default.
+
+
+Specifying the location of the query
+------------------------------------
+
+Nimsuggest than waits for queries to process. A query consists of a
+cryptic 3 letter "command" ``def`` or ``con`` or ``sug`` or ``use`` followed by
+a location. A query location consists of:
+
+
+``file.nim``
+    This is the name of the module or include file the query refers to.
+
+``dirtyfile.nim``
+    This is optional.
+
+    The ``file`` paramater is enough for static analysis, but IDEs
+    tend to have *unsaved buffers* where the user may still be in
+    the middle of typing a line. In such situations the IDE can
+    save the current contents to a temporary file and then use the
+    ``dirtyfile.nim`` option to tell Nimsuggest that ``foobar.nim`` should
+    be taken from ``temporary/foobar.nim``.
+
+
+``line``
+    An integer with the line you are going to query. For the compiler
+    lines start at **1**.
+
+``col``
+    An integer with the column you are going to query. For the
+    compiler columns start at **1**.
+
+
+Definitions
+-----------
+
+The ``def`` Nimsuggest command performs a query about the definition
+of a specific symbol. If available, Nimsuggest will answer with the
+type, source file, line/column information and other accessory data
+if available like a docstring. With this information an IDE can
+provide the typical *Jump to definition* where a user puts the
+cursor on a symbol or uses the mouse to select it and is redirected
+to the place where the symbol is located.
+
+Since Nim is implemented in Nim, one of the nice things of
+this feature is that any user with an IDE supporting it can quickly
+jump around the standard library implementation and see exactly
+what a proc does, learning about the language and seeing real life
+examples of how to write/implement specific features.
+
+Nimsuggest will always answer with a single definition or none if it
+can't find any valid symbol matching the position of the query.
+
+
+Suggestions
+-----------
+
+The ``sug`` Nimsuggest command performs a query about possible
+completion symbols at some point in the file.
+
+The typical usage scenario for this option is to call it after the
+user has typed the dot character for `the object oriented call
+syntax <tut2.html#method-call-syntax>`_. Nimsuggest will try to return
+the suggestions sorted first by scope (from innermost to outermost)
+and then by item name.
+
+
+Invocation context
+------------------
+
+The ``con`` Nimsuggest command is very similar to the suggestions
+command, but instead of being used after the user has typed a dot
+character, this one is meant to be used after the user has typed
+an opening brace to start typing parameters.
+
+
+Symbol usages
+-------------
+
+The ``use`` Nimsuggest command lists all usages of the symbol at
+a position. IDEs can use this to find all the places in the file
+where the symbol is used and offer the user to rename it in all
+places at the same time.
+
+For this kind of query the IDE will most likely ignore all the
+type/signature info provided by Nimsuggest and concentrate on the
+filename, line and column position of the multiple returned answers.
+
+
+
+Parsing nimsuggest output
+=========================
+
+Nimsuggest output is always returned on single lines separated by
+tab characters (``\t``). The values of each column are:
+
+1. Three characters indicating the type of returned answer (e.g.
+   ``def`` for definition, ``sug`` for suggestion, etc).
+2. Type of the symbol. This can be ``skProc``, ``skLet``, and just
+   about any of the enums defined in the module ``compiler/ast.nim``.
+3. Full qualitifed path of the symbol. If you are querying a symbol
+   defined in the ``proj.nim`` file, this would have the form
+   ``proj.symbolName``.
+4. Type/signature. For variables and enums this will contain the
+   type of the symbol, for procs, methods and templates this will
+   contain the full unique signature (e.g. ``proc (File)``).
+5. Full path to the file containing the symbol.
+6. Line where the symbol is located in the file. Lines start to
+   count at **1**.
+7. Column where the symbol is located in the file. Columns start
+   to count at **1**.
+8. Docstring for the symbol if available or the empty string. To
+   differentiate the docstring from end of answer,
+   the docstring is always provided enclosed in double quotes, and
+   if the docstring spans multiple lines, all following lines of the
+   docstring will start with a blank space to align visually with
+   the starting quote.
+
+   Also, you won't find raw ``\n`` characters breaking the one
+   answer per line format. Instead you will need to parse sequences
+   in the form ``\xHH``, where *HH* is a hexadecimal value (e.g.
+   newlines generate the sequence ``\x0A``).
diff --git a/doc/tools.txt b/doc/tools.txt
index 7f2830879..b0a45c575 100644
--- a/doc/tools.txt
+++ b/doc/tools.txt
@@ -4,6 +4,11 @@ Tools available with Nim
 
 The standard distribution ships with the following tools:
 
+- | `Nimsuggest for IDE support <nimsuggest.html>`_
+  | Through the ``nimsuggest`` tool, any IDE can query a ``.nim`` source file
+    and obtain useful information like definition of symbols or suggestions for
+    completion.
+
 - | `Nim Installation Generator <niminst.html>`_
   | How to generate a nice installer for your Nim program.
 
diff --git a/koch.nim b/koch.nim
index 3ebfb6655..55019b544 100644
--- a/koch.nim
+++ b/koch.nim
@@ -106,6 +106,12 @@ proc zip(args: string) =
   exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim zip compiler/installer.ini" %
        ["tools/niminst/niminst".exe, VersionAsString])
 
+proc targz(args: string) =
+  exec("$3 cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" %
+       [VersionAsString, compileNimInst, findNim()])
+  exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim targz compiler/installer.ini" %
+       ["tools" / "niminst" / "niminst".exe, VersionAsString])
+
 proc buildTool(toolname, args: string) =
   exec("$# cc $# $#" % [findNim(), args, toolname])
   copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe)
@@ -113,12 +119,12 @@ proc buildTool(toolname, args: string) =
 proc nsis(args: string) =
   # make sure we have generated the niminst executables:
   buildTool("tools/niminst/niminst", args)
-  buildTool("tools/nimgrep", args)
+  #buildTool("tools/nimgrep", args)
   # produce 'nim_debug.exe':
-  exec "nim c compiler" / "nim.nim"
-  copyExe("compiler/nim".exe, "bin/nim_debug".exe)
+  #exec "nim c compiler" / "nim.nim"
+  #copyExe("compiler/nim".exe, "bin/nim_debug".exe)
   exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" &
-        " nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)])
+        " nsis compiler/installer.ini") % [VersionAsString, $(sizeof(pointer)*8)])
 
 proc install(args: string) =
   exec("$# cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" %
@@ -308,12 +314,14 @@ proc winRelease() =
   #buildTool("tools/niminst/niminst", " -d:release")
   buildTool("tools/nimgrep", " -d:release")
   buildTool("compiler/nimfix/nimfix", " -d:release")
+  buildTool("compiler/nimsuggest/nimsuggest", " -d:release")
+
+  #run7z("win32", "bin/nim.exe", "bin/c2nim.exe", "bin/nimgrep.exe",
+  #      "bin/nimfix.exe",
+  #      "bin/nimble.exe", "bin/*.dll",
+  #      "config", "dist/*.dll", "examples", "lib",
+  #      "readme.txt", "contributors.txt", "copying.txt")
 
-  run7z("win32", "bin/nim.exe", "bin/c2nim.exe", "bin/nimgrep.exe",
-        "bin/nimfix.exe",
-        "bin/nimble.exe", "bin/*.dll",
-        "config", "dist/*.dll", "examples", "lib",
-        "readme.txt", "contributors.txt", "copying.txt")
   # second step: XXX build 64 bit version
 
 # -------------- tests --------------------------------------------------------
@@ -357,6 +365,7 @@ of cmdArgument:
   of "pdf": pdf()
   of "csource", "csources": csource(op.cmdLineRest)
   of "zip": zip(op.cmdLineRest)
+  of "targz": targz(op.cmdLineRest)
   of "nsis": nsis(op.cmdLineRest)
   of "install": install(op.cmdLineRest)
   of "test", "tests": tests(op.cmdLineRest)
diff --git a/lib/system.nim b/lib/system.nim
index 85f1350d7..33eee42f0 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1532,10 +1532,10 @@ const
   NimMajor*: int = 0
     ## is the major number of Nim's version.
 
-  NimMinor*: int = 10
+  NimMinor*: int = 11
     ## is the minor number of Nim's version.
 
-  NimPatch*: int = 3
+  NimPatch*: int = 0
     ## is the patch number of Nim's version.
 
   NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim
new file mode 100644
index 000000000..26e4ae85e
--- /dev/null
+++ b/tests/tuples/tuple_with_nil.nim
@@ -0,0 +1,766 @@
+import macros
+from strutils import IdentStartChars
+import parseutils
+import unicode
+import math
+import fenv
+import unsigned
+import pegs
+import streams
+
+type
+  FormatError = object of Exception ## Error in the format string.
+
+  Writer = concept W
+    ## Writer to output a character `c`.
+    when (NimMajor, NimMinor, NimPatch) > (0, 10, 2):
+      write(W, 'c')
+    else:
+      block:
+        var x: W
+        write(x, char)
+
+  FmtAlign = enum ## Format alignment
+    faDefault  ## default for given format type
+    faLeft     ## left aligned
+    faRight    ## right aligned
+    faCenter   ## centered
+    faPadding  ## right aligned, fill characters after sign (numbers only)
+
+  FmtSign = enum ## Format sign
+    fsMinus    ## only unary minus, no reservered sign space for positive numbers
+    fsPlus     ## unary minus and unary plus
+    fsSpace    ## unary minus and reserved space for positive numbers
+
+  FmtType = enum ## Format type
+    ftDefault  ## default format for given parameter type
+    ftStr      ## string
+    ftChar     ## character
+    ftDec      ## decimal integer
+    ftBin      ## binary integer
+    ftOct      ## octal integer
+    ftHex      ## hexadecimal integer
+    ftFix      ## real number in fixed point notation
+    ftSci      ## real number in scientific notation
+    ftGen      ## real number in generic form (either fixed point or scientific)
+    ftPercent  ## real number multiplied by 100 and % added
+
+  Format = tuple ## Formatting information.
+    typ: FmtType     ## format type
+    precision: int    ## floating point precision
+    width: int        ## minimal width
+    fill: string      ## the fill character, UTF8
+    align: FmtAlign  ## aligment
+    sign: FmtSign    ## sign notation
+    baseprefix: bool  ## whether binary, octal, hex should be prefixed by 0b, 0x, 0o
+    upcase: bool      ## upper case letters in hex or exponential formats
+    comma: bool       ##
+    arysep: string    ## separator for array elements
+
+  PartKind = enum pkStr, pkFmt
+
+  Part = object
+    ## Information of a part of the target string.
+    case kind: PartKind ## type of the part
+    of pkStr:
+      str: string ## literal string
+    of pkFmt:
+      arg: int ## position argument
+      fmt: string ## format string
+      field: string ## field of argument to be accessed
+      index: int ## array index of argument to be accessed
+      nested: bool ## true if the argument contains nested formats
+
+const
+  DefaultPrec = 6 ## Default precision for floating point numbers.
+  DefaultFmt: Format = (ftDefault, -1, -1, nil, faDefault, fsMinus, false, false, false, nil)
+    ## Default format corresponding to the empty format string, i.e.
+    ##   `x.format("") == x.format(DefaultFmt)`.
+  round_nums = [0.5, 0.05, 0.005, 0.0005, 0.00005, 0.000005, 0.0000005, 0.00000005]
+    ## Rounding offset for floating point numbers up to precision 8.
+
+proc write(s: var string; c: char) =
+  s.add(c)
+
+proc has(c: Captures; i: range[0..pegs.MaxSubpatterns-1]): bool {.nosideeffect, inline.} =
+  ## Tests whether `c` contains a non-empty capture `i`.
+  let b = c.bounds(i)
+  result = b.first <= b.last
+
+proc get(str: string; c: Captures; i: range[0..MaxSubpatterns-1]; def: char): char {.nosideeffect, inline.} =
+  ## If capture `i` is non-empty return that portion of `str` casted
+  ## to `char`, otherwise return `def`.
+  result = if c.has(i): str[c.bounds(i).first] else: def
+
+proc get(str: string; c: Captures; i: range[0..MaxSubpatterns-1]; def: string; begoff: int = 0): string {.nosideeffect, inline.} =
+  ## If capture `i` is non-empty return that portion of `str` as
+  ## string, otherwise return `def`.
+  let b = c.bounds(i)
+  result = if c.has(i): str.substr(b.first + begoff, b.last) else: def
+
+proc get(str: string; c: Captures; i: range[0..MaxSubpatterns-1]; def: int; begoff: int = 0): int {.nosideeffect, inline.} =
+  ## If capture `i` is non-empty return that portion of `str`
+  ## converted to int, otherwise return `def`.
+  if c.has(i):
+    discard str.parseInt(result, c.bounds(i).first + begoff)
+  else:
+    result = def
+
+proc parse(fmt: string): Format {.nosideeffect.} =
+  # Converts the format string `fmt` into a `Format` structure.
+  let p =
+    sequence(capture(?sequence(anyRune(), &charSet({'<', '>', '=', '^'}))),
+             capture(?charSet({'<', '>', '=', '^'})),
+             capture(?charSet({'-', '+', ' '})),
+             capture(?charSet({'#'})),
+             capture(?(+digits())),
+             capture(?charSet({','})),
+             capture(?sequence(charSet({'.'}), +digits())),
+             capture(?charSet({'b', 'c', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 's', 'x', 'X', '%'})),
+             capture(?sequence(charSet({'a'}), *pegs.any())))
+  # let p=peg"{(_&[<>=^])?}{[<>=^]?}{[-+ ]?}{[#]?}{[0-9]+?}{[,]?}{([.][0-9]+)?}{[bcdeEfFgGnosxX%]?}{(a.*)?}"
+
+  var caps: Captures
+  if fmt.rawmatch(p, 0, caps) < 0:
+    raise newException(FormatError, "Invalid format string")
+
+  result.fill = fmt.get(caps, 0, nil)
+
+  case fmt.get(caps, 1, 0.char)
+  of '<': result.align = faLeft
+  of '>': result.align = faRight
+  of '^': result.align = faCenter
+  of '=': result.align = faPadding
+  else: result.align = faDefault
+
+  case fmt.get(caps, 2, '-')
+  of '-': result.sign = fsMinus
+  of '+': result.sign = fsPlus
+  of ' ': result.sign = fsSpace
+  else: result.sign = fsMinus
+
+  result.baseprefix = caps.has(3)
+
+  result.width = fmt.get(caps, 4, -1)
+
+  if caps.has(4) and fmt[caps.bounds(4).first] == '0':
+    if result.fill != nil:
+      raise newException(FormatError, "Leading 0 in with not allowed with explicit fill character")
+    if result.align != faDefault:
+      raise newException(FormatError, "Leading 0 in with not allowed with explicit alignment")
+    result.fill = "0"
+    result.align = faPadding
+
+  result.comma = caps.has(5)
+
+  result.precision = fmt.get(caps, 6, -1, 1)
+
+  case fmt.get(caps, 7, 0.char)
+  of 's': result.typ = ftStr
+  of 'c': result.typ = ftChar
+  of 'd', 'n': result.typ = ftDec
+  of 'b': result.typ = ftBin
+  of 'o': result.typ = ftOct
+  of 'x': result.typ = ftHex
+  of 'X': result.typ = ftHex; result.upcase = true
+  of 'f', 'F': result.typ = ftFix
+  of 'e': result.typ = ftSci
+  of 'E': result.typ = ftSci; result.upcase = true
+  of 'g': result.typ = ftGen
+  of 'G': result.typ = ftGen; result.upcase = true
+  of '%': result.typ = ftPercent
+  else: result.typ = ftDefault
+
+  result.arysep = fmt.get(caps, 8, nil, 1)
+
+proc getalign(fmt: Format; defalign: FmtAlign; slen: int) : tuple[left, right:int] {.nosideeffect.} =
+  ## Returns the number of left and right padding characters for a
+  ## given format alignment and width of the object to be printed.
+  ##
+  ## `fmt`
+  ##    the format data
+  ## `default`
+  ##    if `fmt.align == faDefault`, then this alignment is used
+  ## `slen`
+  ##    the width of the object to be printed.
+  ##
+  ## The returned values `(left, right)` will be as minimal as possible
+  ## so that `left + slen + right >= fmt.width`.
+  result.left = 0
+  result.right = 0
+  if (fmt.width >= 0) and (slen < fmt.width):
+    let alg = if fmt.align == faDefault: defalign else: fmt.align
+    case alg:
+    of faLeft: result.right = fmt.width - slen
+    of faRight, faPadding: result.left = fmt.width - slen
+    of faCenter:
+      result.left = (fmt.width - slen) div 2
+      result.right = fmt.width - slen - result.left
+    else: discard
+
+proc writefill(o: var Writer; fmt: Format; n: int; signum: int = 0) =
+  ## Write characters for filling. This function also writes the sign
+  ## of a numeric format and handles the padding alignment
+  ## accordingly.
+  ##
+  ## `o`
+  ##   output object
+  ## `add`
+  ##   output function
+  ## `fmt`
+  ##   format to be used (important for padding aligment)
+  ## `n`
+  ##   the number of filling characters to be written
+  ## `signum`
+  ##   the sign of the number to be written, < 0 negative, > 0 positive, = 0 zero
+  if fmt.align == faPadding and signum != 0:
+    if signum < 0: write(o, '-')
+    elif fmt.sign == fsPlus: write(o, '+')
+    elif fmt.sign == fsSpace: write(o, ' ')
+
+  if fmt.fill == nil:
+    for i in 1..n: write(o, ' ')
+  else:
+    for i in 1..n:
+      for c in fmt.fill:
+        write(o, c)
+
+  if fmt.align != faPadding and signum != 0:
+    if signum < 0: write(o, '-')
+    elif fmt.sign == fsPlus: write(o, '+')
+    elif fmt.sign == fsSpace: write(o, ' ')
+
+proc writeformat(o: var Writer; s: string; fmt: Format) =
+  ## Write string `s` according to format `fmt` using output object
+  ## `o` and output function `add`.
+  if fmt.typ notin {ftDefault, ftStr}:
+    raise newException(FormatError, "String variable must have 's' format type")
+
+  # compute alignment
+  let len = if fmt.precision < 0: runelen(s) else: min(runelen(s), fmt.precision)
+  var alg = getalign(fmt, faLeft, len)
+  writefill(o, fmt, alg.left)
+  var pos = 0
+  for i in 0..len-1:
+    let rlen = runeLenAt(s, pos)
+    for j in pos..pos+rlen-1: write(o, s[j])
+    pos += rlen
+  writefill(o, fmt, alg.right)
+
+proc writeformat(o: var Writer; c: char; fmt: Format) =
+  ## Write character `c` according to format `fmt` using output object
+  ## `o` and output function `add`.
+  if not (fmt.typ in {ftChar, ftDefault}):
+    raise newException(FormatError, "Character variable must have 'c' format type")
+
+  # compute alignment
+  var alg = getalign(fmt, faLeft, 1)
+  writefill(o, fmt, alg.left)
+  write(o, c)
+  writefill(o, fmt, alg.right)
+
+proc writeformat(o: var Writer; c: Rune; fmt: Format) =
+  ## Write rune `c` according to format `fmt` using output object
+  ## `o` and output function `add`.
+  if not (fmt.typ in {ftChar, ftDefault}):
+    raise newException(FormatError, "Character variable must have 'c' format type")
+
+  # compute alignment
+  var alg = getalign(fmt, faLeft, 1)
+  writefill(o, fmt, alg.left)
+  let s = c.toUTF8
+  for c in s: write(o, c)
+  writefill(o, fmt, alg.right)
+
+proc abs(x: SomeUnsignedInt): SomeUnsignedInt {.inline.} = x
+  ## Return the absolute value of the unsigned int `x`.
+
+proc writeformat(o: var Writer; i: SomeInteger; fmt: Format) =
+  ## Write integer `i` according to format `fmt` using output object
+  ## `o` and output function `add`.
+  var fmt = fmt
+  if fmt.typ == ftDefault:
+    fmt.typ = ftDec
+  if not (fmt.typ in {ftBin, ftOct, ftHex, ftDec}):
+    raise newException(FormatError, "Integer variable must of one of the following types: b,o,x,X,d,n")
+
+  var base: type(i)
+  var len = 0
+  case fmt.typ:
+  of ftDec:
+    base = 10
+  of ftBin:
+    base = 2
+    if fmt.baseprefix: len += 2
+  of ftOct:
+    base = 8
+    if fmt.baseprefix: len += 2
+  of ftHex:
+    base = 16
+    if fmt.baseprefix: len += 2
+  else: assert(false)
+
+  if fmt.sign != fsMinus or i < 0: len.inc
+
+  var x: type(i) = abs(i)
+  var irev: type(i) = 0
+  var ilen = 0
+  while x > 0.SomeInteger:
+    len.inc
+    ilen.inc
+    irev = irev * base + x mod base
+    x = x div base
+  if ilen == 0:
+    ilen.inc
+    len.inc
+
+  var alg = getalign(fmt, faRight, len)
+  writefill(o, fmt, alg.left, if i >= 0.SomeInteger: 1 else: -1)
+  if fmt.baseprefix:
+    case fmt.typ
+    of ftBin:
+      write(o, '0')
+      write(o, 'b')
+    of ftOct:
+      write(o, '0')
+      write(o, 'o')
+    of ftHex:
+      write(o, '0')
+      write(o, 'x')
+    else:
+      raise newException(FormatError, "# only allowed with b, o, x or X")
+  while ilen > 0:
+    ilen.dec
+    let c = irev mod base
+    irev = irev div base
+    if c < 10:
+      write(o, ('0'.int + c.int).char)
+    elif fmt.upcase:
+      write(o, ('A'.int + c.int - 10).char)
+    else:
+      write(o, ('a'.int + c.int - 10).char)
+  writefill(o, fmt, alg.right)
+
+proc writeformat(o: var Writer; p: pointer; fmt: Format) =
+  ## Write pointer `i` according to format `fmt` using output object
+  ## `o` and output function `add`.
+  ##
+  ## Pointers are casted to unsigned int and formated as hexadecimal
+  ## with prefix unless specified otherwise.
+  var f = fmt
+  if f.typ == 0.char:
+    f.typ = 'x'
+    f.baseprefix = true
+  writeformat(o, add, cast[uint](p), f)
+
+proc writeformat(o: var Writer; x: SomeReal; fmt: Format) =
+  ## Write real number `x` according to format `fmt` using output
+  ## object `o` and output function `add`.
+  var fmt = fmt
+  # handle default format
+  if fmt.typ == ftDefault:
+    fmt.typ = ftGen
+    if fmt.precision < 0: fmt.precision = DefaultPrec
+  if not (fmt.typ in {ftFix, ftSci, ftGen, ftPercent}):
+    raise newException(FormatError, "Integer variable must of one of the following types: f,F,e,E,g,G,%")
+
+  let positive = x >= 0 and classify(x) != fcNegZero
+  var len = 0
+
+  if fmt.sign != fsMinus or not positive: len.inc
+
+  var prec = if fmt.precision < 0: DefaultPrec else: fmt.precision
+  var y = abs(x)
+  var exp = 0
+  var numstr, frstr: array[0..31, char]
+  var numlen, frbeg, frlen = 0
+
+  if fmt.typ == ftPercent: y *= 100
+
+  case classify(x):
+  of fcNan:
+    numstr[0..2] = ['n', 'a', 'n']
+    numlen = 3
+  of fcInf, fcNegInf:
+    numstr[0..2] = ['f', 'n', 'i']
+    numlen = 3
+  of fcZero, fcNegZero:
+    numstr[0] = '0'
+    numlen = 1
+  else: # a usual fractional number
+    if not (fmt.typ in {ftFix, ftPercent}): # not fixed point
+      exp = int(floor(log10(y)))
+      if fmt.typ == ftGen:
+        if prec == 0: prec = 1
+        if -4 <= exp and exp < prec:
+          prec = prec-1-exp
+          exp = 0
+        else:
+          prec = prec - 1
+          len += 4 # exponent
+      else:
+        len += 4 # exponent
+      # shift y so that 1 <= abs(y) < 2
+      if exp > 0: y /= pow(10.SomeReal, abs(exp).SomeReal)
+      elif exp < 0: y *= pow(10.SomeReal, abs(exp).SomeReal)
+    elif fmt.typ == ftPercent:
+      len += 1 # percent sign
+
+    # handle rounding by adding +0.5 * LSB
+    if prec < len(round_nums): y += round_nums[prec]
+
+    # split into integer and fractional part
+    var mult = 1'i64
+    for i in 1..prec: mult *= 10
+    var num = y.int64
+    var fr = ((y - num.SomeReal) * mult.SomeReal).int64
+    # build integer part string
+    while num != 0:
+      numstr[numlen] = ('0'.int + (num mod 10)).char
+      numlen.inc
+      num = num div 10
+    if numlen == 0:
+      numstr[0] = '0'
+      numlen.inc
+    # build fractional part string
+    while fr != 0:
+      frstr[frlen] = ('0'.int + (fr mod 10)).char
+      frlen.inc
+      fr = fr div 10
+    while frlen < prec:
+      frstr[frlen] = '0'
+      frlen.inc
+    # possible remove trailing 0
+    if fmt.typ == ftGen:
+      while frbeg < frlen and frstr[frbeg] == '0': frbeg.inc
+  # update length of string
+  len += numlen;
+  if frbeg < frlen:
+    len += 1 + frlen - frbeg # decimal point and fractional string
+
+  let alg = getalign(fmt, faRight, len)
+  writefill(o, fmt, alg.left, if positive: 1 else: -1)
+  for i in (numlen-1).countdown(0): write(o, numstr[i])
+  if frbeg < frlen:
+    write(o, '.')
+    for i in (frlen-1).countdown(frbeg): write(o, frstr[i])
+  if fmt.typ == ftSci or (fmt.typ == ftGen and exp != 0):
+    write(o, if fmt.upcase: 'E' else: 'e')
+    if exp >= 0:
+      write(o, '+')
+    else:
+      write(o, '-')
+      exp = -exp
+    if exp < 10:
+      write(o, '0')
+      write(o, ('0'.int + exp).char)
+    else:
+      var i=0
+      while exp > 0:
+        numstr[i] = ('0'.int + exp mod 10).char
+        i+=1
+        exp = exp div 10
+      while i>0:
+        i-=1
+        write(o, numstr[i])
+  if fmt.typ == ftPercent: write(o, '%')
+  writefill(o, fmt, alg.right)
+
+proc writeformat(o: var Writer; b: bool; fmt: Format) =
+  ## Write boolean value `b` according to format `fmt` using output
+  ## object `o`. A boolean may be formatted numerically or as string.
+  ## In the former case true is written as 1 and false as 0, in the
+  ## latter the strings "true" and "false" are shown, respectively.
+  ## The default is string format.
+  if fmt.typ in {ftStr, ftDefault}:
+    writeformat(o,
+                if b: "true"
+                else: "false",
+                fmt)
+  elif fmt.typ in {ftBin, ftOct, ftHex, ftDec}:
+    writeformat(o,
+                if b: 1
+                else: 0,
+                fmt)
+  else:
+    raise newException(FormatError, "Boolean values must of one of the following types: s,b,o,x,X,d,n")
+
+proc writeformat(o: var Writer; ary: openarray[any]; fmt: Format) =
+  ## Write array `ary` according to format `fmt` using output object
+  ## `o` and output function `add`.
+  if ary.len == 0: return
+
+  var sep: string
+  var nxtfmt = fmt
+  if fmt.arysep == nil:
+    sep = "\t"
+  elif fmt.arysep.len == 0:
+    sep = ""
+  else:
+    let sepch = fmt.arysep[0]
+    let nxt = 1 + skipUntil(fmt.arysep, sepch, 1)
+    if nxt >= 1:
+      nxtfmt.arysep = fmt.arysep.substr(nxt)
+      sep = fmt.arysep.substr(1, nxt-1)
+    else:
+      nxtfmt.arysep = ""
+      sep = fmt.arysep.substr(1)
+  writeformat(o, ary[0], nxtfmt)
+  for i in 1..ary.len-1:
+    for c in sep: write(o, c)
+    writeformat(o, ary[i], nxtfmt)
+
+proc addformat[T](o: var Writer; x: T; fmt: Format = DefaultFmt) {.inline.} =
+  ## Write `x` formatted with `fmt` to `o`.
+  writeformat(o, x, fmt)
+
+proc addformat[T](o: var Writer; x: T; fmt: string) {.inline.} =
+  ## The same as `addformat(o, x, parse(fmt))`.
+  addformat(o, x, fmt.parse)
+
+proc addformat(s: var string; x: string) {.inline.} =
+  ## Write `x` to `s`. This is a fast specialized version for
+  ## appending unformatted strings.
+  add(s, x)
+
+proc addformat(f: File; x: string) {.inline.} =
+  ## Write `x` to `f`. This is a fast specialized version for
+  ## writing unformatted strings to a file.
+  write(f, x)
+
+proc addformat[T](f: File; x: T; fmt: Format = DefaultFmt) {.inline.} =
+  ## Write `x` to file `f` using format `fmt`.
+  var g = f
+  writeformat(g, x, fmt)
+
+proc addformat[T](f: File; x: T; fmt: string) {.inline.} =
+  ## Write `x` to file `f` using format string `fmt`. This is the same
+  ## as `addformat(f, x, parse(fmt))`
+  addformat(f, x, parse(fmt))
+
+proc addformat(s: Stream; x: string) {.inline.} =
+  ## Write `x` to `s`. This is a fast specialized version for
+  ## writing unformatted strings to a stream.
+  write(s, x)
+
+proc addformat[T](s: Stream; x: T; fmt: Format = DefaultFmt) {.inline.} =
+  ## Write `x` to stream `s` using format `fmt`.
+  var g = s
+  writeformat(g, x, fmt)
+
+proc addformat[T](s: Stream; x: T; fmt: string) {.inline.} =
+  ## Write `x` to stream `s` using format string `fmt`. This is the same
+  ## as `addformat(s, x, parse(fmt))`
+  addformat(s, x, parse(fmt))
+
+proc format[T](x: T; fmt: Format): string =
+  ## Return `x` formatted as a string according to format `fmt`.
+  result = ""
+  addformat(result, x, fmt)
+
+proc format[T](x: T; fmt: string): string =
+  ## Return `x` formatted as a string according to format string `fmt`.
+  result = format(x, fmt.parse)
+
+proc format[T](x: T): string {.inline.} =
+  ## Return `x` formatted as a string according to the default format.
+  ## The default format corresponds to an empty format string.
+  var fmt {.global.} : Format = DefaultFmt
+  result = format(x, fmt)
+
+proc unquoted(s: string): string {.compileTime.} =
+  ## Return `s` {{ and }} by single { and }, respectively.
+  result = ""
+  var pos = 0
+  while pos < s.len:
+    let nxt = pos + skipUntil(s, {'{', '}'})
+    result.add(s.substr(pos, nxt))
+    pos = nxt + 2
+
+proc splitfmt(s: string): seq[Part] {.compiletime, nosideeffect.} =
+  ## Split format string `s` into a sequence of "parts".
+  ##
+
+  ## Each part is either a literal string or a format specification. A
+  ## format specification is a substring of the form
+  ## "{[arg][:format]}" where `arg` is either empty or a number
+  ## refering to the arg-th argument and an additional field or array
+  ## index. The format string is a string accepted by `parse`.
+  let subpeg = sequence(capture(digits()),
+                          capture(?sequence(charSet({'.'}), *pegs.identStartChars(), *identChars())),
+                          capture(?sequence(charSet({'['}), +digits(), charSet({']'}))),
+                          capture(?sequence(charSet({':'}), *pegs.any())))
+  result = @[]
+  var pos = 0
+  while true:
+    let oppos = pos + skipUntil(s, {'{', '}'}, pos)
+    # reached the end
+    if oppos >= s.len:
+      if pos < s.len:
+        result.add(Part(kind: pkStr, str: s.substr(pos).unquoted))
+      return
+    # skip double
+    if oppos + 1 < s.len and s[oppos] == s[oppos+1]:
+      result.add(Part(kind: pkStr, str: s.substr(pos, oppos)))
+      pos = oppos + 2
+      continue
+    if s[oppos] == '}':
+      error("Single '}' encountered in format string")
+    if oppos > pos:
+      result.add(Part(kind: pkStr, str: s.substr(pos, oppos-1).unquoted))
+    # find matching closing }
+    var lvl = 1
+    var nested = false
+    pos = oppos
+    while lvl > 0:
+      pos.inc
+      pos = pos + skipUntil(s, {'{', '}'}, pos)
+      if pos >= s.len:
+        error("Single '{' encountered in format string")
+      if s[pos] == '{':
+        lvl.inc
+        if lvl == 2:
+          nested = true
+        if lvl > 2:
+          error("Too many nested format levels")
+      else:
+        lvl.dec
+    let clpos = pos
+    var fmtpart = Part(kind: pkFmt, arg: -1, fmt: s.substr(oppos+1, clpos-1), field: nil, index: int.high, nested: nested)
+    if fmtpart.fmt.len > 0:
+      var m: array[0..3, string]
+      if not fmtpart.fmt.match(subpeg, m):
+        error("invalid format string")
+
+      if m[1] != nil and m[1].len > 0:
+        fmtpart.field = m[1].substr(1)
+      if m[2] != nil and m[2].len > 0:
+        discard parseInt(m[2].substr(1, m[2].len-2), fmtpart.index)
+
+      if m[0].len > 0: discard parseInt(m[0], fmtpart.arg)
+      if m[3] == nil or m[3].len == 0:
+        fmtpart.fmt = ""
+      elif m[3][0] == ':':
+        fmtpart.fmt = m[3].substr(1)
+      else:
+        fmtpart.fmt = m[3]
+    result.add(fmtpart)
+    pos = clpos + 1
+
+proc literal(s: string): NimNode {.compiletime, nosideeffect.} =
+  ## Return the nim literal of string `s`. This handles the case if
+  ## `s` is nil.
+  result = if s == nil: newNilLit() else: newLit(s)
+
+proc literal(b: bool): NimNode {.compiletime, nosideeffect.} =
+  ## Return the nim literal of boolean `b`. This is either `true`
+  ## or `false` symbol.
+  result = if b: "true".ident else: "false".ident
+
+proc literal[T](x: T): NimNode {.compiletime, nosideeffect.} =
+  ## Return the nim literal of value `x`.
+  when type(x) is enum:
+    result = ($x).ident
+  else:
+    result = newLit(x)
+
+proc generatefmt(fmtstr: string;
+                 args: var openarray[tuple[arg:NimNode, cnt:int]];
+                 arg: var int;): seq[tuple[val, fmt:NimNode]] {.compiletime.} =
+  ## fmtstr
+  ##   the format string
+  ## args
+  ##   array of expressions for the arguments
+  ## arg
+  ##   the number of the next argument for automatic parsing
+  ##
+  ## If arg is < 0 then the functions assumes that explicit numbering
+  ## must be used, otherwise automatic numbering is used starting at
+  ## `arg`. The value of arg is updated according to the number of
+  ## arguments being used. If arg == 0 then automatic and manual
+  ## numbering is not decided (because no explicit manual numbering is
+  ## fixed und no automatically numbered argument has been used so
+  ## far).
+  ##
+  ## The function returns a list of pairs `(val, fmt)` where `val` is
+  ## an expression to be formatted and `fmt` is the format string (or
+  ## Format). Therefore, the resulting string can be generated by
+  ## concatenating expressions `val.format(fmt)`. If `fmt` is `nil`
+  ## then `val` is a (literal) string expression.
+  try:
+    result = @[]
+    for part in splitfmt(fmtstr):
+      case part.kind
+      of pkStr: result.add((newLit(part.str), nil))
+      of pkFmt:
+        # first compute the argument expression
+        # start with the correct index
+        var argexpr : NimNode
+        if part.arg >= 0:
+          if arg > 0:
+            error("Cannot switch from automatic field numbering to manual field specification")
+          if part.arg >= args.len:
+            error("Invalid explicit argument index: " & $part.arg)
+          argexpr = args[part.arg].arg
+          args[part.arg].cnt = args[part.arg].cnt + 1
+          arg = -1
+        else:
+          if arg < 0:
+            error("Cannot switch from manual field specification to automatic field numbering")
+          if arg >= args.len:
+            error("Too few arguments for format string")
+          argexpr = args[arg].arg
+          args[arg].cnt = args[arg].cnt + 1
+          arg.inc
+        # possible field access
+        if part.field != nil and part.field.len > 0:
+          argexpr = newDotExpr(argexpr, part.field.ident)
+        # possible array access
+        if part.index < int.high:
+          argexpr = newNimNode(nnkBracketExpr).add(argexpr, newLit(part.index))
+        # now the expression for the format data
+        var fmtexpr: NimNode
+        if part.nested:
+          # nested format string. Compute the format string by
+          # concatenating the parts of the substring.
+          for e in generatefmt(part.fmt, args, arg):
+            var newexpr = if part.fmt == nil: e.val else: newCall(bindsym"format", e.val, e.fmt)
+            if fmtexpr != nil and fmtexpr.kind != nnkNilLit:
+              fmtexpr = infix(fmtexpr, "&", newexpr)
+            else:
+              fmtexpr = newexpr
+        else:
+          # literal format string, precompute the format data
+          fmtexpr = newNimNode(nnkPar)
+          for field, val in part.fmt.parse.fieldPairs:
+            fmtexpr.add(newNimNode(nnkExprColonExpr).add(field.ident, literal(val)))
+        # add argument
+        result.add((argexpr, fmtexpr))
+  finally:
+    discard
+
+proc addfmtfmt(fmtstr: string; args: NimNode; retvar: NimNode): NimNode {.compileTime.} =
+  var argexprs = newseq[tuple[arg:NimNode; cnt:int]](args.len)
+  result = newNimNode(nnkStmtListExpr)
+  # generate let bindings for arguments
+  for i in 0..args.len-1:
+    let argsym = gensym(nskLet, "arg" & $i)
+    result.add(newLetStmt(argsym, args[i]))
+    argexprs[i].arg = argsym
+  # add result values
+  var arg = 0
+  for e in generatefmt(fmtstr, argexprs, arg):
+    if e.fmt == nil or e.fmt.kind == nnkNilLit:
+      result.add(newCall(bindsym"addformat", retvar, e.val))
+    else:
+      result.add(newCall(bindsym"addformat", retvar, e.val, e.fmt))
+  for i, arg in argexprs:
+    if arg.cnt == 0:
+      warning("Argument " & $(i+1) & " `" & args[i].repr & "` is not used in format string")
+
+macro addfmt(s: var string, fmtstr: string{lit}, args: varargs[expr]): expr =
+  ## The same as `s.add(fmtstr.fmt(args...))` but faster.
+  result = addfmtfmt($fmtstr, args, s)
+
+var s: string = ""
+s.addfmt("a:{}", 42)
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index e50b251d3..f0ae45484 100644
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -35,6 +35,7 @@ type
     actionNsis,   # action: create NSIS installer
     actionScripts # action: create install and deinstall scripts
     actionZip,    # action: create zip file
+    actionTargz,  # action: create targz file
     actionDeb     # action: prepare deb package
 
   FileCategory = enum
@@ -171,6 +172,7 @@ proc parseCmdLine(c: var ConfigData) =
           of "csource": incl(c.actions, actionCSource)
           of "scripts": incl(c.actions, actionScripts)
           of "zip": incl(c.actions, actionZip)
+          of "targz": incl(c.actions, actionTargz)
           of "inno": incl(c.actions, actionInno)
           of "nsis": incl(c.actions, actionNsis)
           of "deb": incl(c.actions, actionDeb)
@@ -181,10 +183,10 @@ proc parseCmdLine(c: var ConfigData) =
         break
     of cmdLongoption, cmdShortOption:
       case normalize(key.string)
-      of "help", "h": 
+      of "help", "h":
         stdout.write(Usage)
         quit(0)
-      of "version", "v": 
+      of "version", "v":
         stdout.write(Version & "\n")
         quit(0)
       of "o", "output": c.outdir = val
@@ -240,7 +242,7 @@ proc incl(s: var seq[string], x: string): int =
   for i in 0.. <s.len:
     if cmpIgnoreStyle(s[i], x) == 0: return i
   s.add(x)
-  result = s.len-1 
+  result = s.len-1
 
 proc platforms(c: var ConfigData, v: string) =
   for line in splitLines(v):
@@ -277,17 +279,17 @@ proc parseIniFile(c: var ConfigData) =
           of "name": c.name = v
           of "displayname": c.displayName = v
           of "version": c.version = v
-          of "os": 
+          of "os":
             c.oses = split(v, {';'})
             hasCpuOs = true
             if c.explicitPlatforms:
               quit(errorStr(p, "you cannot have both 'platforms' and 'os'"))
-          of "cpu": 
+          of "cpu":
             c.cpus = split(v, {';'})
             hasCpuOs = true
             if c.explicitPlatforms:
               quit(errorStr(p, "you cannot have both 'platforms' and 'cpu'"))
-          of "platforms": 
+          of "platforms":
             platforms(c, v)
             c.explicitPlatforms = true
             if hasCpuOs:
@@ -389,7 +391,7 @@ proc readCFiles(c: var ConfigData, osA, cpuA: int) =
       of cfgKeyValuePair:
         case section
         of "ccompiler": pathFlags(p, k.key, k.value, c.ccompiler)
-        of "linker": 
+        of "linker":
           pathFlags(p, k.key, k.value, c.linker)
           # HACK: we conditionally add ``-lm -ldl``, so remove them from the
           # linker flags:
@@ -558,28 +560,68 @@ when haveZipLib:
     else:
       quit("Cannot open for writing: " & n)
 
+proc targzDist(c: var ConfigData) =
+  let proj = toLower(c.name) & "-" & c.version
+  var n = "$#.tar.gz" % proj
+  let tmpDir = if c.outdir.len == 0: "build" else: c.outdir
+
+  template processFile(z, dest, src) =
+    let s = src
+    let d = dest
+    echo "Copying ", s, " to ", tmpDir / d
+    let destdir = tmpdir / d.splitFile.dir
+    if not dirExists(destdir): createDir(destdir)
+    copyFile(s, tmpDir / d)
+
+  processFile(z, proj / buildBatFile32, "build" / buildBatFile32)
+  processFile(z, proj / buildBatFile64, "build" / buildBatFile64)
+  processFile(z, proj / buildShFile, "build" / buildShFile)
+  processFile(z, proj / makeFile, "build" / makeFile)
+  processFile(z, proj / installShFile, installShFile)
+  processFile(z, proj / deinstallShFile, deinstallShFile)
+  for f in walkFiles(c.libpath / "lib/*.h"):
+    processFile(z, proj / "c_code" / extractFilename(f), f)
+  for osA in 1..c.oses.len:
+    for cpuA in 1..c.cpus.len:
+      var dir = buildDir(osA, cpuA)
+      for k, f in walkDir("build" / dir):
+        if k == pcFile: processFile(z, proj / dir / extractFilename(f), f)
+
+  for cat in items({fcConfig..fcOther, fcUnix}):
+    for f in items(c.cat[cat]): processFile(z, proj / f, f)
+
+  let oldDir = getCurrentDir()
+  setCurrentDir(tmpDir)
+  try:
+    #if execShellCmd("7z a -ttar $1.tar $1" % proj) != 0 or
+    #   execShellCmd("7z a -tgzip $1.tar.gz $1.tar" % proj) != 0 or
+    if execShellCmd("7z a -tzip $1.zip $1" % proj) != 0:
+      echo("External program failed")
+  finally:
+    setCurrentDir(oldDir)
+
 # -- prepare build files for .deb creation
 
 proc debDist(c: var ConfigData) =
   if not existsFile(getOutputDir(c) / "build.sh"): quit("No build.sh found.")
   if not existsFile(getOutputDir(c) / "install.sh"): quit("No install.sh found.")
-  
+
   if c.debOpts.shortDesc == "": quit("shortDesc must be set in the .ini file.")
   if c.debOpts.licenses.len == 0:
     echo("[Warning] No licenses specified for .deb creation.")
-  
+
   # -- Copy files into /tmp/..
   echo("Copying source to tmp/niminst/deb/")
   var currentSource = getCurrentDir()
   var workingDir = getTempDir() / "niminst" / "deb"
   var upstreamSource = (c.name.toLower() & "-" & c.version)
-  
+
   createDir(workingDir / upstreamSource)
-  
+
   template copyNimDist(f, dest: string): stmt =
     createDir((workingDir / upstreamSource / dest).splitFile.dir)
     copyFile(currentSource / f, workingDir / upstreamSource / dest)
-  
+
   # Don't copy all files, only the ones specified in the config:
   copyNimDist(buildShFile, buildShFile)
   copyNimDist(makeFile, makeFile)
@@ -624,5 +666,7 @@ if actionZip in c.actions:
     zipDist(c)
   else:
     quit("libzip is not installed")
+if actionTargz in c.actions:
+  targzDist(c)
 if actionDeb in c.actions:
   debDist(c)
diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl
index c21bfb9d5..843a8cf44 100644
--- a/tools/niminst/nsis.tmpl
+++ b/tools/niminst/nsis.tmpl
@@ -1,5 +1,5 @@
 #! stdtmpl(subsChar='?') | standard
-#proc generateNsisSetup(c: ConfigData): string = 
+#proc generateNsisSetup(c: ConfigData): string =
 #  result = "; NSIS script generated by niminst\n" &
 #           "; To regenerate run ``niminst nsis`` or ``koch nsis``\n"
 
@@ -35,8 +35,8 @@
 
   ; Default installation folder
   ; This is changed later (in .onInit) to the root directory, if possible.
-  InstallDir "$LOCALAPPDATA\?{c.name}"
-  
+  InstallDir "$LOCALAPPDATA\?{c.name}-?{c.version}"
+
   ; Get installation folder from registry if available
   InstallDirRegKey HKCU "Software\c.name\c.version" ""
 
@@ -86,14 +86,14 @@
 
   !insertmacro MUI_PAGE_INSTFILES
   !insertmacro MUI_PAGE_FINISH
-  
+
   ; Setup the uninstaller pages
   !insertmacro MUI_UNPAGE_CONFIRM
   !insertmacro MUI_UNPAGE_INSTFILES
-  
+
 ;--------------------------------
 ;Languages
- 
+
   !insertmacro MUI_LANGUAGE "English"
 
 ;--------------------------------
@@ -104,7 +104,7 @@
   ; Nim binary.
   Section "Core Files" CoreSection
     ; This is a mandotory section
-    SectionIn RO 
+    SectionIn RO
 
     ; Output files to the base installation directory
     SetOutPath "$INSTDIR"
@@ -164,7 +164,7 @@
 
   ; The downloadable sections. These sections are automatically generated by
   ; niminst and the template filters.
-  #var i = 0 
+  #var i = 0
   #for download in c.downloads:
   #  inc i
   #  let d = download.split('|')
@@ -207,7 +207,7 @@
         CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}"
       !insertmacro MUI_STARTMENU_WRITE_END
     #  end if
-    
+
     ignore:
   SectionEnd
   #end
diff --git a/web/documentation.txt b/web/documentation.txt
index dbb737cd9..145a6e827 100644
--- a/web/documentation.txt
+++ b/web/documentation.txt
@@ -8,13 +8,13 @@ Nim's Documentation
 
   .. container:: libraries
 
-    - | `Standard Library <lib.html>`_
+    - | `Standard Library <0.11.0/lib.html>`_
       | This document describes Nim's standard library.
 
-    - | `Language Manual <manual.html>`_
+    - | `Language Manual <0.11.0/manual.html>`_
       | The Nim manual is a draft that will evolve into a proper specification.
 
-    - | `Compiler User Guide <nimc.html>`_
+    - | `Compiler User Guide <0.11.0/nimc.html>`_
       | The user guide lists command line arguments, special features of the
         compiler, etc.
 
@@ -26,11 +26,11 @@ Nim's Documentation
 
   .. container:: tools
 
-    - | `Source Code Filters <filters.html>`_
+    - | `Source Code Filters <0.11.0/filters.html>`_
       | The Nim compiler supports source code filters as a simple yet powerful
         builtin templating system.
 
-    - | `Tools Documentation <tools.html>`_
+    - | `Tools Documentation <0.11.0/tools.html>`_
       | Description of some tools that come with the standard distribution.
 
 
@@ -41,16 +41,17 @@ Nim's Documentation
 
   .. container:: internals
 
-    - | `Garbage Collector <gc.html>`_
+    - | `Garbage Collector <0.11.0/gc.html>`_
       | Additional documentation about Nim's GC and how to operate it in a
         realtime setting.
 
-    - | `Internal Documentation <intern.html>`_
-      | The internal documentation describes how the compiler is implemented. Read
-        this if you want to hack the compiler.
+    - | `Internal Documentation <0.11.0/intern.html>`_
+      | The internal documentation describes how the compiler is implemented.
+        Read this if you want to hack the compiler.
 
 
 Search Options
 --------------
 
-`Documentation Index <theindex.html>`_ - The generated index. **Index + (Ctrl+F) == Joy**
+`Documentation Index <0.11.0/theindex.html>`_ - The generated
+index. **Index + (Ctrl+F) == Joy**
diff --git a/web/download.txt b/web/download.txt
index 3d47467f2..c9bc202cd 100644
--- a/web/download.txt
+++ b/web/download.txt
@@ -13,8 +13,8 @@ Binaries
 --------
 
 Unfortunately for now we only provide builds for Windows.
-* 32 bit: `nim-0.10.2_x32.exe <download/nim-0.10.2_x32.exe>`_
-* 64 bit: `nim-0.10.2_x64.exe <download/nim-0.10.2_x64.exe>`_
+* 32 bit: `nim-0.11.0_x32.exe <download/nim-0.11.0_x32.exe>`_
+* 64 bit: `nim-0.11.0_x64.exe <download/nim-0.11.0_x64.exe>`_
 
 
 Installation based on generated C code
@@ -24,8 +24,12 @@ This installation method is the preferred way for Linux, Mac OS X, and other Uni
 like systems. Binary packages may be provided later.
 
 
-Download `nim-0.10.2.zip <download/nim-0.10.2.zip>`_, extract it and follow
-these instructions:
+Download one of these:
+
+* `nim-0.11.0.zip (28 MB) <download/nim-0.11.0.zip>`_
+* `nim-0.11.0.tar.xz (2.6MB) <download/nim-0.11.0.tar.xz>`_
+
+Extract the file and follow these instructions:
 
 * sh build.sh
 * Add ``$your_install_dir/bin`` to your PATH.
diff --git a/web/learn.txt b/web/learn.txt
index 7a9600e57..a2df38cde 100644
--- a/web/learn.txt
+++ b/web/learn.txt
@@ -8,10 +8,10 @@ Learning Nim
 
   .. container:: tutorials
 
-    - | `Tutorial (part I) <tut1.html>`_
+    - | `Tutorial (part I) <0.11.0/tut1.html>`_
       | Learn the basics of Nim's types, variables, procedures, control flow, etc...
 
-    - | `Tutorial (part II) <tut2.html>`_
+    - | `Tutorial (part II) <0.11.0/tut2.html>`_
       | Learn Nim's more advanced features such as OOP, generics, macros, etc...
 
 
@@ -52,5 +52,5 @@ Learning Nim
 Documentation
 -------------
 
-More examples of Nim code can be found in the `Nim Language Documentation <manual.html>`_.
+More examples of Nim code can be found in the `Nim Language Documentation <0.11.0/manual.html>`_.
 
diff --git a/web/news.txt b/web/news.txt
index 6cb92b581..0f3f8def6 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -2,349 +2,399 @@
 News
 ====
 
+
+2015-04-30 Version 0.11.0 released
+==================================
+
+With this release we are one step closer to reaching version 1.0 and by
+extension the persistence of the Nim specification. As mentioned in the
+previous release notes, starting with version 1.0, we will not be introducing
+any more breaking changes to Nim.
+
+The *language* itself is very close to 1.0, the primary area that requires
+more work is the standard library.
+
+Take a look at the `download <download.html>`_ page for binaries (Windows-only)
+and 0.11.0 snapshots of the source code. The Windows installer now also
+includes `Aporia <https://github.com/nim-lang/aporia>`_,
+`Nimble <https://github.com/nim-lang/nimble>`_ and other useful tools to get
+you started with Nim.
+
+What's left to be done
+~~~~~~~~~~~~~~~~~~~~~~
+
+The 1.0 release is expected by the end of this year. Rumors say it will be in
+summer 2015. What's left:
+
+* Bug fixes, bug fixes, bug fixes, in particular:
+  - The remaining bugs of the lambda lifting pass that is responsible to enable
+    closures and closure iterators need to be fixed.
+  - ``concept`` needs to be refined, a nice name for the feature is not enough.
+  - Destructors need to be refined.
+  - ``static[T]`` needs to be fixed.
+  - Finish the implementation of the 'parallel' statement.
+* ``immediate`` templates and macros will be deprecated as these will soon be
+  completely unnecessary, instead the ``typed`` or ``untyped`` metatypes can
+  be used.
+* More of the standard library should be moved to Nimble packages and what's
+  left should use the features we have for concurrency and parallelism.
+
+
+
+Changes affecting backwards compatibility
+-----------------------------------------
+
+- Parameter names are finally properly ``gensym``'ed. This can break
+  templates though that used to rely on the fact that they are not.
+  (Bug #1915.) This means this doesn't compile anymore:
+
+.. code-block:: nim
+
+  template doIt(body: stmt) {.immediate.} =
+    # this used to inject the 'str' parameter:
+    proc res(str: string) =
+      body
+
+  doIt:
+    echo str # Error: undeclared identifier: 'str'
 ..
-  2015-03-01 Version 0.11.0 released
-  ==================================
-
-
-  Changes affecting backwards compatibility
-  -----------------------------------------
-
-  - Parameter names are finally properly ``gensym``'ed. This can break
-    templates though that used to rely on the fact that they are not.
-    (Bug #1915.) This means this doesn't compile anymore:
-
-  .. code-block:: nim
-
-    template doIt(body: stmt) {.immediate.} =
-      # this used to inject the 'str' parameter:
-      proc res(str: string) =
-        body
-
-    doIt:
-      echo str # Error: undeclared identifier: 'str'
-
-    Declare the ``doIt`` template as ``immediate, dirty`` to get the old
-    behaviour.
-  - Tuple field names are not ignored anymore, this caused too many problems
-    in practice so now the behaviour as it was for version 0.9.6: If field
-    names exist for the tuple type, they are checked.
-  - ``logging.level`` and ``logging.handlers`` are no longer exported.
-    ``addHandler``, ``getHandlers``, ``setLogFilter`` and ``getLogFilter``
-    should be used instead.
-  - ``nim idetools`` has been replaced by a separate tool `nimsuggest`_.
-  - *arrow like* operators are not right associative anymore.
-  - *arrow like* operators are now required to end with either ``->``, ``~>`` or
-    ``=>``, not just ``>``. Examples of operators still considered arrow like:
-    ``->``, ``==>``, ``+=>``. On the other hand, the following operators are now
-    considered regular operators again: ``|>``, ``-+>``, etc.
-  - Typeless parameters are now only allowed in templates and macros. The old
-    way turned out to be too error-prone.
-  - The 'addr' and 'type' operators are now parsed as unary function
-    application. This means ``type(x).name`` is now parsed as ``(type(x)).name``
-    and not as ``type((x).name)``. Note that this also affects the AST
-    structure; for immediate macro parameters ``nkCall('addr', 'x')`` is
-    produced instead of ``nkAddr('x')``.
-  - ``concept`` is now a keyword and is used instead of ``generic``.
-  - The ``inc``, ``dec``, ``+=``, ``-=`` builtins now produce OverflowError
-    exceptions. This means code like the following:
-
-  .. code-block:: nim
-    var x = low(T)
-    while x <= high(T):
-      echo x
-      inc x
-
-  Needs to be replaced by something like this:
-
-  .. code-block:: nim
-    var x = low(T).int
-    while x <= high(T).int:
-      echo x.T
-      inc x
-
-  - **Negative indexing for slicing does not work anymore!** Instead
-    of ``a[0.. -1]`` you can
-    use ``a[0.. ^1]``. This also works with accessing a single
-    element ``a[^1]``. Note that we cannot detect this reliably as it is
-    determined at **runtime** whether negative indexing is used!
-    ``a[0.. -1]`` now produces the empty string/sequence.
-  - The compiler now warns about code like ``foo +=1`` which uses inconsistent
-    spacing around binary operators. Later versions of the language will parse
-    these as unary operators instead so that ``echo $foo`` finally can do what
-    people expect it to do.
-  - ``system.untyped`` and ``system.typed`` have been introduced as aliases
-    for ``expr`` and ``stmt``. The new names capture the semantics much better
-    and most likely  ``expr`` and ``stmt`` will be deprecated in favor of the
-    new names.
-  - The ``split`` method in module ``re`` has changed. It now handles the case
-    of matches having a length of 0, and empty strings being yielded from the
-    iterator. A notable change might be that a pattern being matched at the
-    beginning and end of a string, will result in an empty string being produced
-    at the start and the end of the iterator.
-
-  Language Additions
-  ------------------
-
-  - For empty ``case object`` branches ``discard`` can finally be used instead
-    of ``nil``.
-  - Automatic dereferencing is now done for the first argument of a routine
-    call if overloading resolution produces no match otherwise. This feature
-    has to be enabled with the `experimental`_ pragma.
-  - Objects that do not use inheritance nor ``case`` can be put into ``const``
-    sections. This means that finally this is possible and produces rather
-    nice code:
-
-  .. code-block:: nim
-    import tables
-
-    const
-      foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable()
-
-
-  - Ordinary parameters can follow after a varargs parameter. This means the
-    following is finally accepted by the compiler:
-
-  .. code-block:: nim
-    template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) =
-      blck
-      echo a, b
-
-    takesBlock 1, 2, "some", 0.90, "random stuff":
-      echo "yay"
-
-  - Overloading by 'var T' is now finally possible:
-
-  .. code-block:: nim
-    proc varOrConst(x: var int) = echo "var"
-    proc varOrConst(x: int) = echo "const"
-
-    var x: int
-    varOrConst(x) # "var"
-    varOrConst(45) # "const"
-
-  - Array and seq indexing can now use the builtin ``^`` operator to access
-    things from backwards: ``a[^1]`` is like Python's ``a[-1]``.
-  - A first version of the specification and implementation of the overloading
-    of the assignment operator has arrived!
-  - ``system.len`` for strings and sequences now returns 0 for nil.
-
-  - A single underscore can now be used to discard values when unpacking tuples.
-  - ``marshal.$$`` and ``marshal.to`` can be executed at compile-time.
-  - Interoperability with C++ improved tremendously; C++'s templates and
-    operators can be wrapped directly. See `this <nimc.html#ImportCpp-pragma>`_
-    for more information.
-
-
-  Library additions
-  -----------------
-
-  - ``reversed`` proc added to the ``unicode`` module.
-  - Added multipart param to httpclient's ``post`` and ``postContent`` together
-    with a ``newMultipartData`` proc.
-  - Added `%*` operator for JSON.
-  - The compiler is now available as Nimble package for c2nim.
-  - Added ``..^`` and ``..<`` templates to system so that the rather annoying
-    space between ``.. <`` and ``.. ^`` is not necessary anymore.
-  - Added ``system.xlen`` for strings and sequences to get back the old ``len``
-    operation that doesn't check for ``nil`` for efficiency.
-
-
-  Bugfixes
-  --------
-
-  - Fixed internal compiler error when using ``char()`` in an echo call
-    (`#1788 <https://github.com/Araq/Nim/issues/1788>`_).
-  - Fixed Windows cross-compilation on Linux.
-  - Overload resolution now works for types distinguished only by a
-    ``static[int]`` param
-    (`#1056 <https://github.com/Araq/Nim/issues/1056>`_).
-  - Other fixes relating to generic types and static params.
-  - Fixed some compiler crashes with unnamed tuples
-    (`#1774 <https://github.com/Araq/Nim/issues/1774>`_).
-  - Fixed ``channels.tryRecv`` blocking
-    (`#1816 <https://github.com/Araq/Nim/issues/1816>`_).
-  - Fixed generic instantiation errors with ``typedesc``
-    (`#419 <https://github.com/Araq/Nim/issues/419>`_).
-  - Fixed generic regression where the compiler no longer detected constant
-    expressions properly (`#544 <https://github.com/Araq/Nim/issues/544>`_).
-  - Fixed internal error with generic proc using ``static[T]`` in a specific
-    way (`#1049 <https://github.com/Araq/Nim/issues/1049>`_).
-  - More fixes relating to generics
-    (`#1820 <https://github.com/Araq/Nim/issues/1820>`_,
-     `#1050 <https://github.com/Araq/Nim/issues/1050>`_,
-     `#1859 <https://github.com/Araq/Nim/issues/1859>`_,
-     `#1858 <https://github.com/Araq/Nim/issues/1858>`_).
-  - Fixed httpclient to properly encode queries.
-  - Many fixes to the ``uri`` module.
-  - Async sockets are now closed on error.
-  - Fixes to httpclient's handling of multipart data.
-  - Fixed GC segfaults with asynchronous sockets
-    (`#1796 <https://github.com/Araq/Nim/issues/1796>`_).
-  - Added more versions to openssl's DLL version list
-    (`076f993 <https://github.com/Araq/Nim/commit/076f993>`_).
-  - Fixed shallow copy in iterators being broken
-    (`#1803 <https://github.com/Araq/Nim/issues/1803>`_).
-  - ``nil`` can now be inserted into tables with the ``db_sqlite`` module
-    (`#1866 <https://github.com/Araq/Nim/issues/1866>`_).
-  - Fixed "Incorrect assembler generated"
-    (`#1907 <https://github.com/Araq/Nim/issues/1907>`_)
-  - Fixed "Expression templates that define macros are unusable in some contexts"
-    (`#1903 <https://github.com/Araq/Nim/issues/1903>`_)
-  - Fixed "a second level generic subclass causes the compiler to crash"
-    (`#1919 <https://github.com/Araq/Nim/issues/1919>`_)
-  - Fixed "nim 0.10.2 generates invalid AsyncHttpClient C code for MSVC "
-    (`#1901 <https://github.com/Araq/Nim/issues/1901>`_)
-  - Fixed "1 shl n produces wrong C code"
-    (`#1928 <https://github.com/Araq/Nim/issues/1928>`_)
-  - Fixed "Internal error on tuple yield"
-    (`#1838 <https://github.com/Araq/Nim/issues/1838>`_)
-  - Fixed "ICE with template"
-    (`#1915 <https://github.com/Araq/Nim/issues/1915>`_)
-  - Fixed "include the tool directory in the installer as it is required by koch"
-    (`#1947 <https://github.com/Araq/Nim/issues/1947>`_)
-  - Fixed "Can't compile if file location contains spaces on Windows"
-    (`#1955 <https://github.com/Araq/Nim/issues/1955>`_)
-  - Fixed "List comprehension macro only supports infix checks as guards"
-    (`#1920 <https://github.com/Araq/Nim/issues/1920>`_)
-  - Fixed "wrong field names of compatible tuples in generic types"
-    (`#1910 <https://github.com/Araq/Nim/issues/1910>`_)
-  - Fixed "Macros within templates no longer work as expected"
-    (`#1944 <https://github.com/Araq/Nim/issues/1944>`_)
-  - Fixed "Compiling for Standalone AVR broken in 0.10.2"
-    (`#1964 <https://github.com/Araq/Nim/issues/1964>`_)
-  - Fixed "Compiling for Standalone AVR broken in 0.10.2"
-    (`#1964 <https://github.com/Araq/Nim/issues/1964>`_)
-  - Fixed "Code generation for mitems with tuple elements"
-    (`#1833 <https://github.com/Araq/Nim/issues/1833>`_)
-  - Fixed "httpclient.HttpMethod should not be an enum"
-    (`#1962 <https://github.com/Araq/Nim/issues/1962>`_)
-  - Fixed "terminal / eraseScreen() throws an OverflowError"
-    (`#1906 <https://github.com/Araq/Nim/issues/1906>`_)
-  - Fixed "setControlCHook(nil) disables registered quit procs"
-    (`#1546 <https://github.com/Araq/Nim/issues/1546>`_)
-  - Fixed "Unexpected idetools behaviour"
-    (`#325 <https://github.com/Araq/Nim/issues/325>`_)
-  - Fixed "Unused lifted lambda does not compile"
-    (`#1642 <https://github.com/Araq/Nim/issues/1642>`_)
-  - Fixed "'low' and 'high' don't work with cstring asguments"
-    (`#2030 <https://github.com/Araq/Nim/issues/2030>`_)
-  - Fixed "Converting to int does not round in JS backend"
-    (`#1959 <https://github.com/Araq/Nim/issues/1959>`_)
-  - Fixed "Internal error genRecordField 2 when adding region to pointer."
-    (`#2039 <https://github.com/Araq/Nim/issues/2039>`_)
-  - Fixed "Macros fail to compile when compiled with --os:standalone"
-    (`#2041 <https://github.com/Araq/Nim/issues/2041>`_)
-  - Fixed "Reading from {.compileTime.} variables can cause code generation to fail"
-    (`#2022 <https://github.com/Araq/Nim/issues/2022>`_)
-  - Fixed "Passing overloaded symbols to templates fails inside generic procedures"
-    (`#1988 <https://github.com/Araq/Nim/issues/1988>`_)
-  - Fixed "Compiling iterator with object assignment in release mode causes "var not init""
-    (`#2023 <https://github.com/Araq/Nim/issues/2023>`_)
-  - Fixed "calling a large number of macros doing some computation fails"
-    (`#1989 <https://github.com/Araq/Nim/issues/1989>`_)
-  - Fixed "Can't get Koch to install nim under Windows"
-    (`#2061 <https://github.com/Araq/Nim/issues/2061>`_)
-  - Fixed "Template with two stmt parameters segfaults compiler"
-    (`#2057 <https://github.com/Araq/Nim/issues/2057>`_)
-  - Fixed "`noSideEffect` not affected by `echo`"
-    (`#2011 <https://github.com/Araq/Nim/issues/2011>`_)
-  - Fixed "Compiling with the cpp backend ignores --passc"
-    (`#1601 <https://github.com/Araq/Nim/issues/1601>`_)
-  - Fixed "Put untyped procedure parameters behind the experimental pragma"
-    (`#1956 <https://github.com/Araq/Nim/issues/1956>`_)
-  - Fixed "generic regression"
-    (`#2073 <https://github.com/Araq/Nim/issues/2073>`_)
-  - Fixed "generic regression"
-    (`#2073 <https://github.com/Araq/Nim/issues/2073>`_)
-  - Fixed "Regression in template lookup with generics"
-    (`#2004 <https://github.com/Araq/Nim/issues/2004>`_)
-  - Fixed "GC's growObj is wrong for edge cases"
-    (`#2070 <https://github.com/Araq/Nim/issues/2070>`_)
-  - Fixed "Compiler internal error when creating an array out of a typeclass"
-    (`#1131 <https://github.com/Araq/Nim/issues/1131>`_)
-  - Fixed "GC's growObj is wrong for edge cases"
-    (`#2070 <https://github.com/Araq/Nim/issues/2070>`_)
-  - Fixed "Invalid Objective-C code generated when calling class method"
-    (`#2068 <https://github.com/Araq/Nim/issues/2068>`_)
-  - Fixed "walkDirRec Error"
-    (`#2116 <https://github.com/Araq/Nim/issues/2116>`_)
-  - Fixed "Typo in code causes compiler SIGSEGV in evalAtCompileTime"
-    (`#2113 <https://github.com/Araq/Nim/issues/2113>`_)
-  - Fixed "Regression on exportc"
-    (`#2118 <https://github.com/Araq/Nim/issues/2118>`_)
-  - Fixed "Error message"
-    (`#2102 <https://github.com/Araq/Nim/issues/2102>`_)
-  - Fixed "hint[path] = off not working in nim.cfg"
-    (`#2103 <https://github.com/Araq/Nim/issues/2103>`_)
-  - Fixed "compiler crashes when getting a tuple from a sequence of generic tuples"
-    (`#2121 <https://github.com/Araq/Nim/issues/2121>`_)
-  - Fixed "nim check hangs with when"
-    (`#2123 <https://github.com/Araq/Nim/issues/2123>`_)
-  - Fixed "static[T] param in nested type resolve/caching issue"
-    (`#2125 <https://github.com/Araq/Nim/issues/2125>`_)
-  - Fixed "repr should display ``\0``"
-    (`#2124 <https://github.com/Araq/Nim/issues/2124>`_)
-  - Fixed "'nim check' never ends in case of recursive dependency "
-    (`#2051 <https://github.com/Araq/Nim/issues/2051>`_)
-  - Fixed "From macros: Error: unhandled exception: sons is not accessible"
-    (`#2167 <https://github.com/Araq/Nim/issues/2167>`_)
-  - Fixed "`fieldPairs` doesn't work inside templates"
-    (`#1902 <https://github.com/Araq/Nim/issues/1902>`_)
-  - Fixed "fields iterator misbehavior on break statement"
-    (`#2134 <https://github.com/Araq/Nim/issues/2134>`_)
-  - Fixed "Fix for compiler not building anymore since #c3244ef1ff"
-    (`#2193 <https://github.com/Araq/Nim/issues/2193>`_)
-  - Fixed "JSON parser fails in cpp output mode"
-    (`#2199 <https://github.com/Araq/Nim/issues/2199>`_)
-  - Fixed "macros.getType mishandles void return"
-    (`#2211 <https://github.com/Araq/Nim/issues/2211>`_)
-  - Fixed "Regression involving templates instantiated within generics"
-    (`#2215 <https://github.com/Araq/Nim/issues/2215>`_)
-  - Fixed ""Error: invalid type" for 'not nil' on generic type."
-    (`#2216 <https://github.com/Araq/Nim/issues/2216>`_)
-  - Fixed "--threads:on breaks async"
-    (`#2074 <https://github.com/Araq/Nim/issues/2074>`_)
-  - Fixed "Type mismatch not always caught, can generate bad code for C backend."
-    (`#2169 <https://github.com/Araq/Nim/issues/2169>`_)
-  - Fixed "Failed C compilation when storing proc to own type in object"
-    (`#2233 <https://github.com/Araq/Nim/issues/2233>`_)
-  - Fixed "Unknown line/column number in constant declaration type conversion error"
-    (`#2252 <https://github.com/Araq/Nim/issues/2252>`_)
-  - Fixed "Adding {.compile.} fails if nimcache already exists."
-    (`#2247 <https://github.com/Araq/Nim/issues/2247>`_)
-  - Fixed "Two different type names generated for a single type (C backend)"
-    (`#2250 <https://github.com/Araq/Nim/issues/2250>`_)
-  - Fixed "Ambigous call when it should not be"
-    (`#2229 <https://github.com/Araq/Nim/issues/2229>`_)
-  - Fixed "Make sure we can load root urls"
-    (`#2227 <https://github.com/Araq/Nim/issues/2227>`_)
-  - Fixed "Failure to slice a string with an int subrange type"
-    (`#794 <https://github.com/Araq/Nim/issues/794>`_)
-  - Fixed "documentation error"
-    (`#2205 <https://github.com/Araq/Nim/issues/2205>`_)
-  - Fixed "Code growth when using `const`"
-    (`#1940 <https://github.com/Araq/Nim/issues/1940>`_)
-  - Fixed "Instances of generic types confuse overload resolution"
-    (`#2220 <https://github.com/Araq/Nim/issues/2220>`_)
-  - Fixed "Compiler error when initializing sdl2's EventType"
-    (`#2316 <https://github.com/Araq/Nim/issues/2316>`_)
-  - Fixed "Parallel disjoint checking can't handle `<`, `items`, or arrays"
-    (`#2287 <https://github.com/Araq/Nim/issues/2287>`_)
-  - Fixed "Strings aren't copied in parallel loop"
-    (`#2286 <https://github.com/Araq/Nim/issues/2286>`_)
-  - Fixed "JavaScript compiler crash with tables"
-    (`#2298 <https://github.com/Araq/Nim/issues/2298>`_)
-  - Fixed "Range checker too restrictive"
-    (`#1845 <https://github.com/Araq/Nim/issues/1845>`_)
-  - Fixed "Failure to slice a string with an int subrange type"
-    (`#794 <https://github.com/Araq/Nim/issues/794>`_)
-  - Fixed "Remind user when compiling in debug mode"
-    (`#1868 <https://github.com/Araq/Nim/issues/1868>`_)
-  - Fixed "Compiler user guide has jumbled options/commands."
-    (`#1819 <https://github.com/Araq/Nim/issues/1819>`_)
-  - Fixed "using `method`: 1 in a objects constructor fails when compiling"
-    (`#1791 <https://github.com/Araq/Nim/issues/1791>`_)
+
+  This used to inject the ``str`` parameter into the scope of the body.
+  Declare the ``doIt`` template as ``immediate, dirty`` to get the old
+  behaviour.
+- Tuple field names are not ignored anymore, this caused too many problems
+  in practice so now the behaviour is as it was for version 0.9.6: If field
+  names exist for the tuple type, they are checked.
+- ``logging.level`` and ``logging.handlers`` are no longer exported.
+  ``addHandler``, ``getHandlers``, ``setLogFilter`` and ``getLogFilter``
+  should be used instead.
+- ``nim idetools`` has been replaced by a separate
+  tool `nimsuggest <0.11.0/nimsuggest.html>`_.
+- *arrow like* operators are not right associative anymore and are required
+  to end with either ``->``, ``~>`` or
+  ``=>``, not just ``>``. Examples of operators still considered arrow like:
+  ``->``, ``==>``, ``+=>``. On the other hand, the following operators are now
+  considered regular operators again: ``|>``, ``-+>``, etc.
+- Typeless parameters are now only allowed in templates and macros. The old
+  way turned out to be too error-prone.
+- The 'addr' and 'type' operators are now parsed as unary function
+  application. This means ``type(x).name`` is now parsed as ``(type(x)).name``
+  and not as ``type((x).name)``. Note that this also affects the AST
+  structure; for immediate macro parameters ``nkCall('addr', 'x')`` is
+  produced instead of ``nkAddr('x')``.
+- ``concept`` is now a keyword and is used instead of ``generic``.
+- The ``inc``, ``dec``, ``+=``, ``-=`` builtins now produce OverflowError
+  exceptions. This means code like the following:
+
+.. code-block:: nim
+  var x = low(T)
+  while x <= high(T):
+    echo x
+    inc x
+
+Needs to be replaced by something like this:
+
+.. code-block:: nim
+  var x = low(T).int
+  while x <= high(T).int:
+    echo x.T
+    inc x
+
+- **Negative indexing for slicing does not work anymore!** Instead
+  of ``a[0.. -1]`` you can
+  use ``a[0.. ^1]``. This also works with accessing a single
+  element ``a[^1]``. Note that we cannot detect this reliably as it is
+  determined at **runtime** whether negative indexing is used!
+  ``a[0.. -1]`` now produces the empty string/sequence.
+- The compiler now warns about code like ``foo +=1`` which uses inconsistent
+  spacing around binary operators. Later versions of the language will parse
+  these as unary operators instead so that ``echo $foo`` finally can do what
+  people expect it to do.
+- ``system.untyped`` and ``system.typed`` have been introduced as aliases
+  for ``expr`` and ``stmt``. The new names capture the semantics much better
+  and most likely  ``expr`` and ``stmt`` will be deprecated in favor of the
+  new names.
+- The ``split`` method in module ``re`` has changed. It now handles the case
+  of matches having a length of 0, and empty strings being yielded from the
+  iterator. A notable change might be that a pattern being matched at the
+  beginning and end of a string, will result in an empty string being produced
+  at the start and the end of the iterator.
+- The compiler and nimsuggest now count columns starting with 1, not 0 for
+  consistency with the rest of the world.
+
+
+Language Additions
+------------------
+
+- For empty ``case object`` branches ``discard`` can finally be used instead
+  of ``nil``.
+- Automatic dereferencing is now done for the first argument of a routine
+  call if overloading resolution produces no match otherwise. This feature
+  has to be enabled with
+  the `experimental <0.11.0/manual.html#pragmas-experimental-pragma>`_ pragma.
+- Objects that do not use inheritance nor ``case`` can be put into ``const``
+  sections. This means that finally this is possible and produces rather
+  nice code:
+
+.. code-block:: nim
+  import tables
+
+  const
+    foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable()
+
+
+- Ordinary parameters can follow after a varargs parameter. This means the
+  following is finally accepted by the compiler:
+
+.. code-block:: nim
+  template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) =
+    blck
+    echo a, b
+
+  takesBlock 1, 2, "some", 0.90, "random stuff":
+    echo "yay"
+
+- Overloading by 'var T' is now finally possible:
+
+.. code-block:: nim
+  proc varOrConst(x: var int) = echo "var"
+  proc varOrConst(x: int) = echo "const"
+
+  var x: int
+  varOrConst(x) # "var"
+  varOrConst(45) # "const"
+
+- Array and seq indexing can now use the builtin ``^`` operator to access
+  things from backwards: ``a[^1]`` is like Python's ``a[-1]``.
+- A first version of the specification and implementation of the overloading
+  of the assignment operator has arrived!
+- ``system.len`` for strings and sequences now returns 0 for nil.
+
+- A single underscore can now be used to discard values when unpacking tuples:
+
+.. code-block:: nim
+  let (path, _, _) = os.splitFile("path/file.ext")
+
+
+- ``marshal.$$`` and ``marshal.to`` can be executed at compile-time.
+- Interoperability with C++ improved tremendously; C++'s templates and
+  operators can be wrapped directly. See
+  `this <0.11.0/nimc.html#additional-features-importcpp-pragma>`_
+  for more information.
+- ``macros.getType`` can be used to query an AST's type at compile-time. This
+  enables more powerful macros, for instance *currying* can now be done with
+  a macro.
+
+
+Library additions
+-----------------
+
+- ``reversed`` proc added to the ``unicode`` module.
+- Added multipart param to httpclient's ``post`` and ``postContent`` together
+  with a ``newMultipartData`` proc.
+- Added `%*` operator for JSON.
+- The compiler is now available as Nimble package for c2nim.
+- Added ``..^`` and ``..<`` templates to system so that the rather annoying
+  space between ``.. <`` and ``.. ^`` is not necessary anymore.
+- Added ``system.xlen`` for strings and sequences to get back the old ``len``
+  operation that doesn't check for ``nil`` for efficiency.
+
+
+Bugfixes
+--------
+
+- Fixed internal compiler error when using ``char()`` in an echo call
+  (`#1788 <https://github.com/Araq/Nim/issues/1788>`_).
+- Fixed Windows cross-compilation on Linux.
+- Overload resolution now works for types distinguished only by a
+  ``static[int]`` param
+  (`#1056 <https://github.com/Araq/Nim/issues/1056>`_).
+- Other fixes relating to generic types and static params.
+- Fixed some compiler crashes with unnamed tuples
+  (`#1774 <https://github.com/Araq/Nim/issues/1774>`_).
+- Fixed ``channels.tryRecv`` blocking
+  (`#1816 <https://github.com/Araq/Nim/issues/1816>`_).
+- Fixed generic instantiation errors with ``typedesc``
+  (`#419 <https://github.com/Araq/Nim/issues/419>`_).
+- Fixed generic regression where the compiler no longer detected constant
+  expressions properly (`#544 <https://github.com/Araq/Nim/issues/544>`_).
+- Fixed internal error with generic proc using ``static[T]`` in a specific
+  way (`#1049 <https://github.com/Araq/Nim/issues/1049>`_).
+- More fixes relating to generics (`#1820 <https://github.com/Araq/Nim/issues/1820>`_,
+  `#1050 <https://github.com/Araq/Nim/issues/1050>`_,
+  `#1859 <https://github.com/Araq/Nim/issues/1859>`_,
+  `#1858 <https://github.com/Araq/Nim/issues/1858>`_).
+- Fixed httpclient to properly encode queries.
+- Many fixes to the ``uri`` module.
+- Async sockets are now closed on error.
+- Fixes to httpclient's handling of multipart data.
+- Fixed GC segfaults with asynchronous sockets
+  (`#1796 <https://github.com/Araq/Nim/issues/1796>`_).
+- Added more versions to openssl's DLL version list
+  (`076f993 <https://github.com/Araq/Nim/commit/076f993>`_).
+- Fixed shallow copy in iterators being broken
+  (`#1803 <https://github.com/Araq/Nim/issues/1803>`_).
+- ``nil`` can now be inserted into tables with the ``db_sqlite`` module
+  (`#1866 <https://github.com/Araq/Nim/issues/1866>`_).
+- Fixed "Incorrect assembler generated"
+  (`#1907 <https://github.com/Araq/Nim/issues/1907>`_)
+- Fixed "Expression templates that define macros are unusable in some contexts"
+  (`#1903 <https://github.com/Araq/Nim/issues/1903>`_)
+- Fixed "a second level generic subclass causes the compiler to crash"
+  (`#1919 <https://github.com/Araq/Nim/issues/1919>`_)
+- Fixed "nim 0.10.2 generates invalid AsyncHttpClient C code for MSVC "
+  (`#1901 <https://github.com/Araq/Nim/issues/1901>`_)
+- Fixed "1 shl n produces wrong C code"
+  (`#1928 <https://github.com/Araq/Nim/issues/1928>`_)
+- Fixed "Internal error on tuple yield"
+  (`#1838 <https://github.com/Araq/Nim/issues/1838>`_)
+- Fixed "ICE with template"
+  (`#1915 <https://github.com/Araq/Nim/issues/1915>`_)
+- Fixed "include the tool directory in the installer as it is required by koch"
+  (`#1947 <https://github.com/Araq/Nim/issues/1947>`_)
+- Fixed "Can't compile if file location contains spaces on Windows"
+  (`#1955 <https://github.com/Araq/Nim/issues/1955>`_)
+- Fixed "List comprehension macro only supports infix checks as guards"
+  (`#1920 <https://github.com/Araq/Nim/issues/1920>`_)
+- Fixed "wrong field names of compatible tuples in generic types"
+  (`#1910 <https://github.com/Araq/Nim/issues/1910>`_)
+- Fixed "Macros within templates no longer work as expected"
+  (`#1944 <https://github.com/Araq/Nim/issues/1944>`_)
+- Fixed "Compiling for Standalone AVR broken in 0.10.2"
+  (`#1964 <https://github.com/Araq/Nim/issues/1964>`_)
+- Fixed "Compiling for Standalone AVR broken in 0.10.2"
+  (`#1964 <https://github.com/Araq/Nim/issues/1964>`_)
+- Fixed "Code generation for mitems with tuple elements"
+  (`#1833 <https://github.com/Araq/Nim/issues/1833>`_)
+- Fixed "httpclient.HttpMethod should not be an enum"
+  (`#1962 <https://github.com/Araq/Nim/issues/1962>`_)
+- Fixed "terminal / eraseScreen() throws an OverflowError"
+  (`#1906 <https://github.com/Araq/Nim/issues/1906>`_)
+- Fixed "setControlCHook(nil) disables registered quit procs"
+  (`#1546 <https://github.com/Araq/Nim/issues/1546>`_)
+- Fixed "Unexpected idetools behaviour"
+  (`#325 <https://github.com/Araq/Nim/issues/325>`_)
+- Fixed "Unused lifted lambda does not compile"
+  (`#1642 <https://github.com/Araq/Nim/issues/1642>`_)
+- Fixed "'low' and 'high' don't work with cstring asguments"
+  (`#2030 <https://github.com/Araq/Nim/issues/2030>`_)
+- Fixed "Converting to int does not round in JS backend"
+  (`#1959 <https://github.com/Araq/Nim/issues/1959>`_)
+- Fixed "Internal error genRecordField 2 when adding region to pointer."
+  (`#2039 <https://github.com/Araq/Nim/issues/2039>`_)
+- Fixed "Macros fail to compile when compiled with --os:standalone"
+  (`#2041 <https://github.com/Araq/Nim/issues/2041>`_)
+- Fixed "Reading from {.compileTime.} variables can cause code generation to fail"
+  (`#2022 <https://github.com/Araq/Nim/issues/2022>`_)
+- Fixed "Passing overloaded symbols to templates fails inside generic procedures"
+  (`#1988 <https://github.com/Araq/Nim/issues/1988>`_)
+- Fixed "Compiling iterator with object assignment in release mode causes "var not init""
+  (`#2023 <https://github.com/Araq/Nim/issues/2023>`_)
+- Fixed "calling a large number of macros doing some computation fails"
+  (`#1989 <https://github.com/Araq/Nim/issues/1989>`_)
+- Fixed "Can't get Koch to install nim under Windows"
+  (`#2061 <https://github.com/Araq/Nim/issues/2061>`_)
+- Fixed "Template with two stmt parameters segfaults compiler"
+  (`#2057 <https://github.com/Araq/Nim/issues/2057>`_)
+- Fixed "`noSideEffect` not affected by `echo`"
+  (`#2011 <https://github.com/Araq/Nim/issues/2011>`_)
+- Fixed "Compiling with the cpp backend ignores --passc"
+  (`#1601 <https://github.com/Araq/Nim/issues/1601>`_)
+- Fixed "Put untyped procedure parameters behind the experimental pragma"
+  (`#1956 <https://github.com/Araq/Nim/issues/1956>`_)
+- Fixed "generic regression"
+  (`#2073 <https://github.com/Araq/Nim/issues/2073>`_)
+- Fixed "generic regression"
+  (`#2073 <https://github.com/Araq/Nim/issues/2073>`_)
+- Fixed "Regression in template lookup with generics"
+  (`#2004 <https://github.com/Araq/Nim/issues/2004>`_)
+- Fixed "GC's growObj is wrong for edge cases"
+  (`#2070 <https://github.com/Araq/Nim/issues/2070>`_)
+- Fixed "Compiler internal error when creating an array out of a typeclass"
+  (`#1131 <https://github.com/Araq/Nim/issues/1131>`_)
+- Fixed "GC's growObj is wrong for edge cases"
+  (`#2070 <https://github.com/Araq/Nim/issues/2070>`_)
+- Fixed "Invalid Objective-C code generated when calling class method"
+  (`#2068 <https://github.com/Araq/Nim/issues/2068>`_)
+- Fixed "walkDirRec Error"
+  (`#2116 <https://github.com/Araq/Nim/issues/2116>`_)
+- Fixed "Typo in code causes compiler SIGSEGV in evalAtCompileTime"
+  (`#2113 <https://github.com/Araq/Nim/issues/2113>`_)
+- Fixed "Regression on exportc"
+  (`#2118 <https://github.com/Araq/Nim/issues/2118>`_)
+- Fixed "Error message"
+  (`#2102 <https://github.com/Araq/Nim/issues/2102>`_)
+- Fixed "hint[path] = off not working in nim.cfg"
+  (`#2103 <https://github.com/Araq/Nim/issues/2103>`_)
+- Fixed "compiler crashes when getting a tuple from a sequence of generic tuples"
+  (`#2121 <https://github.com/Araq/Nim/issues/2121>`_)
+- Fixed "nim check hangs with when"
+  (`#2123 <https://github.com/Araq/Nim/issues/2123>`_)
+- Fixed "static[T] param in nested type resolve/caching issue"
+  (`#2125 <https://github.com/Araq/Nim/issues/2125>`_)
+- Fixed "repr should display ``\0``"
+  (`#2124 <https://github.com/Araq/Nim/issues/2124>`_)
+- Fixed "'nim check' never ends in case of recursive dependency "
+  (`#2051 <https://github.com/Araq/Nim/issues/2051>`_)
+- Fixed "From macros: Error: unhandled exception: sons is not accessible"
+  (`#2167 <https://github.com/Araq/Nim/issues/2167>`_)
+- Fixed "`fieldPairs` doesn't work inside templates"
+  (`#1902 <https://github.com/Araq/Nim/issues/1902>`_)
+- Fixed "fields iterator misbehavior on break statement"
+  (`#2134 <https://github.com/Araq/Nim/issues/2134>`_)
+- Fixed "Fix for compiler not building anymore since #c3244ef1ff"
+  (`#2193 <https://github.com/Araq/Nim/issues/2193>`_)
+- Fixed "JSON parser fails in cpp output mode"
+  (`#2199 <https://github.com/Araq/Nim/issues/2199>`_)
+- Fixed "macros.getType mishandles void return"
+  (`#2211 <https://github.com/Araq/Nim/issues/2211>`_)
+- Fixed "Regression involving templates instantiated within generics"
+  (`#2215 <https://github.com/Araq/Nim/issues/2215>`_)
+- Fixed ""Error: invalid type" for 'not nil' on generic type."
+  (`#2216 <https://github.com/Araq/Nim/issues/2216>`_)
+- Fixed "--threads:on breaks async"
+  (`#2074 <https://github.com/Araq/Nim/issues/2074>`_)
+- Fixed "Type mismatch not always caught, can generate bad code for C backend."
+  (`#2169 <https://github.com/Araq/Nim/issues/2169>`_)
+- Fixed "Failed C compilation when storing proc to own type in object"
+  (`#2233 <https://github.com/Araq/Nim/issues/2233>`_)
+- Fixed "Unknown line/column number in constant declaration type conversion error"
+  (`#2252 <https://github.com/Araq/Nim/issues/2252>`_)
+- Fixed "Adding {.compile.} fails if nimcache already exists."
+  (`#2247 <https://github.com/Araq/Nim/issues/2247>`_)
+- Fixed "Two different type names generated for a single type (C backend)"
+  (`#2250 <https://github.com/Araq/Nim/issues/2250>`_)
+- Fixed "Ambigous call when it should not be"
+  (`#2229 <https://github.com/Araq/Nim/issues/2229>`_)
+- Fixed "Make sure we can load root urls"
+  (`#2227 <https://github.com/Araq/Nim/issues/2227>`_)
+- Fixed "Failure to slice a string with an int subrange type"
+  (`#794 <https://github.com/Araq/Nim/issues/794>`_)
+- Fixed "documentation error"
+  (`#2205 <https://github.com/Araq/Nim/issues/2205>`_)
+- Fixed "Code growth when using `const`"
+  (`#1940 <https://github.com/Araq/Nim/issues/1940>`_)
+- Fixed "Instances of generic types confuse overload resolution"
+  (`#2220 <https://github.com/Araq/Nim/issues/2220>`_)
+- Fixed "Compiler error when initializing sdl2's EventType"
+  (`#2316 <https://github.com/Araq/Nim/issues/2316>`_)
+- Fixed "Parallel disjoint checking can't handle `<`, `items`, or arrays"
+  (`#2287 <https://github.com/Araq/Nim/issues/2287>`_)
+- Fixed "Strings aren't copied in parallel loop"
+  (`#2286 <https://github.com/Araq/Nim/issues/2286>`_)
+- Fixed "JavaScript compiler crash with tables"
+  (`#2298 <https://github.com/Araq/Nim/issues/2298>`_)
+- Fixed "Range checker too restrictive"
+  (`#1845 <https://github.com/Araq/Nim/issues/1845>`_)
+- Fixed "Failure to slice a string with an int subrange type"
+  (`#794 <https://github.com/Araq/Nim/issues/794>`_)
+- Fixed "Remind user when compiling in debug mode"
+  (`#1868 <https://github.com/Araq/Nim/issues/1868>`_)
+- Fixed "Compiler user guide has jumbled options/commands."
+  (`#1819 <https://github.com/Araq/Nim/issues/1819>`_)
+- Fixed "using `method`: 1 in a objects constructor fails when compiling"
+  (`#1791 <https://github.com/Araq/Nim/issues/1791>`_)
+
 
 2014-12-29 Version 0.10.2 released
 ==================================
diff --git a/web/ticker.txt b/web/ticker.txt
index 724d29231..799246521 100644
--- a/web/ticker.txt
+++ b/web/ticker.txt
@@ -1,13 +1,13 @@
+<a class="news" href="news.html#Z2015-04-30-version-0-11-0-released">
+  <h4>Apr 30, 2015</h4>
+  <p>Nim version 0.11.0 has been released!</p>
+</a>
+
 <a class="news" href="news.html#Z2014-12-29-version-0-10-2-released">
   <h4>Dec 29, 2014</h4>
   <p>Nim version 0.10.2 has been released!</p>
 </a>
 
-<a class="news" href="news.html#Z2014-12-09-new-website-design">
-  <h4>Dec 9, 2014</h4>
-  <p>The new website design and forum are now online!</p>
-</a>
-
 <a class="news" href="news.html#Z2014-02-11-nimrod-featured-in-dr-dobb-s-journal">
   <h4>Feb 11, 2014</h4>
   <p>Nimrod featured in Dr. Dobb's Journal</p>
diff --git a/web/website.ini b/web/website.ini
index 6266f05bb..bb9f1b204 100644
--- a/web/website.ini
+++ b/web/website.ini
@@ -31,7 +31,7 @@ file: ticker.txt
 [Documentation]
 doc: "endb;intern;apis;lib;manual.txt;tut1;tut2;nimc;overview;filters"
 doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt"
-doc: "nimfix.txt"
+doc: "nimfix.txt;nimsuggest.txt"
 pdf: "manual.txt;lib;tut1;tut2;nimc;niminst;gc"
 srcdoc2: "system.nim"
 srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned"
@@ -49,7 +49,7 @@ srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor"
 srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
 srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes"
 srcdoc2: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics"
-srcdoc2: "impure/rdstdin"
+srcdoc2: "impure/rdstdin;impure/dialogs"
 srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
 srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/encodings"
 srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies"
@@ -60,7 +60,7 @@ srcdoc2: "packages/docutils/rst;packages/docutils/rstast"
 srcdoc2: "packages/docutils/rstgen;pure/logging;pure/asyncdispatch;pure/asyncnet"
 srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future"
 srcdoc2: "pure/asyncfile"
-srcdoc2: "pure/md5"
+srcdoc2: "pure/md5;pure/rationals"
 srcdoc2: "posix/posix"
 srcdoc2: "pure/fenv"
 srcdoc2: "pure/basic2d;pure/basic3d"