rewrote everything
parent
56397bb866
commit
570ef8d78f
18
args.rkt
18
args.rkt
|
@ -16,30 +16,30 @@
|
||||||
|
|
||||||
;; help-command
|
;; help-command
|
||||||
[(and (equal? args-length 1)
|
[(and (equal? args-length 1)
|
||||||
(member (list-ref args 0) config:help-command))
|
(member (list-ref args 0) config:help-commands))
|
||||||
(utils:display-hash-ref messages:messages 'show-help)]
|
(utils:display-hash-ref messages:messages 'show-help)]
|
||||||
|
|
||||||
;; initialize-command
|
;; initialize-command
|
||||||
[(and (equal? args-length 1)
|
[(and (equal? args-length 1)
|
||||||
(member (list-ref args 0) config:initialize-command))
|
(member (list-ref args 0) config:initialize-commands))
|
||||||
(init:initialize)]
|
(init:check-initialize-conditions)]
|
||||||
|
|
||||||
;; add-command
|
;; add-command
|
||||||
[(and (or (equal? args-length 2) (>= args-length 2))
|
[(and (or (equal? args-length 2) (>= args-length 2))
|
||||||
(member (list-ref args 0) config:add-command))
|
(member (list-ref args 0) config:add-commands))
|
||||||
(utils:add-item-to-list config:list-file args)]
|
(utils:check-add-conditions args)]
|
||||||
|
|
||||||
;; list-command
|
;; list-command
|
||||||
[(and (equal? args-length 1)
|
[(and (equal? args-length 1)
|
||||||
(member (list-ref args 0) config:list-command))
|
(member (list-ref args 0) config:list-commands))
|
||||||
(utils:show-list-from-file config:list-file)]
|
(utils:check-list-conditions)]
|
||||||
|
|
||||||
;; remove-command
|
;; remove-command
|
||||||
[(and (equal? args-length 2)
|
[(and (equal? args-length 2)
|
||||||
(member (list-ref args 0) config:remove-command)
|
(member (list-ref args 0) config:remove-commands)
|
||||||
(real? (string->number (list-ref args 1)))
|
(real? (string->number (list-ref args 1)))
|
||||||
(or (positive? (string->number (list-ref args 1)))
|
(or (positive? (string->number (list-ref args 1)))
|
||||||
(zero? (string->number (list-ref args 1)))))
|
(zero? (string->number (list-ref args 1)))))
|
||||||
(utils:remove-item-from-list args)]
|
(utils:check-remove-conditions args)]
|
||||||
|
|
||||||
[else (utils:display-hash-ref messages:messages 'show-usage)])))
|
[else (utils:display-hash-ref messages:messages 'show-usage)])))
|
||||||
|
|
41
config.rkt
41
config.rkt
|
@ -6,34 +6,29 @@
|
||||||
|
|
||||||
(define program-directory
|
(define program-directory
|
||||||
(path->string
|
(path->string
|
||||||
(expand-user-path
|
(expand-user-path
|
||||||
(string-append "~/." program-name "/"))))
|
(string-append "~/." program-name "/"))))
|
||||||
|
|
||||||
(define list-file
|
(define list-file
|
||||||
(string-append program-directory file-name))
|
(string-append program-directory file-name))
|
||||||
|
|
||||||
;; TODO: pluralize this value's name
|
(define help-commands '("-h"
|
||||||
(define help-command '("-h"
|
"--help"
|
||||||
"--help"
|
"h"
|
||||||
"h"
|
"help"))
|
||||||
"help"))
|
|
||||||
|
|
||||||
;; TODO: pluralize this value's name
|
(define initialize-commands '("init"
|
||||||
(define initialize-command '("init"
|
"create"
|
||||||
"create"
|
"start"
|
||||||
"start"
|
"begin"))
|
||||||
"begin"))
|
|
||||||
|
|
||||||
;; TODO: pluralize this value's name
|
(define add-commands '("add"
|
||||||
(define add-command '("add"
|
"a"))
|
||||||
"a"))
|
|
||||||
|
|
||||||
;; TODO: pluralize this value's name
|
(define list-commands '("ls"
|
||||||
(define list-command '("ls"
|
"list"))
|
||||||
"list"))
|
|
||||||
|
|
||||||
;; TODO: pluralize this value's name
|
(define remove-commands '("rm"
|
||||||
(define remove-command '("rm"
|
"remove"
|
||||||
"remove"
|
"del"
|
||||||
"del"
|
"delete"))
|
||||||
"delete"))
|
|
||||||
|
|
31
init.rkt
31
init.rkt
|
@ -6,26 +6,27 @@
|
||||||
|
|
||||||
(provide (all-defined-out))
|
(provide (all-defined-out))
|
||||||
|
|
||||||
(define (init-prompt hash-list key)
|
(define (create-initialization-contents)
|
||||||
(utils:display-hash-ref hash-list key)
|
(utils:display-hash-ref messages:messages 'creating)
|
||||||
|
(utils:create-directory-700 config:program-directory)
|
||||||
|
(utils:create-file-600 config:list-file)
|
||||||
|
(if (and (directory-exists? config:program-directory)
|
||||||
|
(file-exists? config:list-file))
|
||||||
|
(utils:display-hash-ref messages:messages 'successfully-created)
|
||||||
|
;; Otherwise
|
||||||
|
(utils:display-hash-ref messages:messages 'creation-error)))
|
||||||
|
|
||||||
|
(define (initialize)
|
||||||
|
(utils:display-hash-ref messages:messages 'init-y/n)
|
||||||
(display "> ")
|
(display "> ")
|
||||||
(let ([user-input (read-line)])
|
(let ([user-input (read-line)])
|
||||||
(cond [(member user-input (hash-ref messages:y/n 'yes))
|
(cond [(member user-input (hash-ref messages:y/n 'yes))
|
||||||
(begin
|
(create-initialization-contents)]
|
||||||
(utils:display-hash-ref messages:messages 'creating)
|
|
||||||
(utils:create-directory-700 config:program-directory)
|
|
||||||
(utils:create-file-600 config:list-file)
|
|
||||||
(if (and (directory-exists? config:program-directory)
|
|
||||||
(file-exists? config:list-file))
|
|
||||||
(utils:display-hash-ref messages:messages 'successfully-created)
|
|
||||||
(utils:display-hash-ref messages:messages 'creation-error)))]
|
|
||||||
[(member user-input (hash-ref messages:y/n 'no))
|
[(member user-input (hash-ref messages:y/n 'no))
|
||||||
(utils:display-hash-ref messages:messages 'terminating)]
|
(utils:display-hash-ref messages:messages 'terminating)]
|
||||||
[else
|
[else (utils:display-hash-ref messages:messages 'choose-y/n)])))
|
||||||
(init-prompt messages:messages 'choose-y/n)])))
|
|
||||||
|
|
||||||
(define (initialize)
|
(define (check-initialize-conditions)
|
||||||
(if (file-exists? config:list-file)
|
(if (file-exists? config:list-file)
|
||||||
(utils:display-hash-ref messages:messages 'file-already-exists)
|
(utils:display-hash-ref messages:messages 'file-already-exists)
|
||||||
(begin
|
(initialize)))
|
||||||
(init-prompt messages:messages 'init-y/n))))
|
|
||||||
|
|
64
messages.rkt
64
messages.rkt
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
(provide (all-defined-out))
|
(provide (all-defined-out))
|
||||||
|
|
||||||
(define newline "\n")
|
(define (indent string)
|
||||||
|
(string-append "\t" string))
|
||||||
|
|
||||||
(define messages
|
(define messages
|
||||||
(hash
|
(hash
|
||||||
|
@ -22,80 +23,68 @@
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; initialize-command
|
;; initialize-command
|
||||||
(format "~a" (car config:initialize-command))
|
(format "~a" (car config:initialize-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent (format "Creates a list in ~a." config:list-file))
|
||||||
(format "Creates a list in ~a." config:list-file)
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; list-command
|
;; list-command
|
||||||
(format "~a" (car config:list-command))
|
(format "~a" (car config:list-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent "Displays items in your list.")
|
||||||
"Displays items in your list."
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; add-command
|
;; add-command
|
||||||
(format "~a" (car config:add-command))
|
(format "~a" (car config:add-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent "Adds an item to your list.")
|
||||||
"Adds an item to your list."
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; remove-command
|
;; remove-command
|
||||||
(format "~a" (car config:remove-command))
|
(format "~a" (car config:remove-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent "Removes an item from your list.")
|
||||||
"Removes an item from your list."
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
"Usage examples\n"
|
"Usage examples\n"
|
||||||
"=============="
|
"=============="
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; initialize-command
|
;; initialize-command
|
||||||
(format "~a" (car config:initialize-command))
|
(format "~a" (car config:initialize-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent (format "~a ~a" config:program-name (car config:initialize-commands)))
|
||||||
(format "~a ~a" config:program-name (car config:initialize-command))
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; list-command
|
;; list-command
|
||||||
(format "~a" (car config:list-command))
|
(format "~a" (car config:list-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent (format "~a ~a" config:program-name (car config:list-commands)))
|
||||||
(format "~a ~a" config:program-name (car config:list-command))
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; add-command
|
;; add-command
|
||||||
(format "~a" (car config:add-command))
|
(format "~a" (car config:add-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent (format "~a ~a this is an item without double quotation marks" config:program-name (car config:add-commands)))
|
||||||
(format "~a ~a this is an item without double quotation marks" config:program-name (car config:add-command))
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent (format "~a ~a \"this is an item surrounded by double quotation marks\"" config:program-name (car config:add-commands)))
|
||||||
(format "~a ~a \"this is an item surrounded by double quotation marks\"" config:program-name (car config:add-command))
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent "Note: Grave accents (`) and single quotation marks (\') cannot be used with this command.")
|
||||||
"Note: Grave accents (`) and single quotation marks (\') cannot be used with this command."
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
;; remove-command
|
;; remove-command
|
||||||
(format "~a" (car config:remove-command))
|
(format "~a" (car config:remove-commands))
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent (format "~a ~a 2" config:program-name (car config:remove-commands)))
|
||||||
(format "~a ~a 2" config:program-name (car config:remove-command))
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
(indent "Note: The example above will remove the third item from your list, because the list starts at zero.")
|
||||||
"Note: The example above will remove the third item from your list, because the list starts at zero."
|
|
||||||
"\n\n"
|
"\n\n"
|
||||||
|
|
||||||
"Can't see the whole help message?\n"
|
"Can't see the whole help message?\n"
|
||||||
"================================="
|
"================================="
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
|
||||||
(format "Try running \"~a -h | less\" (without the double quotation marks), so you can use the arrow keys to scroll up and down." config:program-name)
|
(format "Try running \"~a -h | less\" (without the double quotation marks), so you can use the arrow keys to scroll up and down." config:program-name)
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"\t"
|
|
||||||
"When you want to quit, type \"q\" (without the double quotation marks)."
|
"When you want to quit, type \"q\" (without the double quotation marks)."
|
||||||
"\n\n")
|
"\n\n")
|
||||||
|
|
||||||
|
@ -120,7 +109,7 @@
|
||||||
config:list-file)
|
config:list-file)
|
||||||
|
|
||||||
'try-init (format "> Try typing \"~a ~a\" to set it up (without the double quotation marks).\n"
|
'try-init (format "> Try typing \"~a ~a\" to set it up (without the double quotation marks).\n"
|
||||||
config:program-name (car config:initialize-command))
|
config:program-name (car config:initialize-commands))
|
||||||
|
|
||||||
'terminating (format "> Exited ~a.\n" config:program-name)
|
'terminating (format "> Exited ~a.\n" config:program-name)
|
||||||
|
|
||||||
|
@ -128,13 +117,10 @@
|
||||||
|
|
||||||
'not-in-list "> Error: Item does not exist\n"
|
'not-in-list "> Error: Item does not exist\n"
|
||||||
|
|
||||||
'item-added-prefix "> Added "
|
'item-added "> Added \"~a\" to your list\n"
|
||||||
|
|
||||||
'item-added-suffix " to list\n"
|
'item-removed "> Removed \"~a\" from your list\n"))
|
||||||
|
|
||||||
'item-removed-prefix "> Removed "
|
|
||||||
|
|
||||||
'item-removed-suffix " from list\n"))
|
|
||||||
|
|
||||||
(define y/n (hash 'yes '("yes" "Yes" "y" "Y")
|
(define y/n (hash 'yes '("yes" "Yes" "y" "Y")
|
||||||
'no '("no" "No" "n" "N")))
|
'no '("no" "No" "n" "N")))
|
||||||
|
|
91
utils.rkt
91
utils.rkt
|
@ -20,6 +20,10 @@
|
||||||
(define (display-hash-ref hash-list key)
|
(define (display-hash-ref hash-list key)
|
||||||
(display (hash-ref hash-list key)))
|
(display (hash-ref hash-list key)))
|
||||||
|
|
||||||
|
(define (display-hash-ref-multi hash-list key-list)
|
||||||
|
(for ([key key-list])
|
||||||
|
(display (hash-ref hash-list key))))
|
||||||
|
|
||||||
(define (list->ascending-numbers lst)
|
(define (list->ascending-numbers lst)
|
||||||
(list:range (length lst)))
|
(list:range (length lst)))
|
||||||
|
|
||||||
|
@ -41,61 +45,58 @@
|
||||||
(define (surround-with-quotation-marks item)
|
(define (surround-with-quotation-marks item)
|
||||||
(string-append "\"" item "\""))
|
(string-append "\"" item "\""))
|
||||||
|
|
||||||
(define (display-item-added item)
|
(define (display-item-added item-to-add)
|
||||||
(display-hash-ref messages:messages 'item-added-prefix)
|
(display (format (hash-ref messages:messages 'item-added) item-to-add)))
|
||||||
(display (surround-with-quotation-marks item))
|
|
||||||
(display-hash-ref messages:messages 'item-added-suffix))
|
|
||||||
|
|
||||||
(define (display-item-removed args)
|
(define (display-item-removed item-to-remove)
|
||||||
(display-hash-ref messages:messages 'item-removed-prefix)
|
(display (format (hash-ref messages:messages 'item-removed) item-to-remove)))
|
||||||
(display (surround-with-quotation-marks args))
|
|
||||||
(display-hash-ref messages:messages 'item-removed-suffix))
|
|
||||||
|
|
||||||
;; TODO: Turn into a check-show-list-conditions and then break
|
(define (check-list-conditions)
|
||||||
;; the rest down into separate functions
|
|
||||||
(define (show-list-from-file a-file)
|
|
||||||
(cond
|
(cond
|
||||||
;; If exists and not empty
|
;; If exists and not empty
|
||||||
[(and (file-exists? config:list-file)
|
[(and (file-exists? config:list-file)
|
||||||
(not (null? (file:file->lines a-file))))
|
(not (null? (file:file->lines config:list-file))))
|
||||||
(display (file->vertically-numbered-list a-file))]
|
(display (file->vertically-numbered-list config:list-file))]
|
||||||
|
|
||||||
;; If exists and empty
|
;; If exists and empty
|
||||||
[(and (file-exists? config:list-file)
|
[(and (file-exists? config:list-file)
|
||||||
(null? (file:file->lines a-file)))
|
(null? (file:file->lines config:list-file)))
|
||||||
(display-hash-ref messages:messages 'empty-list)]
|
(display-hash-ref messages:messages 'empty-list)]
|
||||||
|
|
||||||
;; If not exist
|
;; If not exist
|
||||||
[(and (not (file-exists? config:list-file)))
|
[(and (not (file-exists? config:list-file)))
|
||||||
(begin
|
(display-hash-ref-multi messages:messages '(file-not-found try-init))]
|
||||||
(display-hash-ref messages:messages 'file-not-found)
|
|
||||||
(display-hash-ref messages:messages 'try-init))]
|
|
||||||
|
|
||||||
;; Otherwise
|
|
||||||
[else (display-hash-ref messages:messages 'show-usage)]))
|
[else (display-hash-ref messages:messages 'show-usage)]))
|
||||||
|
|
||||||
(define (append-item-to-list args lst)
|
(define (append-element-to-end-of-list lst item-to-add)
|
||||||
(append (file:file->lines lst) '(args)))
|
(reverse (cons item-to-add (reverse (file:file->lines lst)))))
|
||||||
|
|
||||||
;; TODO: Turn into a check-add-conditions and then break
|
(define (add-item-to-list args)
|
||||||
;; the rest down into separate procedures
|
(let* ([item-to-add (string:string-join (cdr args) " ")]
|
||||||
(define (add-item-to-list a-file args)
|
[new-list (append-element-to-end-of-list config:list-file item-to-add)])
|
||||||
|
(file:display-lines-to-file new-list
|
||||||
|
config:list-file
|
||||||
|
#:mode 'text
|
||||||
|
#:exists 'truncate)
|
||||||
|
(display-item-added item-to-add)))
|
||||||
|
|
||||||
|
(define (check-add-conditions args)
|
||||||
(if (and (file-exists? config:list-file))
|
(if (and (file-exists? config:list-file))
|
||||||
;; Make this a procedure
|
(add-item-to-list args)
|
||||||
(let* ([item (string:string-join (cdr args) " ")]
|
;; Otherwise
|
||||||
[new-list (append-item-to-list item config:list-file)])
|
(display-hash-ref-multi messages:messages '(file-not-found try-init))))
|
||||||
(file:display-to-file (string:string-join new-list "\n")
|
|
||||||
config:list-file
|
|
||||||
#:mode 'text
|
|
||||||
#:exists 'truncate)
|
|
||||||
(display-item-added item))
|
|
||||||
(begin
|
|
||||||
(display-hash-ref messages:messages 'file-not-found)
|
|
||||||
(display-hash-ref messages:messages 'try-init))))
|
|
||||||
|
|
||||||
;; TODO: Turn into a check-remove-conditions and then break
|
(define (remove-item-from-list user-args)
|
||||||
;; the rest down into separate procedures
|
(let* ([item-to-remove (list-ref (file:file->lines config:list-file) user-args)]
|
||||||
(define (remove-item-from-list args)
|
[new-list (remove item-to-remove (file:file->lines config:list-file))])
|
||||||
|
(file:display-lines-to-file new-list
|
||||||
|
config:list-file
|
||||||
|
#:mode 'text
|
||||||
|
#:exists 'truncate)
|
||||||
|
(display-item-removed item-to-remove)))
|
||||||
|
|
||||||
|
(define (check-remove-conditions args)
|
||||||
(cond
|
(cond
|
||||||
;; If directory and file exist, but file is empty
|
;; If directory and file exist, but file is empty
|
||||||
[(and (directory-exists? config:program-directory)
|
[(and (directory-exists? config:program-directory)
|
||||||
|
@ -111,21 +112,11 @@
|
||||||
;; Length subtract one because the numbering starts at zero
|
;; Length subtract one because the numbering starts at zero
|
||||||
[list-length (sub1 (length (file:file->lines config:list-file)))])
|
[list-length (sub1 (length (file:file->lines config:list-file)))])
|
||||||
(if (not (> user-args list-length))
|
(if (not (> user-args list-length))
|
||||||
;; Make this a procedure
|
(remove-item-from-list user-args)
|
||||||
(let* ([item-to-remove (list-ref (file:file->lines config:list-file) user-args)]
|
;; Otherwise
|
||||||
[new-list (remove item-to-remove (file:file->lines config:list-file))])
|
|
||||||
;; Might be able to just use display-lines-to-file procedure. See docs
|
|
||||||
(file:display-to-file (string:string-join new-list "\n")
|
|
||||||
config:list-file
|
|
||||||
#:mode 'text
|
|
||||||
#:exists 'truncate)
|
|
||||||
(display-item-removed item-to-remove))
|
|
||||||
;; Else
|
|
||||||
(display-hash-ref messages:messages 'item-not-found)))]
|
(display-hash-ref messages:messages 'item-not-found)))]
|
||||||
|
|
||||||
;; If directory and file don't exist
|
;; If directory and file don't exist
|
||||||
[(and (not (directory-exists? config:program-directory))
|
[(and (not (directory-exists? config:program-directory))
|
||||||
(not (file-exists? config:list-file)))
|
(not (file-exists? config:list-file)))
|
||||||
(begin
|
(display-hash-ref-multi messages:messages '(file-not-found try-init))]))
|
||||||
(display-hash-ref messages:messages 'file-not-found)
|
|
||||||
(display-hash-ref messages:messages 'try-init))]))
|
|
||||||
|
|
Loading…
Reference in New Issue