summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorClyybber <darkmine956@gmail.com>2020-09-22 10:43:12 +0200
committerGitHub <noreply@github.com>2020-09-22 10:43:12 +0200
commitd67c5cb75171fcbf1ca9078452e8fcbe36fc79bc (patch)
tree461841c502d8921b1b4b42c46f66930ad17f6f79 /lib
parentaca9c5fb30fe2de12671e9103e93b81201bb8e71 (diff)
downloadNim-d67c5cb75171fcbf1ca9078452e8fcbe36fc79bc.tar.gz
Add strutils.indentation and make unindent use it (#15264)
* Add strutils.indentation and make unindent use it

* Code style

* Fix bootstrapping

* Improve wording

* Fix test

* Introduce without breaking change

* Fix

* Reduce diff

* Fix docs link

* Add since annotation

* Update changelog
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/strutils.nim47
1 files changed, 36 insertions, 11 deletions
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 156929dee..d97ed9a07 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -82,6 +82,7 @@ when defined(nimVmExportFixed):
   export toLower, toUpper
 
 include "system/inclrtl"
+import std/private/since
 
 const
   Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'}
@@ -1511,6 +1512,7 @@ proc indent*(s: string, count: Natural, padding: string = " "): string
   ## * `alignLeft proc<#alignLeft,string,Natural,char>`_
   ## * `spaces proc<#spaces,Natural>`_
   ## * `unindent proc<#unindent,string,Natural,string>`_
+  ## * `dedent proc<#dedent,string,Natural,string>`_
   runnableExamples:
     doAssert indent("First line\c\l and second line.", 2) ==
              "  First line\l   and second line."
@@ -1524,21 +1526,25 @@ proc indent*(s: string, count: Natural, padding: string = " "): string
     result.add(line)
     i.inc
 
-proc unindent*(s: string, count: Natural, padding: string = " "): string
+proc unindent*(s: string, count: Natural = int.high, padding: string = " "): string
     {.noSideEffect, rtl, extern: "nsuUnindent".} =
   ## Unindents each line in ``s`` by ``count`` amount of ``padding``.
-  ## Sometimes called `dedent`:idx:
   ##
   ## **Note:** This does not preserve the new line characters used in ``s``.
   ##
   ## See also:
+  ## * `dedent proc<#dedent,string,Natural,string>`
   ## * `align proc<#align,string,Natural,char>`_
   ## * `alignLeft proc<#alignLeft,string,Natural,char>`_
   ## * `spaces proc<#spaces,Natural>`_
   ## * `indent proc<#indent,string,Natural,string>`_
   runnableExamples:
-    doAssert unindent("  First line\l   and second line", 3) ==
-             "First line\land second line"
+    let x = """
+      Hello
+        There
+    """.unindent()
+
+    doAssert x == "Hello\nThere\n"
   result = ""
   var i = 0
   for line in s.splitLines():
@@ -1553,11 +1559,30 @@ proc unindent*(s: string, count: Natural, padding: string = " "): string
     result.add(line[indentCount*padding.len .. ^1])
     i.inc
 
-proc unindent*(s: string): string
-    {.noSideEffect, rtl, extern: "nsuUnindentAll".} =
-  ## Removes all indentation composed of whitespace from each line in ``s``.
+proc indentation*(s: string): Natural {.since: (1, 3).} =
+  ## Returns the amount of indentation all lines of ``s`` have in common,
+  ## ignoring lines that consist only of whitespace.
+  result = int.high
+  for line in s.splitLines:
+    for i, c in line:
+      if i >= result: break
+      elif c != ' ':
+        result = i
+        break
+  if result == int.high:
+    result = 0
+
+proc dedent*(s: string, count: Natural = indentation(s)): string
+    {.noSideEffect, rtl, extern: "nsuDedent", since: (1, 3).} =
+  ## Unindents each line in ``s`` by ``count`` amount of ``padding``.
+  ## The only difference between this and `unindent proc<#unindent,string,Natural,string>`
+  ## is that this by default only cuts off the amount of indentation that all
+  ## lines of ``s`` share as opposed to all indentation. It only supports spcaes as padding.
+  ##
+  ## **Note:** This does not preserve the new line characters used in ``s``.
   ##
   ## See also:
+  ## * `unindent proc<#unindent,string,Natural,string>`
   ## * `align proc<#align,string,Natural,char>`_
   ## * `alignLeft proc<#alignLeft,string,Natural,char>`_
   ## * `spaces proc<#spaces,Natural>`_
@@ -1565,11 +1590,11 @@ proc unindent*(s: string): string
   runnableExamples:
     let x = """
       Hello
-      There
-    """.unindent()
+        There
+    """.dedent()
 
-    doAssert x == "Hello\nThere\n"
-  unindent(s, 1000) # TODO: Passing a 1000 is a bit hackish.
+    doAssert x == "Hello\n  There\n"
+  unindent(s, count, " ")
 
 proc delete*(s: var string, first, last: int) {.noSideEffect,
   rtl, extern: "nsuDelete".} =