mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
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
This commit is contained in:
@@ -187,6 +187,15 @@
|
|||||||
|
|
||||||
- Add missing attributes and methods to `dom.Navigator` like `deviceMemory`, `onLine`, `vibrate()`, etc.
|
- Add missing attributes and methods to `dom.Navigator` like `deviceMemory`, `onLine`, `vibrate()`, etc.
|
||||||
|
|
||||||
|
- Added `strutils.indentation` and `strutils.dedent` which enable indented string literals:
|
||||||
|
```nim
|
||||||
|
import strutils
|
||||||
|
echo dedent """
|
||||||
|
This
|
||||||
|
is
|
||||||
|
cool!
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
## Language changes
|
## Language changes
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ when defined(nimVmExportFixed):
|
|||||||
export toLower, toUpper
|
export toLower, toUpper
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
|
import std/private/since
|
||||||
|
|
||||||
const
|
const
|
||||||
Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'}
|
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>`_
|
## * `alignLeft proc<#alignLeft,string,Natural,char>`_
|
||||||
## * `spaces proc<#spaces,Natural>`_
|
## * `spaces proc<#spaces,Natural>`_
|
||||||
## * `unindent proc<#unindent,string,Natural,string>`_
|
## * `unindent proc<#unindent,string,Natural,string>`_
|
||||||
|
## * `dedent proc<#dedent,string,Natural,string>`_
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
doAssert indent("First line\c\l and second line.", 2) ==
|
doAssert indent("First line\c\l and second line.", 2) ==
|
||||||
" First line\l and second line."
|
" First line\l and second line."
|
||||||
@@ -1524,21 +1526,25 @@ proc indent*(s: string, count: Natural, padding: string = " "): string
|
|||||||
result.add(line)
|
result.add(line)
|
||||||
i.inc
|
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".} =
|
{.noSideEffect, rtl, extern: "nsuUnindent".} =
|
||||||
## Unindents each line in ``s`` by ``count`` amount of ``padding``.
|
## 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``.
|
## **Note:** This does not preserve the new line characters used in ``s``.
|
||||||
##
|
##
|
||||||
## See also:
|
## See also:
|
||||||
|
## * `dedent proc<#dedent,string,Natural,string>`
|
||||||
## * `align proc<#align,string,Natural,char>`_
|
## * `align proc<#align,string,Natural,char>`_
|
||||||
## * `alignLeft proc<#alignLeft,string,Natural,char>`_
|
## * `alignLeft proc<#alignLeft,string,Natural,char>`_
|
||||||
## * `spaces proc<#spaces,Natural>`_
|
## * `spaces proc<#spaces,Natural>`_
|
||||||
## * `indent proc<#indent,string,Natural,string>`_
|
## * `indent proc<#indent,string,Natural,string>`_
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
doAssert unindent(" First line\l and second line", 3) ==
|
let x = """
|
||||||
"First line\land second line"
|
Hello
|
||||||
|
There
|
||||||
|
""".unindent()
|
||||||
|
|
||||||
|
doAssert x == "Hello\nThere\n"
|
||||||
result = ""
|
result = ""
|
||||||
var i = 0
|
var i = 0
|
||||||
for line in s.splitLines():
|
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])
|
result.add(line[indentCount*padding.len .. ^1])
|
||||||
i.inc
|
i.inc
|
||||||
|
|
||||||
proc unindent*(s: string): string
|
proc indentation*(s: string): Natural {.since: (1, 3).} =
|
||||||
{.noSideEffect, rtl, extern: "nsuUnindentAll".} =
|
## Returns the amount of indentation all lines of ``s`` have in common,
|
||||||
## Removes all indentation composed of whitespace from each line in ``s``.
|
## 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:
|
## See also:
|
||||||
|
## * `unindent proc<#unindent,string,Natural,string>`
|
||||||
## * `align proc<#align,string,Natural,char>`_
|
## * `align proc<#align,string,Natural,char>`_
|
||||||
## * `alignLeft proc<#alignLeft,string,Natural,char>`_
|
## * `alignLeft proc<#alignLeft,string,Natural,char>`_
|
||||||
## * `spaces proc<#spaces,Natural>`_
|
## * `spaces proc<#spaces,Natural>`_
|
||||||
@@ -1565,11 +1590,11 @@ proc unindent*(s: string): string
|
|||||||
runnableExamples:
|
runnableExamples:
|
||||||
let x = """
|
let x = """
|
||||||
Hello
|
Hello
|
||||||
There
|
There
|
||||||
""".unindent()
|
""".dedent()
|
||||||
|
|
||||||
doAssert x == "Hello\nThere\n"
|
doAssert x == "Hello\n There\n"
|
||||||
unindent(s, 1000) # TODO: Passing a 1000 is a bit hackish.
|
unindent(s, count, " ")
|
||||||
|
|
||||||
proc delete*(s: var string, first, last: int) {.noSideEffect,
|
proc delete*(s: var string, first, last: int) {.noSideEffect,
|
||||||
rtl, extern: "nsuDelete".} =
|
rtl, extern: "nsuDelete".} =
|
||||||
|
|||||||
@@ -435,3 +435,25 @@ block:
|
|||||||
doAssert a == f1
|
doAssert a == f1
|
||||||
doAssert b == f2
|
doAssert b == f2
|
||||||
doAssert c == f3
|
doAssert c == f3
|
||||||
|
|
||||||
|
block:
|
||||||
|
assert 0 == indentation """
|
||||||
|
hey
|
||||||
|
low
|
||||||
|
there
|
||||||
|
"""
|
||||||
|
assert 2 == indentation """
|
||||||
|
hey
|
||||||
|
low
|
||||||
|
there
|
||||||
|
"""
|
||||||
|
assert 2 == indentation """ hey
|
||||||
|
low
|
||||||
|
there
|
||||||
|
"""
|
||||||
|
assert 2 == indentation """ hey
|
||||||
|
low
|
||||||
|
there"""
|
||||||
|
assert 0 == indentation ""
|
||||||
|
assert 0 == indentation " \n \n"
|
||||||
|
assert 0 == indentation " "
|
||||||
|
|||||||
Reference in New Issue
Block a user