mirror of
https://github.com/mjl-/mox.git
synced 2025-07-12 19:04:35 +03:00
mox!
This commit is contained in:
1
vendor/github.com/mjl-/xfmt/.gitignore
generated
vendored
Normal file
1
vendor/github.com/mjl-/xfmt/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
/xfmt
|
7
vendor/github.com/mjl-/xfmt/LICENSE
generated
vendored
Normal file
7
vendor/github.com/mjl-/xfmt/LICENSE
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright (c) 2019 Mechiel Lukkien
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
vendor/github.com/mjl-/xfmt/README.txt
generated
vendored
Normal file
26
vendor/github.com/mjl-/xfmt/README.txt
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
xfmt formats long lines, playing nice with text in code.
|
||||
|
||||
To install:
|
||||
|
||||
go get github.com/mjl-/xfmt/cmd/xfmt
|
||||
|
||||
Xfmt reads from stdin, writes formatted output to stdout.
|
||||
|
||||
Xfmt wraps long lines at 80 characters, configurable through -width. But it
|
||||
counts text width excluding indenting and markup. Fmt formats to a max line
|
||||
length that includes indenting. We don't care about total max line length
|
||||
nowadays, we care about a human readable paragraph, which has a certain text
|
||||
width regardless of indent.
|
||||
|
||||
Xfmt recognizes lines with first non-whitespace of "//" and "#" as line
|
||||
comments, and repeats that prefix on later lines.
|
||||
|
||||
Xfmt keep does not merge lines if the first non-prefix text starts with
|
||||
interpunction or numbers. E.g. "- item1" or "1. point 1".
|
||||
|
||||
Xfmt does not merge multiple spaces, it assumes you intended what you typed.
|
||||
|
||||
# todo
|
||||
|
||||
- possibly recognize itemized lists in comments and indent the later lines with whitespace
|
||||
- something else
|
207
vendor/github.com/mjl-/xfmt/xfmt.go
generated
vendored
Normal file
207
vendor/github.com/mjl-/xfmt/xfmt.go
generated
vendored
Normal file
@ -0,0 +1,207 @@
|
||||
// Package xfmt reformats text, wrapping it while recognizing comments.
|
||||
package xfmt
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Config tells format how to reformat text.
|
||||
type Config struct {
|
||||
MaxWidth int // Max width of content (excluding indenting), after which lines are wrapped.
|
||||
BreakPrefixes []string // String prefixes that cause a line to break, instead of being merged into the previous line.
|
||||
}
|
||||
|
||||
// Format reads text from r and writes reformatted text to w, according to
|
||||
// instructions in config. Lines ending with \r\n are formatted with \r\n as well.
|
||||
func Format(w io.Writer, r io.Reader, config Config) error {
|
||||
f := &formatter{
|
||||
in: bufio.NewReader(r),
|
||||
out: bufio.NewWriter(w),
|
||||
config: config,
|
||||
}
|
||||
return f.format()
|
||||
}
|
||||
|
||||
type formatter struct {
|
||||
in *bufio.Reader
|
||||
out *bufio.Writer
|
||||
config Config
|
||||
curLine string
|
||||
curLineend string
|
||||
}
|
||||
|
||||
type parseError error
|
||||
|
||||
func (f *formatter) format() (rerr error) {
|
||||
defer func() {
|
||||
e := recover()
|
||||
if e != nil {
|
||||
if pe, ok := e.(parseError); ok {
|
||||
rerr = pe
|
||||
} else {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
line, end := f.gatherLine()
|
||||
if line == "" && end == "" {
|
||||
break
|
||||
}
|
||||
prefix, rem := parseLine(line)
|
||||
for _, s := range f.splitLine(rem) {
|
||||
f.write(prefix)
|
||||
f.write(s)
|
||||
f.write(end)
|
||||
}
|
||||
}
|
||||
return f.out.Flush()
|
||||
|
||||
}
|
||||
|
||||
func (f *formatter) check(err error, action string) {
|
||||
if err != nil {
|
||||
panic(parseError(fmt.Errorf("%s: %s", action, err)))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *formatter) write(s string) {
|
||||
_, err := f.out.Write([]byte(s))
|
||||
f.check(err, "write")
|
||||
}
|
||||
|
||||
func (f *formatter) peekLine() (string, string) {
|
||||
if f.curLine != "" || f.curLineend != "" {
|
||||
return f.curLine, f.curLineend
|
||||
}
|
||||
|
||||
line, err := f.in.ReadString('\n')
|
||||
if err != io.EOF {
|
||||
f.check(err, "read")
|
||||
}
|
||||
if line == "" {
|
||||
return "", ""
|
||||
}
|
||||
if strings.HasSuffix(line, "\r\n") {
|
||||
f.curLine, f.curLineend = line[:len(line)-2], "\r\n"
|
||||
} else if strings.HasSuffix(line, "\n") {
|
||||
f.curLine, f.curLineend = line[:len(line)-1], "\n"
|
||||
} else {
|
||||
f.curLine, f.curLineend = line, ""
|
||||
}
|
||||
return f.curLine, f.curLineend
|
||||
}
|
||||
|
||||
func (f *formatter) consumeLine() {
|
||||
if f.curLine == "" && f.curLineend == "" {
|
||||
panic("bad")
|
||||
}
|
||||
f.curLine = ""
|
||||
f.curLineend = ""
|
||||
}
|
||||
|
||||
func (f *formatter) gatherLine() (string, string) {
|
||||
var curLine, curLineend string
|
||||
var curPrefix string
|
||||
|
||||
for {
|
||||
line, end := f.peekLine()
|
||||
if line == "" && end == "" {
|
||||
break
|
||||
}
|
||||
if curLine == "" {
|
||||
curLineend = end
|
||||
}
|
||||
prefix, rem := parseLine(line)
|
||||
if prefix == "" && rem == "" {
|
||||
if curLine == "" {
|
||||
f.consumeLine()
|
||||
}
|
||||
break
|
||||
}
|
||||
if curLine != "" && (curPrefix != prefix || rem == "" || f.causeBreak(rem)) {
|
||||
break
|
||||
}
|
||||
curPrefix = prefix
|
||||
if curLine != "" {
|
||||
curLine += " "
|
||||
}
|
||||
curLine += rem
|
||||
f.consumeLine()
|
||||
// Control at begin or end of line are not merged.
|
||||
if curLine != "" && curLine[len(curLine)-1] < 0x20 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return curPrefix + curLine, curLineend
|
||||
}
|
||||
|
||||
func (f *formatter) causeBreak(s string) bool {
|
||||
c := s[0]
|
||||
if c < 0x20 {
|
||||
return true
|
||||
}
|
||||
for _, ss := range f.config.BreakPrefixes {
|
||||
if strings.HasPrefix(s, ss) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Don't merge lines starting with eg "1. ".
|
||||
for i, c := range s {
|
||||
if c >= '0' && c <= '9' {
|
||||
continue
|
||||
}
|
||||
if i > 0 && c == '.' && strings.HasPrefix(s[i:], ". ") {
|
||||
return true
|
||||
}
|
||||
break
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func parseLine(s string) (string, string) {
|
||||
orig := s
|
||||
s = strings.TrimLeft(orig, " \t")
|
||||
prefix := orig[:len(orig)-len(s)]
|
||||
if strings.HasPrefix(s, "//") {
|
||||
prefix += "//"
|
||||
s = s[2:]
|
||||
} else if strings.HasPrefix(s, "#") {
|
||||
prefix += "#"
|
||||
s = s[1:]
|
||||
}
|
||||
ns := strings.TrimLeft(s, " \t")
|
||||
prefix += s[:len(s)-len(ns)]
|
||||
s = ns
|
||||
return prefix, s
|
||||
}
|
||||
|
||||
func (f *formatter) splitLine(s string) []string {
|
||||
if len(s) <= f.config.MaxWidth {
|
||||
return []string{s}
|
||||
}
|
||||
|
||||
line := ""
|
||||
r := []string{}
|
||||
for _, w := range strings.Split(s, " ") {
|
||||
if line != "" && len(line)+1+len(w) > f.config.MaxWidth {
|
||||
r = append(r, line)
|
||||
line = w
|
||||
continue
|
||||
}
|
||||
if line != "" {
|
||||
line += " "
|
||||
}
|
||||
line += w
|
||||
}
|
||||
if line != "" {
|
||||
r = append(r, line)
|
||||
}
|
||||
return r
|
||||
}
|
Reference in New Issue
Block a user