This repository has been archived by the owner on Jul 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
indent.scm
executable file
·139 lines (127 loc) · 3.35 KB
/
indent.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/local/bin/gosh
(use gauche.parseopt) ; command-line
(use file.filter) ; file-filter-fold
(use srfi-13) ; string trim and pad
(include "lib/dir.scm")
(define (main args)
(let-args (cdr args)
((h "h|help" => (cut help (car args)))
(d "d|dot-files")
(f "f|file=s")
(t "t|type=s" "scm")
(v "v|verbose")
. restargs)
(if (not h)
(if f
(indent-file f)
(let ((files (indent-dir (current-directory)
:type t :dot-files d :verbose v)))
(print #"Indented ~files files"))))))
(define (help file)
(print "Indent lines in file or current directory (and below).")
(dir-help))
(define (indent-dir path :rest args)
(apply dir-info path args)
(directory-fold path
(lambda (file result)
; this should be a macro, for use with every file filter
(let ((perm (slot-ref (sys-stat file) 'perm)))
(if (indent-file file)
(begin
(sys-chmod file perm)
(+ 1 result))
result)))
0
:lister
(lambda (dir seed)
(values (apply filter-dir dir args)
seed))))
(define (indent-file file)
(guard (e (else
(print #"Error processing ~file")
(print (condition-message e))
#f))
(file-filter-fold indent-fold '()
:input file
:output file
:temporary-file #t
:leave-unchanged #t)))
(define (indent-fold line columns out)
(let ((new (string-trim-both line)))
(if (> (string-length new) 0)
(let ((column (if (null? columns)
0
(car columns))))
(write-string
(string-pad new (+ column
(string-length new)))
out)))
(newline out)
(if (or
(zero? (string-length new))
(eq? (string-ref new 0) #\;))
columns
(new-columns new columns))))
(define (new-columns s columns)
(let f ((chars (string->list s))
(col (if (null? columns)
0
(car columns)))
(cols columns))
(if (null? chars)
cols
(case (car chars)
;todo - handle brackets
((#\()
(f (cdr chars) (+ 1 col) (cons (+ 1 col) cols)))
((#\))
(f (cdr chars) (+ 1 col) (if (null? cols)
cols
(cdr cols))))
((#\#)
(let-values (((chars col) (hash (cdr chars) (+ 1 col))))
(f chars col cols)))
((#\")
(let-values (((chars col) (quotation (cdr chars) (+ 1 col))))
(f chars col cols)))
((#\;)
cols)
(else
(f (cdr chars) (+ 1 col) cols))))))
(define (hash chars col)
(if (null? chars)
(values chars col)
(case (car chars)
((#\\) ; char
(escape (cdr chars) (+ 1 col)))
((#\/) ; regexp
(regexp (cdr chars) (+ 1 col)))
(else
(values chars col)))))
; skip to end of escape
; todo - character names
(define (escape chars col)
(if (null? chars)
(values chars col)
(values (cdr chars) (+ 1 col))))
; skip to end of quote
(define (quotation chars col)
(if (null? chars)
(values chars col)
(case (car chars)
((#\\) ; char
(let-values (((chars col)
(escape (cdr chars) (+ 1 col))))
(quotation chars col)))
((#\")
(values (cdr chars) (+ 1 col)))
(else
(quotation (cdr chars) (+ 1 col))))))
; skip to end of regexp
(define (regexp chars col)
(if (null? chars)
(values chars col)
; todo - check for escaped slash
(if (eqv? #\/ (car chars))
(values (cdr chars) (+ 1 col))
(quotation (cdr chars) (+ 1 col)))))