diff --git a/LICENSE b/LICENSE index bb6bec8..bcb3972 100755 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2018 m455 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2018 m455 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 4c4a1ed..6c03cbd --- a/README.md +++ b/README.md @@ -87,3 +87,4 @@ rm - `rodo rm 1` ## Configuring rodo Right now, the configurations can be found in the config.rkt file. Settings such at program name, path and directory can be set here. + diff --git a/args.rkt b/args.rkt index 568a6ef..8dd1422 100644 --- a/args.rkt +++ b/args.rkt @@ -1,47 +1,48 @@ -#lang racket/base - -(require racket/vector - racket/list - "config.rkt" - "init.rkt" - "util.rkt" - "messages.rkt") - -(provide (all-defined-out)) - -(define (check-args args) - (let - ([args-length (vector-length args)]) - (cond - [(equal? args-length 0) - (d-hash-ref messages 'show-usage)] - - [(and - (equal? args-length 1) - (equal? (vector-member list-command args) 0)) - (show-list)] - - [(and - (equal? args-length 2) - (equal? (vector-ref args 0) add-command)) - (add-item args)] - - [(and - (equal? args-length 2) - (equal? (vector-member remove-command args) 0) - (not (equal? (vector-member "0" args) 1)) - (vector-member (vector-ref args 1) (list->vector (map number->string (rest (range (length (file->string-list path)))))))) - (remove-item args)] - - [(and - (equal? args-length 1) - (equal? (vector-member initialize-command args) 0)) - (initialize)] - - [(and - (equal? args-length 1) - (member (vector-ref args 0) help-command)) - (d-hash-ref messages 'show-help)] - - [else - (d-hash-ref messages 'show-usage)]))) +#lang racket/base + +(require (prefix-in vector: racket/vector) + (prefix-in list: racket/list) + (prefix-in config: "config.rkt") + (prefix-in init: "init.rkt") + (prefix-in util: "util.rkt") + (prefix-in messages: "messages.rkt")) + +(provide (all-defined-out)) + +(define (check-args args) + (let([args-length (vector-length args)]) + (cond [(equal? args-length 0) + (util:display-hash-ref messages:messages 'show-usage)] + + [(and + (equal? args-length 1) + (equal? (vector:vector-member config:list-command args) 0)) + (util:show-list)] + + [(and + (equal? args-length 2) + (equal? (vector-ref args 0) config:add-command)) + (util:add-item args)] + + [(and + (equal? args-length 2) + (equal? (vector:vector-member config:remove-command args) 0) + (not (equal? (vector:vector-member "0" args) 1)) + (vector:vector-member + (vector-ref args 1) + (list->vector + (map number->string (list:rest (list:range (length (util:file->string-list config:path)))))))) + (util:remove-item args)] + + [(and + (equal? args-length 1) + (equal? (vector:vector-member config:initialize-command args) 0)) + (init:initialize)] + + [(and + (equal? args-length 1) + (member (vector-ref args 0) config:help-command)) + (util:display-hash-ref messages:messages 'show-help)] + + [else + (util:display-hash-ref messages:messages 'show-usage)]))) diff --git a/config.rkt b/config.rkt index 7c3fb23..ffd0ceb 100644 --- a/config.rkt +++ b/config.rkt @@ -1,19 +1,18 @@ -#lang racket/base -(require racket/file) -(provide (all-defined-out)) - -(define program-name "rodo") -(define program-directory ".rodo/") -(define program-path "~/") -(define program-file "todo-list") -(define remove-command "rm") -(define add-command "add") -(define list-command "ls") -(define initialize-command "init") -(define help-command '("-h" "--help")) -(define path - (expand-user-path - (string-append - program-path - program-directory - program-file))) +#lang racket/base +(provide (all-defined-out)) + +(define program-name "rodo") +(define program-directory ".rodo/") +(define program-path "~/") +(define program-file "todo-list") +(define remove-command "rm") +(define add-command "add") +(define list-command "ls") +(define initialize-command "init") +(define help-command '("-h" "--help")) +(define path + (expand-user-path + (string-append + program-path + program-directory + program-file))) diff --git a/init.rkt b/init.rkt index 020bedb..0b1627f 100644 --- a/init.rkt +++ b/init.rkt @@ -1,47 +1,45 @@ -#lang racket/base - -(require racket/file - "config.rkt" - "util.rkt" - "messages.rkt" - "io.rkt") - -(provide (all-defined-out)) - -(define (initialize-file) - (display-to-file - "--Do not edit this file--\n" - path - #:mode 'text - #:exists 'replace)) - -(define (init-prompt hash-list key) - (d-hash-ref hash-list key) - (display "> ") - (let - ([user-input (read-line)]) - (cond - [(member user-input (hash-ref y/n 'yes)) - (d-hash-ref messages 'creating-folder) - (d-hash-ref messages 'creating-file) - (create-folder) - (create-file) - (initialize-file) - (if - (and - (check-for-folder) - (check-for-file)) - (d-hash-ref messages 'successfully-created) - (d-hash-ref messages 'creation-error))] - - [(member user-input (hash-ref y/n 'no)) - (d-hash-ref messages 'terminating)] - - [else - (init-prompt messages 'choose-y/n)]))) - -(define (initialize) - (if (check-for-file) - (d-hash-ref messages 'file-already-exists) - (begin - (init-prompt messages 'init-y/n)))) +#lang racket/base + +(require (prefix-in file: racket/file) + (prefix-in config: "config.rkt") + (prefix-in util: "util.rkt") + (prefix-in messages: "messages.rkt")) + +(provide (all-defined-out)) + +(define (initialize-file) + (file:display-to-file + "--Do not edit this file--\n" + config:path + #:mode 'text + #:exists 'replace)) + +(define (init-prompt hash-list key) + (util:display-hash-ref hash-list key) + (display "> ") + (let + ([user-input (read-line)]) + (cond + [(member user-input (hash-ref messages:y/n 'yes)) + (util:display-hash-ref messages:messages 'creating-folder) + (util:display-hash-ref messages:messages 'creating-file) + (util:create-folder) + (util:create-file) + (initialize-file) + (if (and + (util:check-for-folder) + (util:check-for-file)) + (util:display-hash-ref messages:messages 'successfully-created) + (util:display-hash-ref messages:messages 'creation-error))] + + [(member user-input (hash-ref messages:y/n 'no)) + (util:display-hash-ref messages:messages 'terminating)] + + [else + (init-prompt messages:messages 'choose-y/n)]))) + +(define (initialize) + (if (util:check-for-file) + (util:display-hash-ref messages:messages 'file-already-exists) + (begin + (init-prompt messages:messages 'init-y/n)))) diff --git a/io.rkt b/io.rkt deleted file mode 100644 index 86373aa..0000000 --- a/io.rkt +++ /dev/null @@ -1,32 +0,0 @@ -#lang racket/base - -(require racket/file - "config.rkt") - -(provide (all-defined-out)) - -(define (check-for-file) - (file-exists? path)) - -(define (create-file) - (let - ([opened-file - (open-output-file - path - #:mode 'text - #:exists 'can-update)]) - (close-output-port opened-file))) - -(define (check-for-folder) - (directory-exists? - (expand-user-path - (string-append - program-path - program-directory)))) - -(define (create-folder) - (make-directory - (expand-user-path - (string-append - program-path - program-directory)))) diff --git a/messages.rkt b/messages.rkt index 3e21ceb..cfc1f78 100644 --- a/messages.rkt +++ b/messages.rkt @@ -1,145 +1,145 @@ -#lang racket/base - -(require "config.rkt") - -(provide (all-defined-out)) - -(define messages - (hash - 'show-help - (string-append - "* " initialize-command ": " - "initialize a file in " - program-path - program-directory - program-file - "\n" - "\x09Example: " - "rodo init\n\n" - - "* " list-command ": " - "lists items on the list" - "\n" - "\x09Example: " - "rodo ls\n\n" - - "* " add-command ": " - "adds an item to the list" - "\n" - "\x09Example: " - "rodo add bread\n\n" - "\x09Note: For multi-word items you will need to\n" - "\x09surround your item in double quotes as so:\n" - "\x09rodo add \"go to the bank\"\n" - - "* " remove-command ": " - "removes an item from the list\n" - "\x09Example: " - "rodo rm 1\n" - "\x09Note: You may have to run `rodo ls` to see which\n" - "\x09number corresponds to which item to remove it.\n") - - 'empty-todo-list - "> There is nothing in your list \n" - - 'show-usage - (string-append - "> For usage type " - "`" program-name " -h`" - " or " - "`" program-name " --help`\n") - - 'creating-folder - (string-append - "> creating a " - program-directory - " folder in " - program-path " ...\n") - - 'creating-file - (string-append - "> creating a " - program-file - " file in " - program-path - program-directory " ...\n") - - 'creation-error - (string-append - "> Error: Could not create " - program-file - " in " - program-directory - program-path ".\n" - "> This may be due to directory permissions\n") - - 'file-already-exists - (string-append - "> Error: " - program-name - " already exists in " - program-path - program-directory - program-file "\n") - - 'successfully-created - (string-append - "> " - program-path - program-directory - program-file - " has been successfully created\n") - - 'file-not-found - (string-append - "> Error: Could not find " - program-path - program-directory - program-file "\n") - - 'init-y/n - (string-append - "> A " - program-file - " file will be created in " - program-path - program-directory "\n" - "> Are you sure you want to continue? [y/n]\n") - - 'try-init - (string-append - "> Try typing " - "`" program-name " init` " - "to set it up\n") - - 'terminating - (string-append - "> Exiting " - program-name - " ...\n") - - 'choose-y/n - "> Error: Please choose y or n\n" - - 'not-in-list - "> Error: Item does not exist\n" - - 'item-added-prefix - "> Added " - - 'item-added-suffix - " to list\n" - - 'item-removed-prefix - "> Removed " - - 'item-removed-suffix - " from list\n")) - -(define y/n - (hash - 'yes - '("yes" "Yes" "y" "Y") - - 'no - '("no" "No" "n" "N"))) +#lang racket/base + +(require (prefix-in config: "config.rkt")) + +(provide (all-defined-out)) + +(define messages + (hash + 'show-help + (string-append + config:initialize-command ":\n" + "initialize a file in " + config:program-path + config:program-directory + config:program-file + "\n" + "Example: " + "rodo init\n\n" + + config:list-command ":\n" + "lists items on the list" + "\n" + "Example: " + "rodo ls\n\n" + + config:add-command ":\n" + "adds an item to the list" + "\n" + "Example: " + "rodo add bread\n\n" + "Note: For multi-word items you will need to\n" + "surround your item in double quotes as so:\n" + "rodo add \"go to the bank\"\n\n" + + config:remove-command ":\n" + "removes an item from the list\n" + "Example: " + "rodo rm 1\n\n" + "Note: You may have to run `rodo ls` to see which\n" + "number corresponds to which item to remove it.\n") + + 'empty-todo-list + "> There is nothing in your list \n" + + 'show-usage + (string-append + "> For usage type " + "`" config:program-name " -h`" + " or " + "`" config:program-name " --help`\n") + + 'creating-folder + (string-append + "> creating a " + config:program-directory + " folder in " + config:program-path " ...\n") + + 'creating-file + (string-append + "> creating a " + config:program-file + " file in " + config:program-path + config:program-directory " ...\n") + + 'creation-error + (string-append + "> Error: Could not create " + config:program-file + " in " + config:program-directory + config:program-path ".\n" + "> This may be due to directory permissions\n") + + 'file-already-exists + (string-append + "> Error: " + config:program-name + " already exists in " + config:program-path + config:program-directory + config:program-file "\n") + + 'successfully-created + (string-append + "> " + config:program-path + config:program-directory + config:program-file + " has been successfully created\n") + + 'file-not-found + (string-append + "> Error: Could not find " + config:program-path + config:program-directory + config:program-file "\n") + + 'init-y/n + (string-append + "> A " + config:program-file + " file will be created in " + config:program-path + config:program-directory "\n" + "> Are you sure you want to continue? [y/n]\n") + + 'try-init + (string-append + "> Try typing " + "`" config:program-name " init` " + "to set it up\n") + + 'terminating + (string-append + "> Exiting " + config:program-name + " ...\n") + + 'choose-y/n + "> Error: Please choose y or n\n" + + 'not-in-list + "> Error: Item does not exist\n" + + 'item-added-prefix + "> Added " + + 'item-added-suffix + " to list\n" + + 'item-removed-prefix + "> Removed " + + 'item-removed-suffix + " from list\n")) + +(define y/n + (hash + 'yes + '("yes" "Yes" "y" "Y") + + 'no + '("no" "No" "n" "N"))) diff --git a/rodo b/rodo deleted file mode 100755 index b67fb3c..0000000 Binary files a/rodo and /dev/null differ diff --git a/rodo.rkt b/rodo.rkt index 04f7b96..5263262 100755 --- a/rodo.rkt +++ b/rodo.rkt @@ -1,9 +1,9 @@ -#! /usr/bin/env racket -#lang racket/base - -(require "args.rkt") - -(define (main) - (check-args (current-command-line-arguments))) - -(main) +#! /usr/bin/env racket +#lang racket/base + +(require (prefix-in args: "args.rkt")) + +(define (main) + (args:check-args (current-command-line-arguments))) + +(main) diff --git a/util.rkt b/util.rkt index 3259ac6..829a4a4 100644 --- a/util.rkt +++ b/util.rkt @@ -1,116 +1,134 @@ -#lang racket/base - -(require racket/list - racket/file - racket/string - "config.rkt" - "io.rkt" - "messages.rkt") - -(provide (all-defined-out)) - -(define (d-hash-ref hash-list key) - (display (hash-ref hash-list key))) - -(define (d-vector-ref args key) - (display (vector-ref args key))) - -(define (file->string-list path-to-file) - (let - ([todo-list - (file->lines - path-to-file - #:mode 'text - #:line-mode 'any)]) - todo-list)) - -(define (list-empty? lst) - (empty? (rest (file->string-list lst)))) - -(define (get-removed-item lst args) - (list-ref lst (string->number args))) - -(define (quote-item args) - (display - (string-append "\"" args "\""))) - -(define (number-list lst) - (map string-append - (map number->string (rest (range (length lst)))) - (rest lst))) - -(define (indent-list lst) - (string-append ". " lst)) - -(define (prettify-list) - (display - (string-join - (number-list (map indent-list (file->string-list path))) - "\n" - #:after-last "\n"))) - -(define (show-list) - (cond - [(and - (check-for-folder) - (check-for-file)) - (if - (list-empty? path) - (d-hash-ref messages 'empty-todo-list) - (prettify-list))] - [else - (d-hash-ref messages 'file-not-found) - (d-hash-ref messages 'try-init)])) - -(define (add-item-to-file args) - (let ([new-list - (reverse - (cons args - (reverse (file->string-list path))))]) - (display-to-file - (string-join new-list "\n" #:after-last "\n") - path - #:mode 'text - #:exists 'replace) - (d-hash-ref messages 'item-added-prefix) - (quote-item args) - (d-hash-ref messages 'item-added-suffix))) - -(define (add-item args) - (if - (and - (check-for-folder) - (check-for-file)) - (add-item-to-file (vector-ref args 1)) - (begin - (d-hash-ref messages 'file-not-found) - (d-hash-ref messages 'try-init)))) - -(define (remove-item-from-file args) - (let ([removed-item - (get-removed-item (file->string-list path) args)] - [new-list - (remove - (list-ref (file->string-list path) (string->number args)) - (file->string-list path))]) - (display-to-file - (string-join new-list "\n" #:after-last "\n") - path - #:mode 'text - #:exists 'replace) - (d-hash-ref messages 'item-removed-prefix) - (quote-item removed-item) - (d-hash-ref messages 'item-removed-suffix))) - -(define (remove-item args) - (cond - [(list-empty? path) - (d-hash-ref messages 'empty-todo-list)] - [(and - (check-for-folder) - (check-for-file)) - (remove-item-from-file (vector-ref args 1))] - [(and (not (check-for-folder)) (not (check-for-file))) - (begin - (d-hash-ref messages 'file-not-found) - (d-hash-ref messages 'try-init))])) +#lang racket/base + +(require (prefix-in list: racket/list) + (prefix-in file: racket/file) + (prefix-in string: racket/string) + (prefix-in config: "config.rkt") + (prefix-in messages: "messages.rkt")) + +(provide (all-defined-out)) + +(define (check-for-file) + (file-exists? config:path)) + +(define (create-file) + (let ([opened-file + (open-output-file config:path + #:mode 'text + #:exists 'can-update)]) + (close-output-port opened-file))) + +(define (check-for-folder) + (directory-exists? (expand-user-path + (string-append + config:program-path + config:program-directory)))) + +(define (create-folder) + (make-directory (expand-user-path + (string-append + config:program-path + config:program-directory)))) + +(define (display-hash-ref hash-list key) + (display (hash-ref hash-list key))) + +(define (d-vector-ref args key) + (display (vector-ref args key))) + +(define (file->string-list config:path-to-file) + (let ([todo-list (file:file->lines config:path-to-file + #:mode 'text + #:line-mode 'any)]) + todo-list)) + +(define (list-empty? lst) + (list:empty? (list:rest (file->string-list lst)))) + +(define (get-removed-item lst args) + (list-ref lst (string->number args))) + +(define (quote-item args) + (display + (string-append "\"" args "\""))) + +(define (prefix-with-number lst) + (map string-append + (map number->string (list:rest (list:range (length lst)))) + (list:rest lst))) + +(define (prefix-with-period lst) + (string-append ". " lst)) + +(define (prettify-list) + (display + (string:string-join (prefix-with-number (map prefix-with-period (file->string-list config:path))) + "\n" + #:after-last "\n"))) + +(define (append-to-end args lst) + (reverse (cons args (reverse (file->string-list lst))))) + +(define (display-item-added args) + (display-hash-ref messages:messages 'item-added-prefix) + (quote-item args) + (display-hash-ref messages:messages 'item-added-suffix)) + +(define (display-item-removed args) + (display-hash-ref messages:messages 'item-removed-prefix) + (quote-item args) + (display-hash-ref messages:messages 'item-removed-suffix)) + +(define (show-list) + (cond [(and + (check-for-folder) + (check-for-file)) + (if + (list-empty? config:path) + (display-hash-ref messages:messages 'empty-todo-list) + (prettify-list))] + [else + (display-hash-ref messages:messages 'file-not-found) + (display-hash-ref messages:messages 'try-init)])) + +(define (add-item-to-file args) + (let ([new-list (append-to-end args config:path)]) + (file:display-to-file + (string:string-join new-list "\n" #:after-last "\n") + config:path + #:mode 'text + #:exists 'replace) + (display-item-added args))) + +(define (add-item args) + (if (and + (check-for-folder) + (check-for-file)) + (add-item-to-file (vector-ref args 1)) + (begin + (display-hash-ref messages:messages 'file-not-found) + (display-hash-ref messages:messages 'try-init)))) + +(define (remove-item-from-file args) + (let ([removed-item (get-removed-item (file->string-list config:path) args)] + [new-list (remove + (list-ref (file->string-list config:path) (string->number args)) + (file->string-list config:path))]) + (file:display-to-file + (string:string-join new-list "\n" #:after-last "\n") + config:path + #:mode 'text + #:exists 'replace) + (display-item-removed removed-item))) + +(define (remove-item args) + (cond [(list-empty? config:path) + (display-hash-ref messages:messages 'empty-todo-list)] + [(and + (check-for-folder) + (check-for-file)) + (remove-item-from-file (vector-ref args 1))] + [(and (not (check-for-folder)) (not (check-for-file))) + (begin + (display-hash-ref messages:messages 'file-not-found) + (display-hash-ref messages:messages 'try-init))]))