<commit_before>package ls

import "fmt"
import "io"
import "os"
import "path"
import "strings"
import "time"

import "../box"

var exeSuffixes = map[string]bool{}

const (
	O_STRIP_DIR = 1
	O_LONG      = 2
	O_INDICATOR = 4
	O_COLOR     = 8
	O_ALL       = 16
)

type fileInfoT struct {
	name string
	info os.FileInfo
}

const (
	ANSI_EXEC     = "\x1B[1;35m"
	ANSI_DIR      = "\x1B[1;32m"
	ANSI_NORM     = "\x1B[1;37m"
	ANSI_READONLY = "\x1B[1;33m"
	ANSI_END      = "\x1B[39m"
)

func (this fileInfoT) Name() string       { return this.name }
func (this fileInfoT) Size() int64        { return this.info.Size() }
func (this fileInfoT) Mode() os.FileMode  { return this.info.Mode() }
func (this fileInfoT) ModTime() time.Time { return this.info.ModTime() }
func (this fileInfoT) IsDir() bool        { return this.info.IsDir() }
func (this fileInfoT) Sys() interface{}   { return this.info.Sys() }

func newMyFileInfoT(name string, info os.FileInfo) *fileInfoT {
	this := new(fileInfoT)
	this.name = name
	this.info = info
	return this
}

func lsOneLong(status os.FileInfo, flag int, out io.Writer) {
	indicator := " "
	prefix := ""
	postfix := ""
	if status.IsDir() {
		io.WriteString(out, "d")
		indicator = "/"
		if (flag & O_COLOR) != 0 {
			prefix = ANSI_DIR
			postfix = ANSI_END
		}
	} else {
		io.WriteString(out, "-")
	}
	mode := status.Mode()
	perm := mode.Perm()
	name := status.Name()
	if (perm & 4) > 0 {
		io.WriteString(out, "r")
	} else {
		io.WriteString(out, "-")
	}
	if (perm & 2) > 0 {
		io.WriteString(out, "w")
	} else {
		if (flag & O_COLOR) != 0 {
			prefix = ANSI_READONLY
			postfix = ANSI_END
		}
		io.WriteString(out, "-")
	}
	if (perm & 1) > 0 {
		io.WriteString(out, "x")
	} else if exeSuffixes[strings.ToLower(path.Ext(name))] {
		io.WriteString(out, "x")
		indicator = "*"
		if (flag & O_COLOR) != 0 {
			prefix = ANSI_EXEC
			postfix = ANSI_END
		}
	} else {
		io.WriteString(out, "-")
	}
	if (flag & O_STRIP_DIR) > 0 {
		name = path.Base(name)
	}
	stamp := status.ModTime()
	fmt.Fprintf(out, " %8d %04d-%02d-%02d %02d:%02d %s%s%s",
		status.Size(),
		stamp.Year(),
		stamp.Month(),
		stamp.Day(),
		stamp.Hour(),
		stamp.Minute(),
		prefix,
		name,
		postfix)
	if (flag & O_INDICATOR) > 0 {
		io.WriteString(out, indicator)
	}
	io.WriteString(out, "\n")
}

func lsBox(nodes []os.FileInfo, flag int, out io.Writer) {
	nodes_ := make([]string, len(nodes))
	for key, val := range nodes {
		prefix := ""
		postfix := ""
		if val.IsDir() {
			if (flag & O_COLOR) != 0 {
				prefix = ANSI_DIR
				postfix = ANSI_END
			}
			if (flag & O_INDICATOR) != 0 {
				postfix += "/"
			}
		} else if (val.Mode().Perm() & 2) == 0 {
			if (flag & O_COLOR) != 0 {
				prefix = ANSI_READONLY
				postfix = ANSI_END
			}
		} else if exeSuffixes[strings.ToLower(path.Ext(val.Name()))] {
			if (flag & O_COLOR) != 0 {
				prefix = ANSI_EXEC
				postfix = ANSI_END
			}
			if (flag & O_INDICATOR) != 0 {
				postfix += "*"
			}
		}
		nodes_[key] = prefix + val.Name() + postfix
	}
	box.Print(nodes_, 80, out)
}

func lsLong(nodes []os.FileInfo, flag int, out io.Writer) {
	for _, finfo := range nodes {
		lsOneLong(finfo, flag, out)
	}
}

type fileInfoCollection struct {
	nodes []os.FileInfo
}

func (this *fileInfoCollection) Len() int {
	return len(this.nodes)
}
func (this *fileInfoCollection) Less(i, j int) bool {
	return this.nodes[i].Name() < this.nodes[j].Name()
}
func (this *fileInfoCollection) Swap(i, j int) {
	tmp := this.nodes[i]
	this.nodes[i] = this.nodes[j]
	this.nodes[j] = tmp
}

func lsFolder(folder string, flag int, out io.Writer) error {
	fd, err := os.Open(folder)
	if err != nil {
		return err
	}
	defer fd.Close()
	var nodesArray fileInfoCollection
	nodesArray.nodes, err = fd.Readdir(-1)
	if err != nil {
		return err
	}
	if (flag & O_ALL) == 0 {
		tmp := make([]os.FileInfo, 0)
		for _, f := range nodesArray.nodes {
			if !strings.HasPrefix(f.Name(), ".") {
				tmp = append(tmp, f)
			}
		}
		nodesArray.nodes = tmp
	}
	if (flag & O_LONG) > 0 {
		lsLong(nodesArray.nodes, O_STRIP_DIR|flag, out)
	} else {
		lsBox(nodesArray.nodes, O_STRIP_DIR|flag, out)
	}
	return nil
}

func lsCore(paths []string, flag int, out io.Writer) error {
	if len(paths) <= 0 {
		return lsFolder(".", flag, out)
	}
	dirs := make([]string, 0)
	printCount := 0
	files := make([]os.FileInfo, 0)
	for _, name := range paths {
		status, err := os.Stat(name)<commit_msg>ls - 大文字・小文字を区別しないソートになっていた<commit_after>package ls

import "fmt"
import "io"
import "os"
import "path"
import "sort"
import "strings"
import "time"

import "../box"

var exeSuffixes = map[string]bool{}

const (
	O_STRIP_DIR = 1
	O_LONG      = 2
	O_INDICATOR = 4
	O_COLOR     = 8
	O_ALL       = 16
)

type fileInfoT struct {
	name string
	info os.FileInfo
}

const (
	ANSI_EXEC     = "\x1B[1;35m"
	ANSI_DIR      = "\x1B[1;32m"
	ANSI_NORM     = "\x1B[1;37m"
	ANSI_READONLY = "\x1B[1;33m"
	ANSI_END      = "\x1B[39m"
)

func (this fileInfoT) Name() string       { return this.name }
func (this fileInfoT) Size() int64        { return this.info.Size() }
func (this fileInfoT) Mode() os.FileMode  { return this.info.Mode() }
func (this fileInfoT) ModTime() time.Time { return this.info.ModTime() }
func (this fileInfoT) IsDir() bool        { return this.info.IsDir() }
func (this fileInfoT) Sys() interface{}   { return this.info.Sys() }

func newMyFileInfoT(name string, info os.FileInfo) *fileInfoT {
	this := new(fileInfoT)
	this.name = name
	this.info = info
	return this
}

func lsOneLong(status os.FileInfo, flag int, out io.Writer) {
	indicator := " "
	prefix := ""
	postfix := ""
	if status.IsDir() {
		io.WriteString(out, "d")
		indicator = "/"
		if (flag & O_COLOR) != 0 {
			prefix = ANSI_DIR
			postfix = ANSI_END
		}
	} else {
		io.WriteString(out, "-")
	}
	mode := status.Mode()
	perm := mode.Perm()
	name := status.Name()
	if (perm & 4) > 0 {
		io.WriteString(out, "r")
	} else {
		io.WriteString(out, "-")
	}
	if (perm & 2) > 0 {
		io.WriteString(out, "w")
	} else {
		if (flag & O_COLOR) != 0 {
			prefix = ANSI_READONLY
			postfix = ANSI_END
		}
		io.WriteString(out, "-")
	}
	if (perm & 1) > 0 {
		io.WriteString(out, "x")
	} else if exeSuffixes[strings.ToLower(path.Ext(name))] {
		io.WriteString(out, "x")
		indicator = "*"
		if (flag & O_COLOR) != 0 {
			prefix = ANSI_EXEC
			postfix = ANSI_END
		}
	} else {
		io.WriteString(out, "-")
	}
	if (flag & O_STRIP_DIR) > 0 {
		name = path.Base(name)
	}
	stamp := status.ModTime()
	fmt.Fprintf(out, " %8d %04d-%02d-%02d %02d:%02d %s%s%s",
		status.Size(),
		stamp.Year(),
		stamp.Month(),
		stamp.Day(),
		stamp.Hour(),
		stamp.Minute(),
		prefix,
		name,
		postfix)
	if (flag & O_INDICATOR) > 0 {
		io.WriteString(out, indicator)
	}
	io.WriteString(out, "\n")
}

func lsBox(nodes []os.FileInfo, flag int, out io.Writer) {
	nodes_ := make([]string, len(nodes))
	for key, val := range nodes {
		prefix := ""
		postfix := ""
		if val.IsDir() {
			if (flag & O_COLOR) != 0 {
				prefix = ANSI_DIR
				postfix = ANSI_END
			}
			if (flag & O_INDICATOR) != 0 {
				postfix += "/"
			}
		} else if (val.Mode().Perm() & 2) == 0 {
			if (flag & O_COLOR) != 0 {
				prefix = ANSI_READONLY
				postfix = ANSI_END
			}
		} else if exeSuffixes[strings.ToLower(path.Ext(val.Name()))] {
			if (flag & O_COLOR) != 0 {
				prefix = ANSI_EXEC
				postfix = ANSI_END
			}
			if (flag & O_INDICATOR) != 0 {
				postfix += "*"
			}
		}
		nodes_[key] = prefix + val.Name() + postfix
	}
	box.Print(nodes_, 80, out)
}

func lsLong(nodes []os.FileInfo, flag int, out io.Writer) {
	for _, finfo := range nodes {
		lsOneLong(finfo, flag, out)
	}
}

type fileInfoCollection struct {
	nodes []os.FileInfo
}

func (this fileInfoCollection) Len() int {
	return len(this.nodes)
}
func (this fileInfoCollection) Less(i, j int) bool {
	return this.nodes[i].Name() < this.nodes[j].Name()
}
func (this fileInfoCollection) Swap(i, j int) {
	tmp := this.nodes[i]
	this.nodes[i] = this.nodes[j]
	this.nodes[j] = tmp
}

func lsFolder(folder string, flag int, out io.Writer) error {
	fd, err := os.Open(folder)
	if err != nil {
		return err
	}
	defer fd.Close()
	var nodesArray fileInfoCollection
	nodesArray.nodes, err = fd.Readdir(-1)
	if err != nil {
		return err
	}
	if (flag & O_ALL) == 0 {
		tmp := make([]os.FileInfo, 0)
		for _, f := range nodesArray.nodes {
			if !strings.HasPrefix(f.Name(), ".") {
				tmp = append(tmp, f)
			}
		}
		nodesArray.nodes = tmp
		sort.Sort(nodesArray)
	}
	if (flag & O_LONG) > 0 {
		lsLong(nodesArray.nodes, O_STRIP_DIR|flag, out)
	} else {
		lsBox(nodesArray.nodes, O_STRIP_DIR|flag, out)
	}
	return nil
}

func lsCore(paths []string, flag int, out io.Writer) error {
	if len(paths) <= 0 {
		return lsFolder(".", flag, out)
	}
	dirs := make([]string, 0)
	printCount := 0
	files := make([]os.FileInfo, 0)
	for _, name := range paths {
		status, err := os.Stat(name)
{'fraction_non_alphanumeric': 0.1669126830929942, 'fraction_numerical': 0.014988077665493357, 'mean_word_length': 3.127460168697282, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1473603', 'n_tokens_mistral': 3931, 'n_tokens_neox': 3600, 'n_words': 837}