11 #| String helper functions |#
12 (define (split-prefix str)
13 (define components (string-split str))
14 (define head (car components))
15 (define tail (string-join (rest components)))
18 (define (file-string file) (format "\"~a\"" file))
19 (define non-blank-string? (compose1 non-empty-string? string-trim))
22 (define (git . args) (string-split (with-output-to-string (λ () (system (string-join (cons "git" args))))) "\n"))
23 (define (ls-files . args) (map split-prefix (git "ls-files" "-v" (string-join args))))
24 (define (update-index . args) (git "update-index" (string-join args)))
26 (define (modified-files) (map cdr (ls-files "-m")))
27 (define (skipped-files) (map cdr (ls-files "|" "findstr" "\"^S\"")))
29 (define (skip-file file) (update-index "--skip-worktree" (file-string file)))
30 (define (no-skip-file file) (update-index "--no-skip-worktree" (file-string file)))
31 (define (skip-modified) (for-each skip-file (modified-files)))
32 (define (no-skip-all) (for-each no-skip-file (skipped-files)))
34 #| Interactive mode helper methods |#
35 (define (find-numbered-list number items) (map cdr (filter (compose1 (curry equal? number) number->string car) items)))
36 (define (numbered-list items) (map cons (inclusive-range 1 (length items)) items))
37 (define (format-pair pair) (format "~a - ~a" (car pair) (cdr pair)))
38 (define (format-numbered-list items) (map format-pair (numbered-list items)))
40 (define (parse-input input) (regexp-match* #px"([sn])(\\d+)" input #:match-select rest))
42 (define (interpret-input skipped-file-list modified-file-list pair)
44 ("s" (for-each skip-file (find-numbered-list (cadr pair) (numbered-list modified-file-list))))
45 ("n" (for-each no-skip-file (find-numbered-list (cadr pair) (numbered-list skipped-file-list))))))
47 (define (handle-input input skipped-file-list modified-file-list)
48 (if (non-blank-string? input)
49 (for-each (curry interpret-input skipped-file-list modified-file-list) (parse-input input))
52 (define (display-files skipped-file-list modified-file-list)
53 (displayln "Skipped Files:")
54 (for-each displayln (format-numbered-list skipped-file-list))
55 (displayln "Modified Files:")
56 (for-each displayln (format-numbered-list modified-file-list)))
58 (define (interactive-prompt skipped-file-list modified-file-list)
59 (display-files skipped-file-list modified-file-list)
60 (displayln "Enter 's' or 'n' followed by a file number to skip or unskip a file respectively.")
61 (displayln "e.g. 's3 n12' skips the third file under Modified Files then unskips the twelfth file under Skipped Files.")
62 (displayln "Enter a blank line to quit.")
66 (define (interactive-loop)
67 (define skipped-file-list (skipped-files))
68 (define modified-file-list (modified-files))
69 (if (handle-input (interactive-prompt skipped-file-list modified-file-list) skipped-file-list modified-file-list)
74 (define (program-display-file-status) (display-files (skipped-files) (modified-files)))
76 (define (program-skip-file file)
77 (displayln (format "Skipping file: '~a'" file))
80 (define (program-no-skip-file file)
81 (displayln (format "Unskipping file: '~a'" file))
84 (define (program-no-skip-all)
85 (displayln "Unskipping every file")
88 (define (program-skip-modified)
89 (displayln "Skipping every modified file")
92 (define (program-interactive)
93 (displayln "Interactive mode")
98 (("-i" "--interactive") "Interactive mode" (program-interactive))
99 (("-l" "--list") "View skipped and modified file status" (program-display-file-status))
100 (("-s" "--skip") file "Skip single file" (program-skip-file file))
101 (("-n" "--no-skip") file "Unskip single file" (program-no-skip-file file))
102 (("-p" "--no-skip-all") "Unskip every file" (program-no-skip-all))
103 (("-m" "--skip-modified") "Skip every modified file" (program-skip-modified)))