Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,11 @@
"nodeunit": "^0.9.0",
"tsd": "^0.5.7",
"typescript": "^1.3.0"
},
"compilerOptions": {
"target": "es6",
"module": "esm",
"types": ["nodeunit"]

}
}
10 changes: 6 additions & 4 deletions typescript/src/task.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

export class Task
{
constructor(private _id: number, private _description: string, private _done: boolean) {}
export class Task {
constructor(
private readonly _id: number,
private _description: string,
private _done: boolean
) { }

get id() {
return this._id;
Expand Down
193 changes: 88 additions & 105 deletions typescript/src/task_list.ts
Original file line number Diff line number Diff line change
@@ -1,164 +1,147 @@
/// <reference path="../typings/node/node.d.ts" />

import readline = require('readline');
import util = require('util');

import task = require('./task');

function splitFirstSpace(s: string) {
var pos = s.indexOf(' ');
if(pos === -1) {
return [s];
}
return [s.substr(0, pos), s.substr(pos+1)]
import * as readline from 'readline';
import * as util from 'util';
import { Task } from './task';

enum Commands {
SHOW = 'show',
ADD_PROJECT = 'add project',
ADD_TASK = 'add task',
CHECK = 'check',
UNCHECK = 'uncheck',
HELP = 'help',
QUIT = "QUIT"
}

export class TaskList
{
static QUIT = 'quit';
private readline;
private tasks: {[index: string]: task.Task[]} = {};
export class TaskList {
private readonly readlineInterface;
private readonly tasks: Record<string, Task[]> = {};
private lastId = 0;

constructor(reader: NodeJS.ReadableStream, writer: NodeJS.WritableStream) {

this.readline = readline.createInterface({
constructor(private readonly reader: NodeJS.ReadableStream, private readonly writer: NodeJS.WritableStream) {
this.readlineInterface = readline.createInterface({
terminal: false,
input: reader,
output: writer
});

this.readline.setPrompt("> ");
this.readline.on('line', (cmd) => {
if(cmd == TaskList.QUIT) {
this.readline.close();
return;
}
this.execute(cmd);
this.readline.prompt();
});
this.readline.on('close', () => {
writer.end();
output: writer,
});
}

println(ln: string) {
this.readline.output.write(ln);
this.readline.output.write('\n');
this.setupReadline();
}

run() {
this.readline.prompt();
private setupReadline() {
this.readlineInterface.setPrompt('> ');
this.readlineInterface.on('line', this.handleCommand.bind(this));
this.readlineInterface.on('close', () => this.writer.end());
}

forEachProject(func: (key: string, value: task.Task[]) => any) {
for(var key in this.tasks) {
if(this.tasks.hasOwnProperty(key))
func(key, this.tasks[key])
}
}
private handleCommand(commandLine: string) {
const [command, rest] = this.splitFirstSpace(commandLine);

execute(commandLine: string) {
var commandRest = splitFirstSpace(commandLine);
var command = commandRest[0];
switch (command) {
case "show":
case Commands.QUIT:
this.readlineInterface.close();
break;
case Commands.SHOW:
this.show();
break;
case "add":
this.add(commandRest[1]);
case Commands.ADD_PROJECT:
this.addProject(rest);
break;
case "check":
this.check(commandRest[1]);
case Commands.ADD_TASK:
this.addTask(rest);
break;
case "uncheck":
this.uncheck(commandRest[1]);
case Commands.CHECK:
this.setDone(rest, true);
break;
case "help":
case Commands.UNCHECK:
this.setDone(rest, false);
break;
case Commands.HELP:
this.help();
break;
default:
this.error(command);
break;
}

this.readlineInterface.prompt();
}

private splitFirstSpace(s: string): [string, string] {
const pos = s.indexOf(' ');
if (pos === -1) {
return [s, ''];
}
return [s.substr(0, pos), s.substr(pos + 1)];
}

private show() {
this.forEachProject((project, taskList) => {
for (const [project, taskList] of Object.entries(this.tasks)) {
this.println(project);
taskList.forEach((task) => {
this.println(util.format(" [%s] %d: %s", (task.done ? 'x' : ' '), task.id, task.description));
this.println(util.format(' [%s] %d: %s', task.done ? 'x' : ' ', task.id, task.description));
});
this.println('');
});
}

private add(commandLine: string) {
var subcommandRest = splitFirstSpace(commandLine);
var subcommand = subcommandRest[0];
if (subcommand === "project") {
this.addProject(subcommandRest[1]);
} else if (subcommand === "task") {
var projectTask = splitFirstSpace(subcommandRest[1]);
this.addTask(projectTask[0], projectTask[1]);
}
}

private addProject(name: string) {
this.tasks[name] = [];
}

private addTask(project: string, description: string) {
var projectTasks = this.tasks[project];
if (projectTasks == null) {
this.println(util.format("Could not find a project with the name \"%s\".", project));
private addTask(commandLine: string) {
const [project, description] = this.splitFirstSpace(commandLine);
const projectTasks = this.tasks[project];

if (!projectTasks) {
this.println(util.format('Could not find a project with the name "%s".', project));
return;
}
projectTasks.push(new task.Task(this.nextId(), description, false));
}

private check(idString: string) {
this.setDone(idString, true);
}

private uncheck(idString: string) {
this.setDone(idString, false);
projectTasks.push(new Task(this.nextId(), description, false));
}

private setDone(idString: string, done: boolean) {
var id = parseInt(idString, 10);
var found = false;
this.forEachProject((project, taskList) => {
taskList.forEach((task) => {
if (task.id == id) {
task.done = done;
found = true;
}
});
});
if(!found)
this.println(util.format("Could not find a task with an ID of %d.", id));
const id = parseInt(idString, 10);

for (const taskList of Object.values(this.tasks)) {
const task = taskList.find((t) => t.id === id);
if (task) {
task.done = done;
return;
}
}

this.println(util.format('Could not find a task with an ID of %d.', id));
}

private help() {
this.println("Commands:");
this.println(" show");
this.println(" add project <project name>");
this.println(" add task <project name> <task description>");
this.println(" check <task ID>");
this.println(" uncheck <task ID>");
this.println("");
this.println('Commands:');
this.println(' show');
this.println(' add project <project name>');
this.println(' add task <project name> <task description>');
this.println(' check <task ID>');
this.println(' uncheck <task ID>');
this.println('');
}

private error(command: string) {
this.println('I don\'t know what the command "' + command + '" is.');
this.println(`I don't know what the command "${command}" is.`);
}

private println(ln: string) {
this.readlineInterface.output.write(ln);
this.readlineInterface.output.write('\n');
}

private nextId(): number {
return ++this.lastId;
}

run() {
this.readlineInterface.prompt();
}
}

if(require.main == module) {
new TaskList(process.stdin, process.stdout).run()
if (require.main === module) {
new TaskList(process.stdin, process.stdout).run();
}