1 /**
2 * Copyright (C) 2014 Aaron Ball <nullspoon@iohq.net>
3 *
4 * Noteless is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Noteless is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with noteless. If not, see <http://www.gnu.org/licenses/>.
16 */
17 using namespace std;
18 #include <iostream>
19 #include <stdlib.h>
20 #include <string>
21 #include "lib/config.h"
22 #include "lib/note.h"
23 #include "lib/note_list.h"
24 #include "lib/path.h"
25
26 int get_help() {
27 string out = "\nNoteless provides a simple command line interface for note "
28 "taking.\n\n"
29 "What makes this different than simply using a command line text editor is\n"
30 "there is no need to type paths or file extensions. It handles all of the\n"
31 "file management without having to change directories. It can also perform\n"
32 "search operations without having to write a long command.\n\n"
33 "[1mArguments[0m\n"
34 " cat <note> Outputs the specified note's contents verbatim.\n"
35 " new <note> Creates the specified note and opens for editing.\n"
36 " edit <note> Opens the specified note for editing.\n"
37 " find <term> Performs a case-insensitive search of all notes for the\n"
38 " given search term.\n"
39 " help Displays this help text\n"
40 " ls,list Lists all notes in note directory.\n";
41 cout << out << endl;
42 return 0;
43 }
44
45 /**
46 * Prints names of all notes
47 */
48 void list_notes( note_list list ) {
49 // List notes
50 vector<string> names = list.enum_names();
51 cout << endl;
52 for( int i = 0; i < names.size(); i++ ) {
53 cout << "* " << names[i] << endl;
54 }
55 cout << endl;
56 }
57
58 /**
59 * Searches all note contents for the specified text
60 */
61 int search_notes( note_list list, string term ) {
62 vector<string> matches = list.find( true, term );
63 for( int i = 0; i < matches.size(); i++ ) {
64 cout << matches[i] << endl;
65 }
66 if( matches.size() == 0 ) {
67 return 1;
68 }
69 return 0;
70 }
71
72 int cat_note( note_list list, string name ) {
73 vector<string> body;
74 if( list.cat_note( name, &body ) == 0 ) {
75 // If list returns true, the note exists
76 for( int i = 0; i < body.size(); i++ ) {
77 cout << body[i] << endl;
78 }
79 } else {
80 // List cat_note returned false. Note doesn't exist
81 cout << "Note " << name << " could not be found." << endl;
82 return 1;
83 }
84 return 0;
85 }
86
87 int main( int argc, char** argv ) {
88 /**
89 * Config variables definitions
90 */
91 // Default path to the note store
92 string note_path = getenv( "HOME" );
93 note_path += "/Documents/Notes";
94
95 // Default note extension
96 string note_ext = "mdown";
97
98 // A little editor detection
99 string editor;
100 if( getenv( "EDITOR" ) ) {
101 editor = getenv( "EDITOR" );
102 } else {
103 editor = "vi";
104 }
105
106 /**
107 * Config file overrides
108 */
109 string conf_path = getenv( "HOME" );
110 conf_path += "/.config/noteless.conf";
111 path pconf( conf_path );
112 config conf();
113 if( pconf.exists() ) {
114 config conf( conf_path.c_str() );
115
116 // Override where notes are to be stored
117 if( conf.isset( "path" ) ) {
118 note_path = conf.get( "path" );
119 }
120
121 // Override the extension used by the notes
122 if( conf.isset( "extension" ) ) {
123 note_ext = conf.get( "extension" );
124 }
125
126 // Override editor settings
127 if( conf.isset( "editor" ) ) {
128 editor = conf.get( "editor" );
129 }
130 }
131
132 if( argc == 1 ) {
133 cout << "\nNo command specified. Printing help text.\n" << endl;
134 return get_help();
135 }
136
137 // If the init command was passed, we want to init before checking if the
138 // note path exists, otherwise the error will display and the store will
139 // never be initialized.
140 if( string( argv[1] ) == "init" ) {
141 path p( note_path );
142 return p.create();
143 }
144
145 // Check to make sure the note path exists
146 path p( note_path );
147 if( ! p.exists() ) {
148 string out =
149 "\nThe note store path '" + p.out() + "' does not exist.\n\n"
150 "If this is your first time running noteless, please run "
151 "'[1mnoteless init[0m' to\n"
152 "create the note store here.\n\n"
153 "Otherwise, please verify the path variable in your configuration.";
154 cout << out << endl;
155 return 1;
156 }
157
158 // Create new list
159 note_list list( note_path, note_ext );
160
161 for( int i = 1; i < argc; i++ ) {
162 string arg = argv[i];
163 if( arg == "ls" || arg == "list" ) {
164 list_notes( list );
165 } else if( arg == "new" ) {
166 string name = argv[i + 1];
167 return list.create( editor, name );
168 } else if( arg == "edit" ) {
169 string name = argv[i + 1];
170 return list.edit( editor, name );
171 } else if( arg == "find" ) {
172 string term = argv[i + 1];
173 return search_notes( list, term );
174 } else if( arg == "cat" ) {
175 string name = argv[i + 1];
176 return cat_note( list, name );
177 } else if( arg == "help" ) {
178 return get_help();
179 } else if( list.find_note_id( arg ) != -1 ) {
180 // Try to open the note if it exists
181 return list.edit( editor, arg );
182 } else {
183 cout << "Error: Unknown command or note name '" << arg << "'." << endl;
184 }
185 }
186 return 0;
187 }
|