summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgtypes.nim6
-rw-r--r--compiler/installer.ini4
-rw-r--r--compiler/semgnrc.nim4
-rw-r--r--config/nim.cfg5
-rw-r--r--koch.nim12
-rw-r--r--lib/pure/httpcore.nim4
-rw-r--r--tests/tuples/tuple_with_nil.nim2
-rw-r--r--tools/niminst/buildsh.tmpl38
-rw-r--r--tools/niminst/deinstall.tmpl25
-rw-r--r--tools/niminst/install.tmpl49
-rw-r--r--tools/niminst/makefile.tmpl6
-rw-r--r--tools/niminst/niminst.nim33
-rw-r--r--web/download.rst49
13 files changed, 171 insertions, 66 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 65e9af6c8..0e4080c5d 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -244,7 +244,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
     NumericalTypeToStr: array[tyInt..tyUInt64, string] = [
       "NI", "NI8", "NI16", "NI32", "NI64",
       "NF", "NF32", "NF64", "NF128",
-      "NU", "NU8", "NU16", "NU32", "NU64",]
+      "NU", "NU8", "NU16", "NU32", "NU64"]
   case typ.kind
   of tyPointer:
     result = typeNameOrLiteral(typ, "void*")
@@ -477,7 +477,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
   else:
     addf(result, " {$n", [name])
 
-  var desc = getRecordFields(m, typ, check)
+  let desc = getRecordFields(m, typ, check)
   if desc == nil and not hasField:
     addf(result, "char dummy;$n", [])
   else:
@@ -573,11 +573,13 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
     result = getTypeDescWeak(m, t.sons[0], check) & "*"
     idTablePut(m.typeCache, t, result)
   of tyRange, tyEnum:
+    let orig = t
     let t = if t.kind == tyRange: t.lastSon else: t
     result = getTypeName(t)
     if not (isImportedCppType(t) or
         (sfImportc in t.sym.flags and t.sym.magic == mNone)):
       idTablePut(m.typeCache, t, result)
+      if t != orig: idTablePut(m.typeCache, orig, result)
       var size: int
       if firstOrd(t) < 0:
         addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result])
diff --git a/compiler/installer.ini b/compiler/installer.ini
index 12d9baf82..74747cc9f 100644
--- a/compiler/installer.ini
+++ b/compiler/installer.ini
@@ -279,3 +279,7 @@ buildDepends: "gcc (>= 4:4.3.2)"
 pkgDepends: "gcc (>= 4:4.3.2)"
 shortDesc: "The Nim Compiler"
 licenses: "bin/nim,MIT;lib/*,MIT;"
+
+[nimble]
+pkgName: "compiler"
+pkgFiles: "compiler/*;doc/basicopt.txt;doc/advopt.txt"
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index 6651de78e..0ba76ccd3 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -205,7 +205,7 @@ proc semGenericStmt(c: PContext, n: PNode,
         if macroToExpand(s):
           styleCheckUse(fn.info, s)
           result = semMacroExpr(c, n, n, s, {efNoSemCheck})
-          result = semGenericStmt(c, result, {}, ctx)
+          result = semGenericStmt(c, result, flags, ctx)
         else:
           n.sons[0] = symChoice(c, fn, s, scOption)
           result = n
@@ -214,7 +214,7 @@ proc semGenericStmt(c: PContext, n: PNode,
         if macroToExpand(s):
           styleCheckUse(fn.info, s)
           result = semTemplateExpr(c, n, s, {efNoSemCheck})
-          result = semGenericStmt(c, result, {}, ctx)
+          result = semGenericStmt(c, result, flags, ctx)
         else:
           n.sons[0] = symChoice(c, fn, s, scOption)
           result = n
diff --git a/config/nim.cfg b/config/nim.cfg
index b8608b3ce..93b847784 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -44,6 +44,11 @@ path="$lib/pure"
 
 @if nimbabel:
   nimblepath="$home/.nimble/pkgs/"
+  @if not windows:
+    nimblepath="/opt/nimble/pkgs/"
+  @else:
+    # TODO:
+  @end
 @end
 
 @if release or quick:
diff --git a/koch.nim b/koch.nim
index e8b08c5d2..7ee86c64c 100644
--- a/koch.nim
+++ b/koch.nim
@@ -79,9 +79,17 @@ proc findNim(): string =
   # assume there is a symlink to the exe or something:
   return nim
 
-proc exec(cmd: string, errorcode: int = QuitFailure) =
+proc exec(cmd: string, errorcode: int = QuitFailure, additionalPATH = "") =
+  let prevPATH = getEnv("PATH")
+  if additionalPATH.len > 0:
+    var absolute = additionalPATH
+    if not absolute.isAbsolute:
+      absolute = getCurrentDir() / absolute
+    echo("Adding to $PATH: ", absolute)
+    putEnv("PATH", prevPATH & PathSep & absolute)
   echo(cmd)
   if execShellCmd(cmd) != 0: quit("FAILURE", errorcode)
+  putEnv("PATH", prevPATH)
 
 proc tryExec(cmd: string): bool =
   echo(cmd)
@@ -146,7 +154,7 @@ proc website(args: string) =
 
 proc pdf(args="") =
   exec("$# cc -r tools/nimweb.nim $# --pdf web/website.ini --putenv:nimversion=$#" %
-       [findNim(), args, VersionAsString])
+       [findNim(), args, VersionAsString], additionalPATH=findNim().splitFile.dir)
 
 # -------------- boot ---------------------------------------------------------
 
diff --git a/lib/pure/httpcore.nim b/lib/pure/httpcore.nim
index 98c03d177..219c22265 100644
--- a/lib/pure/httpcore.nim
+++ b/lib/pure/httpcore.nim
@@ -94,8 +94,8 @@ converter toString*(values: HttpHeaderValues): string =
   return seq[string](values)[0]
 
 proc `[]`*(headers: HttpHeaders, key: string, i: int): string =
-  ## Returns the ``i``th value associated with the given key. If there are
-  ## no values associated with the key or the ``i``th value doesn't exist,
+  ## Returns the ``i``'th value associated with the given key. If there are
+  ## no values associated with the key or the ``i``'th value doesn't exist,
   ## an exception is raised.
   return headers.table[key.toLower][i]
 
diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim
index 442fbab92..9b5d583d3 100644
--- a/tests/tuples/tuple_with_nil.nim
+++ b/tests/tuples/tuple_with_nil.nim
@@ -4,7 +4,7 @@ import parseutils
 import unicode
 import math
 import fenv
-import unsigned
+#import unsigned
 import pegs
 import streams
 
diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl
index aa3bce3c3..2c66ea493 100644
--- a/tools/niminst/buildsh.tmpl
+++ b/tools/niminst/buildsh.tmpl
@@ -1,5 +1,5 @@
 #? stdtmpl(subsChar='?') | standard
-#proc generateBuildShellScript(c: ConfigData): string = 
+#proc generateBuildShellScript(c: ConfigData): string =
 #  result = "#! /bin/sh\n# Generated from niminst\n" &
 #           "# Template is in tools/niminst/buildsh.tmpl\n" &
 #           "# To regenerate run ``niminst csource`` or ``koch csource``\n"
@@ -29,8 +29,8 @@ done
 
 CC="gcc"
 LINKER="gcc"
-COMP_FLAGS="?{c.ccompiler.flags}$extraBuildArgs"
-LINK_FLAGS="?{c.linker.flags}"
+COMP_FLAGS="${CPPFLAGS:-} ${CFLAGS:-} ?{c.ccompiler.flags}$extraBuildArgs"
+LINK_FLAGS="${LDFLAGS:-} ?{c.linker.flags}"
 PS4=""
 #  add(result, "# platform detection\n")
 ucpu=`uname -m`
@@ -51,8 +51,8 @@ ucpu=`echo $ucpu | tr "[:upper:]" "[:lower:]"`
 uos=`echo $uos | tr "[:upper:]" "[:lower:]"`
 
 case $uos in
-  *linux* ) 
-    myos="linux" 
+  *linux* )
+    myos="linux"
     LINK_FLAGS="$LINK_FLAGS -ldl -lm"
     ;;
   *dragonfly* )
@@ -66,14 +66,14 @@ case $uos in
     LINK_FLAGS="$LINK_FLAGS -lm"
     ;;
   *openbsd* )
-    myos="openbsd" 
+    myos="openbsd"
     LINK_FLAGS="$LINK_FLAGS -lm"
     ;;
   *netbsd* )
     myos="netbsd"
     LINK_FLAGS="$LINK_FLAGS -lm"
     ;;
-  *darwin* ) 
+  *darwin* )
     myos="macosx"
     CC="clang"
     LINKER="clang"
@@ -84,41 +84,41 @@ case $uos in
     ;;
   *aix* )
     myos="aix"
-    LINK_FLAGS="$LINK_FLAGS -ldl -lm"    
+    LINK_FLAGS="$LINK_FLAGS -ldl -lm"
     ;;
-  *solaris* | *sun* ) 
+  *solaris* | *sun* )
     myos="solaris"
     LINK_FLAGS="$LINK_FLAGS -ldl -lm -lsocket -lnsl"
     ;;
   *haiku* )
     myos="haiku"
     ;;
-  *) 
+  *)
     echo 2>&1 "Error: unknown operating system: $uos"
     exit 1
     ;;
 esac
 
 case $ucpu in
-  *i386* | *i486* | *i586* | *i686* | *bepc* | *i86pc* ) 
+  *i386* | *i486* | *i586* | *i686* | *bepc* | *i86pc* )
     mycpu="i386" ;;
-  *amd*64* | *x86-64* | *x86_64* ) 
+  *amd*64* | *x86-64* | *x86_64* )
     mycpu="amd64" ;;
-  *sparc*|*sun* ) 
+  *sparc*|*sun* )
     mycpu="sparc" ;;
-  *ppc64* ) 
+  *ppc64* )
     if [ "$myos" = "linux" ] ; then
       COMP_FLAGS="$COMP_FLAGS -m64"
       LINK_FLAGS="$LINK_FLAGS -m64"
     fi
     mycpu="powerpc64" ;;
-  *power*|*ppc* ) 
+  *power*|*ppc* )
     mycpu="powerpc" ;;
-  *mips* ) 
+  *mips* )
     mycpu="mips" ;;
   *arm*|*armv6l* )
     mycpu="arm" ;;
-  *) 
+  *)
     echo 2>&1 "Error: unknown processor: $ucpu"
     exit 1
     ;;
@@ -128,7 +128,7 @@ esac
 
 case $myos in
 #  for osA in 1..c.oses.len:
-?{c.oses[osA-1]}) 
+?{c.oses[osA-1]})
   case $mycpu in
 #    for cpuA in 1..c.cpus.len:
   ?{c.cpus[cpuA-1]})
@@ -149,7 +149,7 @@ case $myos in
   esac
   ;;
 #  end for
-*) 
+*)
   echo 2>&1 "Error: no C code generated for: [$myos: $mycpu]"
   exit 1
   ;;
diff --git a/tools/niminst/deinstall.tmpl b/tools/niminst/deinstall.tmpl
index 7349abcb4..bbc91d8f3 100644
--- a/tools/niminst/deinstall.tmpl
+++ b/tools/niminst/deinstall.tmpl
@@ -1,5 +1,5 @@
 #? stdtmpl(subsChar='?') | standard
-#proc generateDeinstallScript(c: ConfigData): string = 
+#proc generateDeinstallScript(c: ConfigData): string =
 #  result = "#! /bin/sh\n# Generated by niminst\n"
 #  var proj = c.name.toLower
 
@@ -12,7 +12,7 @@ if [ $# -eq 1 ] ; then
       echo "  /usr/bin"
       echo "  /usr/local/bin"
       echo "  /opt"
-      echo "  <some other dir> (treated like '/opt')"
+      echo "  <some other dir> (treated similar '/opt')"
       exit 1
       ;;
     "/usr/bin")
@@ -21,6 +21,7 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/lib/?proj
       docdir=/usr/share/?proj/doc
       datadir=/usr/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version/"
       ;;
     "/usr/local/bin")
       bindir=/usr/local/bin
@@ -28,6 +29,15 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/local/lib/?proj
       docdir=/usr/local/share/?proj/doc
       datadir=/usr/local/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version/"
+      ;;
+    "/opt")
+      bindir="/opt/?proj/bin"
+      configdir="/opt/?proj/config"
+      libdir="/opt/?proj/lib"
+      docdir="/opt/?proj/doc"
+      datadir="/opt/?proj/data"
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version/"
       ;;
     *)
       bindir="$1/?proj/bin"
@@ -35,6 +45,7 @@ if [ $# -eq 1 ] ; then
       libdir="$1/?proj/lib"
       docdir="$1/?proj/doc"
       datadir="$1/?proj/data"
+      nimbleDir="$1/?proj"
       ;;
   esac
   echo "removing files..."
@@ -43,7 +54,7 @@ if [ $# -eq 1 ] ; then
   #let f = ff.toUnix
   rm -f $bindir/?f.skipRoot
 #end for
-#for ff in items(c.cat[fcConfig]): 
+#for ff in items(c.cat[fcConfig]):
   #let f = ff.toUnix
   rm -f $configdir/?f.skipRoot
 #end for
@@ -51,6 +62,12 @@ if [ $# -eq 1 ] ; then
   rm -rf $datadir
   rm -rf $libdir
 
+  ## Nimble pkg stuff
+  #for f in items(c.cat[fcNimble]):
+    rm -f $nimbleDir/?f.toUnix
+  #end for
+  rm -f $nimbleDir/?{c.nimblePkgName}.nimble
+
   echo "deinstallation successful"
 else
   echo "?c.displayName deinstallation script"
@@ -59,6 +76,6 @@ else
   echo "  /usr/bin"
   echo "  /usr/local/bin"
   echo "  /opt"
-  echo "  <some other dir> (treated like '/opt')"
+  echo "  <some other dir> (treated similar '/opt')"
   exit 1
 fi
diff --git a/tools/niminst/install.tmpl b/tools/niminst/install.tmpl
index 14d88e07d..fa503fa36 100644
--- a/tools/niminst/install.tmpl
+++ b/tools/niminst/install.tmpl
@@ -1,5 +1,5 @@
 #? stdtmpl(subsChar = '?') | standard
-#proc generateInstallScript(c: ConfigData): string = 
+#proc generateInstallScript(c: ConfigData): string =
 #  result = "#! /bin/sh\n# Generated by niminst\n"
 #  var proj = c.name.toLower
 
@@ -8,7 +8,7 @@ set -e
 if [ $# -eq 1 ] ; then
 # if c.cat[fcUnixBin].len > 0:
   if test -f ?{c.cat[fcUnixBin][0].toUnix}
-  then 
+  then
     echo "?c.displayName build detected"
   else
     echo "Please build ?c.displayName before installing it"
@@ -23,7 +23,7 @@ if [ $# -eq 1 ] ; then
       echo "  /usr/bin"
       echo "  /usr/local/bin"
       echo "  /opt"
-      echo "  <some other dir> (treated like '/opt')"
+      echo "  <some other dir> (treated similar to '/opt')"
       echo "To deinstall, use the command:"
       echo "sh deinstall.sh DIR"
       exit 1
@@ -34,6 +34,7 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/lib/?proj
       docdir=/usr/share/?proj/doc
       datadir=/usr/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version/"
       ;;
     "/usr/local/bin")
       bindir=/usr/local/bin
@@ -41,6 +42,18 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/local/lib/?proj
       docdir=/usr/local/share/?proj/doc
       datadir=/usr/local/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
+      ;;
+    "/opt")
+      bindir="/opt/?proj/bin"
+      configdir="/opt/?proj/config"
+      libdir="/opt/?proj/lib"
+      docdir="/opt/?proj/doc"
+      datadir="/opt/?proj/data"
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
+      mkdir -p /opt/?proj
+      mkdir -p $bindir
+      mkdir -p $configdir
       ;;
     *)
       bindir="$1/?proj/bin"
@@ -48,25 +61,29 @@ if [ $# -eq 1 ] ; then
       libdir="$1/?proj/lib"
       docdir="$1/?proj/doc"
       datadir="$1/?proj/data"
-      
+      nimbleDir="$1/?proj"
       mkdir -p $1/?proj
       mkdir -p $bindir
       mkdir -p $configdir
       ;;
   esac
+
   mkdir -p $libdir
   mkdir -p $docdir
+  mkdir -p $nimbleDir/
   echo "copying files..."
 #var createdDirs = newStringTable()
-#for cat in fcConfig..fcLib:
+#for cat in {fcConfig..fcLib, fcNimble}:
 #  for f in items(c.cat[cat]):
 #    var mk = splitFile(f.skipRoot).dir
-#    if mk.len > 0:
+#    if cat != fcNimble:
 #      mk = unixDirVars[cat] & "/" & mk
-#      if not createdDirs.hasKey(mk):
-#        createdDirs[mk] = "true"
+#    else:
+#      mk = "$nimbleDir" / splitFile(f).dir
+#    end if
+#    if mk.len > 0 and not createdDirs.hasKey(mk):
+#      createdDirs[mk] = "true"
   mkdir -p ?{mk.toUnix}
-#      end if
 #    end if
 #  end for
 #end for
@@ -75,11 +92,11 @@ if [ $# -eq 1 ] ; then
   cp ?f.toUnix $bindir/?f.skipRoot.toUnix
   chmod 755 $bindir/?f.skipRoot.toUnix
 #end for
-#for f in items(c.cat[fcConfig]): 
+#for f in items(c.cat[fcConfig]):
   cp ?f.toUnix $configdir/?f.skipRoot.toUnix
   chmod 644 $configdir/?f.skipRoot.toUnix
 #end for
-#for f in items(c.cat[fcData]): 
+#for f in items(c.cat[fcData]):
   if [ -f ?f.toUnix ]; then
     cp ?f.toUnix $datadir/?f.skipRoot.toUnix
     chmod 644 $datadir/?f.skipRoot.toUnix
@@ -95,7 +112,13 @@ if [ $# -eq 1 ] ; then
   cp ?f.toUnix $libdir/?f.skipRoot.toUnix
   chmod 644 $libdir/?f.skipRoot.toUnix
 #end for
-  
+#for f in items(c.cat[fcNimble]):
+  cp ?f.toUnix $nimbleDir/?f.toUnix
+  chmod 644 $nimbleDir/?f.toUnix
+#end for
+cp ?{c.nimblePkgName}.nimble $nimbleDir/?{c.nimblePkgName}.nimble
+chmod 644 $nimbleDir/?{c.nimblePkgName}.nimble
+
   echo "installation successful"
 else
   echo "?c.displayName installation script"
@@ -104,7 +127,7 @@ else
   echo "  /usr/bin"
   echo "  /usr/local/bin"
   echo "  /opt"
-  echo "  <some other dir> (treated like '/opt')"
+  echo "  <some other dir> (treated similar to '/opt')"
   echo "To deinstall, use the command:"
   echo "sh deinstall.sh DIR"
   exit 1
diff --git a/tools/niminst/makefile.tmpl b/tools/niminst/makefile.tmpl
index 6615ddc02..5c95ccda9 100644
--- a/tools/niminst/makefile.tmpl
+++ b/tools/niminst/makefile.tmpl
@@ -1,13 +1,13 @@
 #? stdtmpl(subsChar='?') | standard
-#proc generateMakefile(c: ConfigData): string = 
+#proc generateMakefile(c: ConfigData): string =
 #  result = "# Generated from niminst\n" &
 #           "# Template is in tools/niminst/makefile.tmpl\n" &
 #           "# To regenerate run ``niminst csource`` or ``koch csource``\n"
 
 CC = gcc
 LINKER = gcc
-COMP_FLAGS = ?{c.ccompiler.flags}
-LINK_FLAGS = ?{c.linker.flags}
+COMP_FLAGS = $(CPPFLAGS) $(CFLAGS) ?{c.ccompiler.flags}
+LINK_FLAGS = $(LDFLAGS) ?{c.linker.flags}
 binDir = ?{firstBinPath(c).toUnix}
 
 koch := $(shell sh -c 'test -s ../koch.nim && echo "yes"')
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index d1216701f..991789a08 100644
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -48,7 +48,8 @@ type
     fcWindows,    # files only for Windows
     fcUnix,       # files only for Unix; must be after ``fcWindows``
     fcUnixBin,    # binaries for Unix
-    fcDocStart    # links to documentation for Windows installer
+    fcDocStart,   # links to documentation for Windows installer
+    fcNimble      # nimble package files to copy to /opt/nimble/pkgs/pkg-ver
 
   ConfigData = object of RootObj
     actions: set[Action]
@@ -65,6 +66,7 @@ type
     app: AppType
     nimArgs: string
     debOpts: TDebOptions
+    nimblePkgName: string
 
 const
   unixDirVars: array[fcConfig..fcLib, string] = [
@@ -214,8 +216,11 @@ proc addFiles(s: var seq[string], patterns: seq[string]) =
     else:
       var i = 0
       for f in walkFiles(p):
-        add(s, unixToNativePath(f))
-        inc(i)
+        if existsDir(f):
+          walkDirRecursively(s, f)
+        else:
+          add(s, unixToNativePath(f))
+          inc(i)
       if i == 0: echo("[Warning] No file found that matches: " & p)
 
 proc pathFlags(p: var CfgParser, k, v: string,
@@ -362,6 +367,14 @@ proc parseIniFile(c: var ConfigData) =
                 else: file.add(v[i])
               inc(i)
           else: quit(errorStr(p, "unknown variable: " & k.key))
+        of "nimble":
+          case normalize(k.key)
+          of "pkgname":
+            c.nimblePkgName = v
+          of "pkgfiles":
+            addFiles(c.cat[fcNimble], split(v, {';'}))
+          else:
+            quit(errorStr(p, "invalid key: " & k.key))
         else: quit(errorStr(p, "invalid section: " & section))
 
       of cfgOption: quit(errorStr(p, "syntax error"))
@@ -554,8 +567,13 @@ when haveZipLib:
           for k, f in walkDir("build" / dir):
             if k == pcFile: addFile(z, proj / dir / extractFilename(f), f)
 
-      for cat in items({fcConfig..fcOther, fcUnix}):
+      for cat in items({fcConfig..fcOther, fcUnix, fcNimble}):
         for f in items(c.cat[cat]): addFile(z, proj / f, f)
+
+      # Copy the .nimble file over
+      let nimbleFile = c.nimblePkgName & ".nimble"
+      processFile(z, proj / nimbleFile, nimbleFile)
+
       close(z)
     else:
       quit("Cannot open for writing: " & n)
@@ -587,9 +605,14 @@ proc xzDist(c: var ConfigData) =
       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 cat in items({fcConfig..fcOther, fcUnix, fcNimble}):
+    echo("Current category: ", cat)
     for f in items(c.cat[cat]): processFile(z, proj / f, f)
 
+  # Copy the .nimble file over
+  let nimbleFile = c.nimblePkgName & ".nimble"
+  processFile(z, proj / nimbleFile, nimbleFile)
+
   let oldDir = getCurrentDir()
   setCurrentDir(tmpDir)
   try:
diff --git a/web/download.rst b/web/download.rst
index cffad4ac9..774f4d017 100644
--- a/web/download.rst
+++ b/web/download.rst
@@ -12,10 +12,14 @@ and Clang on Mac.
 Binaries
 --------
 
-Unfortunately for now we only provide builds for Windows.
+Unfortunately, right now we only provide binaries for Windows. You can download
+an installer for both 32 bit and 64 bit versions of Windows below.
+
 * 32 bit: `nim-0.13.0_x32.exe <download/nim-0.13.0_x32.exe>`_
 * 64 bit: `nim-0.13.0_x64.exe <download/nim-0.13.0_x64.exe>`_
 
+These installers also include Aporia, Nimble and other useful Nim tools to get
+you started with Nim development!
 
 Installation based on generated C code
 --------------------------------------
@@ -24,33 +28,52 @@ This installation method is the preferred way for Linux, Mac OS X, and other Uni
 like systems. Binary packages may be provided later.
 
 
-Download this:
+Firstly, download this archive:
 
 * `nim-0.13.0.tar.xz (3.1MB) <download/nim-0.13.0.tar.xz>`_
 
-Extract the file and follow these instructions:
+Extract the archive. Then copy the extracted files into your chosen installation
+directory, ideally somewhere in your home directory.
+For example: ``~/programs/nim``.
+
+Now open a terminal and follow these instructions:
 
-* sh build.sh
+* ``cd`` into your installation directory, for example by executing
+``cd ~/programs/nim``.
+* run ``sh build.sh``.
 * Add ``$your_install_dir/bin`` to your PATH.
 
+After restarting your terminal, you should be able to run ``nim -v``
+which should show you the version of Nim you just installed.
+
 There are other ways to install Nim (like using the ``install.sh`` script),
 but these tend to cause more problems.
 
 
-Installation from github
-------------------------
+Bleeding edge installation from GitHub
+--------------------------------------
+
+`GitHub <http://github.com/nim-lang/nim>`_ is where Nim's development takes
+place. You may wish to grab the latest development version of Nim, because
+sometimes bug fixes and new features may not have made it to an official
+release yet. In those circumstances you are better off grabbing the
+current development branch.
+
+You will also need to do this if you would like to contribute to Nim.
+
+Before you download the code, open a new terminal and ``cd`` into the
+directory where you would like the download to take place.
 
-Use the following commands to build the compiler from source.
-Change the branch to suit your needs::
+The following commands can be used to download the current development branch
+and then to build it::
 
-  git clone -b master git://github.com/nim-lang/Nim.git
+  git clone git://github.com/nim-lang/Nim.git
   cd Nim
-  git clone -b master --depth 1 git://github.com/nim-lang/csources
+  git clone --depth 1 git://github.com/nim-lang/csources
   cd csources && sh build.sh
   cd ..
   bin/nim c koch
   ./koch boot -d:release
 
-The ``master`` branch always contains the latest stable version of the compiler.
-If you want bleeding edge then switch to the ``devel`` branch and follow
-the same instructions outlined above.
+You should then add the ``./bin`` (make sure to expand this into an
+absolute path) directory to your ``PATH``.