Added an interactive mode.
authorsabadev <saba@sabadev.xyz>
Mon, 12 Jul 2021 00:49:51 +0000 (20:49 -0400)
committersabadev <saba@sabadev.xyz>
Mon, 12 Jul 2021 00:49:51 +0000 (20:49 -0400)
git-skipper.rkt

index 5ec4e4a..92f4c9b 100644 (file)
@@ -3,31 +3,73 @@
 (require racket/system
          racket/port
          racket/cmdline
-         racket/string)
-
-(define (git . args) (string-split (with-output-to-string (λ () (system (string-join (cons "git" args))))) "\n"))
+         racket/function
+         racket/match
+         racket/string
+         racket/list)
 
+#| String helper functions |#
 (define (split-prefix str)
   (define components (string-split str))
   (define head (car components))
-  (define tail (string-join (list-tail components 1)))
+  (define tail (string-join (rest components)))
   (cons head tail))
 
 (define (file-string file) (format "\"~a\"" file))
+(define non-blank-string? (compose1 non-empty-string? string-trim))
 
+#| Git commands |#
+(define (git . args) (string-split (with-output-to-string (λ () (system (string-join (cons "git" args))))) "\n"))
 (define (ls-files . args) (map split-prefix (git "ls-files" "-v" (string-join args))))
+(define (update-index . args) (git "update-index" (string-join args)))
+
 (define (modified-files) (map cdr (ls-files "-m")))
 (define (skipped-files) (map cdr (filter (λ (pair) (equal? "S" (car pair))) (ls-files))))
 
-(define (update-index . args) (git "update-index" (string-join args)))
 (define (skip-file file) (update-index "--skip-worktree" (file-string file)))
 (define (no-skip-file file) (update-index "--no-skip-worktree" (file-string file)))
 (define (skip-modified) (for-each skip-file (modified-files)))
 (define (no-skip-all) (for-each no-skip-file (skipped-files)))
 
+#| Interactive mode helper methods |#
+(define (find-numbered-list number items) (map cdr (filter (compose1 (curry equal? number) number->string car) items)))
+(define (numbered-list items) (map cons (inclusive-range 1 (length items)) items))
+(define (format-pair pair) (format "~a - ~a" (car pair) (cdr pair)))
+(define (format-numbered-list items) (map format-pair (numbered-list items)))
+
+(define (parse-input input) (regexp-match* #px"([sn])(\\d+)" input #:match-select rest))
+
+(define (interpret-input skipped-file-list modified-file-list pair)
+  (match (car pair)
+    ("s" (for-each skip-file (find-numbered-list (cadr pair) (numbered-list modified-file-list))))
+    ("n" (for-each no-skip-file (find-numbered-list (cadr pair) (numbered-list skipped-file-list))))))
+
+(define (handle-input input skipped-file-list modified-file-list)
+  (if (non-blank-string? input)
+    (for-each (curry interpret-input skipped-file-list modified-file-list) (parse-input input))
+    #f))
+
+(define (interactive-prompt skipped-file-list modified-file-list)
+  (displayln "Skipped Files:")
+  (for-each displayln (format-numbered-list skipped-file-list))
+  (displayln "Modified Files:")
+  (for-each displayln (format-numbered-list modified-file-list))
+  (displayln "Enter 's' or 'n' followed by a file number to skip or unskip a file respectively.")
+  (displayln "e.g. 's3 n12' skips the third file under Modified Files then unskips the twelfth file under Skipped Files.")
+  (displayln "Enter a blank line to quit.")
+  (display "Input: ")
+  (read-line))
+
+(define (interactive-loop)
+  (define skipped-file-list (skipped-files))
+  (define modified-file-list (modified-files))
+  (if (handle-input (interactive-prompt skipped-file-list modified-file-list) skipped-file-list modified-file-list)
+    (interactive-loop)
+    #f))
+
 #| Programs |#
 (define (program-display-skipped-files)
-  (displayln "Skipped files:")
+  (displayln "Skipped Files:")
   (for-each displayln (skipped-files)))
 
 (define (program-skip-file file)
   (skip-modified)
   (program-display-skipped-files))
 
+(define (program-interactive)
+  (displayln "Interactive mode")
+  (interactive-loop))
+
 (command-line
   #:once-any
-  #| (("-i" "--interactive") "Interactive mode" (interactive)) |#
+  (("-i" "--interactive") "Interactive mode" (program-interactive))
   (("-l" "--list") "View skipped files" (program-display-skipped-files))
   (("-s" "--skip") file "Skip single file" (program-skip-file file))
   (("-n" "--no-skip") file "Unskip single file" (program-no-skip-file file))