├── .gitignore ├── .npmignore ├── README.md ├── TODO.md ├── bin └── todo ├── gulpfile.coffee ├── package.json └── src ├── index.coffee ├── sep.coffee ├── symbol.coffee └── todo.coffee /.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | node_modules/ 3 | *.log -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | TODO.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # todomado 2 | 3 | ![screenshot](http://i2.tietuku.com/c82c6c7d2301aed0.gif) 4 | 5 | - [x] You made up your mind to create a todo? 6 | 7 | - [x] Update the body of it? 8 | 9 | - [x] Update the status of it? 10 | 11 | - [x] Or just drop it? 12 | 13 | - [x] Finally you can read all of it! 14 | 15 | ## Install 16 | 17 | Use `npm` please: 18 | 19 | [![NPM version](https://img.shields.io/npm/v/todomado.svg?style=flat)](https://www.npmjs.com/package/todomado) 20 | [![NPM download](https://img.shields.io/npm/dm/todomado.svg?style=flat)](https://www.npmjs.com/package/todomado) 21 | [![David Status](https://david-dm.org/touka0/todomado.svg)](https://david-dm.org/touka0/todomado) 22 | 23 | ``` 24 | sudo npm install -g todomado 25 | ``` 26 | 27 | ## Usage 28 | 29 | ```bash 30 | # Check version out 31 | $ todo -v 32 | 33 | # add 34 | $ todo add "to have some benchmark tests" 35 | 36 | # list 37 | $ todo 38 | 39 | # Modify by task number 40 | $ todo 0 -m "to have some other benchmark tests" 41 | 42 | # Delete by task number 43 | $ todo 0 -d 44 | 45 | ## Finished / Unfinished a task 46 | $ todo 0 done[, --done] 47 | $ todo 0 undone[, --undone] 48 | 49 | ``` 50 | 51 | ### Global TODO.md 52 | 53 | Wow! Sounds awesome! You can have a todo list globally instead of using in a project directory. 54 | 55 | Just by passing an arguement `-g`, just like: 56 | 57 | ```bash 58 | todo -g 59 | todo add "global todo item" -g 60 | ``` 61 | 62 | These todos will be stored in your home directory as `TODO.md`, in OS X it is `/Users/$whoami`, wherever you are just pass `-g` to make magic. 63 | 64 | ## License 65 | 66 | MIT. 67 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - [ ] GitHub push trigger 2 | - [ ] set task progress 3 | - [ ] todo history stat 4 | - [ ] add option for settings TODO.md save path, for example you want to save it to dropbox folder to sync it. 5 | -------------------------------------------------------------------------------- /bin/todo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | global.argv = require('minimist')(process.argv.slice(2)) 4 | 5 | var core = require('..') 6 | 7 | core(argv) 8 | -------------------------------------------------------------------------------- /gulpfile.coffee: -------------------------------------------------------------------------------- 1 | gulp = require 'gulp' 2 | coffee = require 'gulp-coffee' 3 | 4 | gulp.task 'coffee', -> 5 | gulp.src './src/*.coffee' 6 | .pipe coffee bare: true 7 | .pipe gulp.dest './lib' 8 | 9 | gulp.task 'watch', -> 10 | gulp.watch './src/*.coffee', ['coffee'] 11 | 12 | gulp.task 'default', ['coffee', 'watch'] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todomado", 3 | "version": "0.2.31", 4 | "description": "Command-line todo made easy", 5 | "main": "lib/index.js", 6 | "bin": { 7 | "todo": "./bin/todo" 8 | }, 9 | "scripts": { 10 | "start": "node lib/index.js", 11 | "test": "npm test" 12 | }, 13 | "keywords": [ 14 | "todo" 15 | ], 16 | "preferGlobal": true, 17 | "author": "Kchan Zen (http://www.kchanzen.com/)", 18 | "license": "MIT", 19 | "dependencies": { 20 | "chalk": "^1.0.0", 21 | "line-reader": "^0.2.4", 22 | "minimist": "^1.1.1", 23 | "trim": "0.0.1" 24 | }, 25 | "devDependencies": { 26 | "coffee-script": "^1.9.1", 27 | "gulp": "^3.8.11", 28 | "gulp-coffee": "^2.3.1" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/kchanzen/todomado.git" 33 | }, 34 | "bugs": { 35 | "url": "https://github.com/kchanzen/todomado/issues" 36 | }, 37 | "homepage": "https://github.com/kchanzen/todomado" 38 | } 39 | -------------------------------------------------------------------------------- /src/index.coffee: -------------------------------------------------------------------------------- 1 | global.chalk = require 'chalk' 2 | todo = require './todo' 3 | 4 | module.exports = (argv) -> 5 | if argv._.length is 0 and not argv.v 6 | todo.list() 7 | else if checkTopCommand() 8 | switch argv._[0] 9 | when 'init' then todo.init() 10 | when 'add' then todo.add() 11 | switch argv._[1] 12 | when 'done' then todo.done() 13 | when 'undone' then todo.undone() 14 | else if argv.m 15 | todo.modify() 16 | else if argv.d 17 | todo.drop() 18 | else if argv.v 19 | console.log 'todomado ~ ' + chalk.cyan require('../package').version 20 | else if argv.done 21 | todo.done() 22 | else if argv.undone 23 | todo.undone() 24 | else 25 | console.log chalk.red 'err: Unknown method' 26 | 27 | checkTopCommand = -> 28 | commands = ['init', 'add', 'done', 'undone'] 29 | return true if argv._[0] in commands 30 | return true if argv._[1] in commands 31 | return false 32 | -------------------------------------------------------------------------------- /src/sep.coffee: -------------------------------------------------------------------------------- 1 | sep = (inputHrStr) -> 2 | width = if process.stdout.isTTY then process.stdout.getWindowSize()[0] else 0 3 | hrStr = if inputHrStr.length > 0 then inputHrStr else '=' 4 | out = Array(Math.floor(width / hrStr.length) + 1).join(hrStr) 5 | partialLen = width - Math.floor(width / hrStr.length) * hrStr.length 6 | out += hrStr.substring(0, partialLen) 7 | out 8 | 9 | module.exports = sep -------------------------------------------------------------------------------- /src/symbol.coffee: -------------------------------------------------------------------------------- 1 | check = (line) -> 2 | symbol = get line 3 | return false if symbol is ' ' 4 | return true if symbol is 'x' 5 | 6 | get = (line) -> 7 | line.substr 3, 1 8 | 9 | getStatus = (line) -> 10 | status = get line 11 | if status is ' ' 12 | return 'undone' 13 | else if status is 'x' 14 | return 'done' 15 | 16 | clean = (line) -> 17 | line.substr 6 18 | 19 | module.exports = 20 | 21 | check: check, 22 | get: get, 23 | getStatus: getStatus, 24 | clean: clean -------------------------------------------------------------------------------- /src/todo.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | lineReader = require 'line-reader' 3 | trim = require 'trim' 4 | symbol = require('./symbol') 5 | sep = require './sep' 6 | cwd = process.cwd() 7 | encoding = 'utf-8' 8 | home = process.env.HOME or process.env.HOMEPATH or process.env.USERPROFILE 9 | lineNumber = argv._[0] 10 | filename = if argv.g then home + '/TODO.md' else cwd + '/TODO.md' 11 | 12 | todo = module.exports = 13 | 14 | list: -> 15 | fs.exists filename, (exists) -> 16 | if not exists 17 | console.log chalk.red 'You don\'t have any TODO.' 18 | console.log ' usage:' + chalk.cyan ' $ todo add -m "what am i going todo"' 19 | return 20 | else 21 | i = 0 22 | lineReader.eachLine filename, (line, last) -> 23 | hr() 24 | if symbol.check line 25 | mark = chalk.green i 26 | else 27 | mark = chalk.red i 28 | console.log mark + '.' + symbol.clean line 29 | i++ 30 | .then -> 31 | hr() 32 | 33 | init: -> 34 | 35 | init('My first todo') 36 | console.log chalk.green('It\'s done! Now use ') + 37 | chalk.underline('todo 0 -m "what to do"') + 38 | chalk.green(' to update it!') 39 | 40 | add: -> 41 | if not argv._[1] 42 | console.log chalk.red 'No todo given!' 43 | return 44 | fs.exists filename, (exists) -> 45 | if not exists 46 | init(argv._[1]) 47 | console.log chalk.green('Added, It\'s you first TODO!') 48 | else 49 | fs.appendFileSync filename, '- [ ] ' + argv._[1] + '\n', encoding 50 | console.log chalk.green('You added a new TODO, Cheers!') 51 | 52 | modify: -> 53 | modifyOrDelete 'modify' 54 | 55 | drop: -> 56 | modifyOrDelete 'delete' 57 | 58 | done: -> 59 | doneOrUndone 'done' 60 | 61 | undone: -> 62 | doneOrUndone 'undone' 63 | 64 | 65 | init = (item) -> 66 | content = '- [ ] ' + item + '\n' 67 | fs.writeFileSync filename, content, encoding 68 | 69 | modifyOrDelete = (type) -> 70 | lines = [] 71 | i = 0 72 | lineReader.eachLine filename, (line, last) -> 73 | lines[i] = line 74 | i++ 75 | .then -> 76 | if not isTask lines 77 | return 78 | if type is 'modify' 79 | lines[lineNumber] = '- [ ] ' + argv.m 80 | fs.writeFileSync filename, lines.join('\n') + '\n', encoding 81 | console.log chalk.green 'It\'s been modified!' 82 | else if type is 'delete' 83 | position = lines.indexOf lines[lineNumber] 84 | lines.splice position, 1 85 | newFile = lines.join('\n') + '\n' 86 | if trim(newFile) is '' 87 | newFile = '' 88 | fs.writeFileSync filename, newFile, encoding 89 | console.log chalk.green 'Task #' + lineNumber + ' is deleted!' 90 | 91 | doneOrUndone = (type) -> 92 | lines = [] 93 | i = 0 94 | lineReader.eachLine filename, (line, last) -> 95 | lines[i] = line 96 | i++ 97 | .then -> 98 | if not isTask lines 99 | return 100 | status = symbol.getStatus lines[lineNumber] 101 | if type is status 102 | console.log chalk.magenta 'You didn\'t make any change, ' + status + ' is still ' + status 103 | return 104 | else if type is 'done' 105 | newLine = replaceByRange lines[lineNumber], 0, 5, '- [x]' 106 | console.log 'The following task is ' + chalk.green('done') + ' now:' 107 | else if type is 'undone' 108 | newLine = replaceByRange lines[lineNumber], 0, 5, '- [ ]' 109 | console.log 'The following task is ' + chalk.green('undone') + ' now:' 110 | lines[lineNumber] = newLine 111 | fs.writeFileSync filename, lines.join('\n') + '\n', encoding 112 | console.log chalk.black.bgYellow ' ' + symbol.clean lines[lineNumber] + ' ' 113 | 114 | replaceByRange = (string, start, end, newString) -> 115 | string.substring(0, start) + 116 | newString + 117 | string.substring end 118 | 119 | hr = -> 120 | console.log chalk.gray sep '-' 121 | 122 | isTask = (lines) -> 123 | position = lines.indexOf lines[lineNumber] 124 | if not ~position 125 | console.log chalk.red 'Can\'t find task in this line!' 126 | return false 127 | return true 128 | --------------------------------------------------------------------------------