mirror of
https://github.com/tomasriveral/NoteWrapper.git
synced 2026-08-12 02:18:38 +02:00
multiple small corections
This commit is contained in:
@@ -105,6 +105,7 @@ Change `~/.config/notewrapper/config.json`. If it does not exist. On building, i
|
|||||||
- [x] Search for config.json in other directories such as ~/.config/notewrapper/ and not only this directory
|
- [x] Search for config.json in other directories such as ~/.config/notewrapper/ and not only this directory
|
||||||
- [x] Port vivify.vim to nixpkgs
|
- [x] Port vivify.vim to nixpkgs
|
||||||
- [ ] Add a way to have vaults in different directories
|
- [ ] Add a way to have vaults in different directories
|
||||||
|
- [ ] some kind of FZF search for notes
|
||||||
- [x] Actually open vivify when opening nvim
|
- [x] Actually open vivify when opening nvim
|
||||||
- [x] Write the journaling code (separate files or one big journal files)
|
- [x] Write the journaling code (separate files or one big journal files)
|
||||||
- [x] Adapt createNewNote with journals
|
- [x] Adapt createNewNote with journals
|
||||||
@@ -118,4 +119,5 @@ Change `~/.config/notewrapper/config.json`. If it does not exist. On building, i
|
|||||||
- [ ] Fixe all the small stuff marked //(TODO LATER) in the code
|
- [ ] Fixe all the small stuff marked //(TODO LATER) in the code
|
||||||
- [x] Comply with GPL-3 notice (add info about no waranty, etc.)
|
- [x] Comply with GPL-3 notice (add info about no waranty, etc.)
|
||||||
- [ ] A converter for both type of journals
|
- [ ] A converter for both type of journals
|
||||||
|
- [ ] With journals, a way to open random entry (not today's)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
"jumpToEndOfFileOnLaunch": true,
|
"jumpToEndOfFileOnLaunch": true,
|
||||||
"editor": "neovim",
|
"editor": "neovim",
|
||||||
"journalRegex": ".*journal.*",
|
"journalRegex": ".*journal.*",
|
||||||
"dateEntry": "# %a %d %m %Y",
|
"dateEntry": "# %Y %m %d %a",
|
||||||
"newLineOnOpening": true,
|
"newLineOnOpening": true,
|
||||||
"backup": {
|
"backup": {
|
||||||
"enable": false,
|
"enable": false,
|
||||||
|
|||||||
+89
-54
@@ -16,7 +16,6 @@
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int shouldDebug = 0;
|
int shouldDebug = 0;
|
||||||
int overwriteConfigPath = 0;
|
int overwriteConfigPath = 0;
|
||||||
// (TODO LATER) we really should change all the HASH_MACRO to an int that checks if it is overwritten and a char* that stores to the string
|
|
||||||
// all of the argument parsing is done after so flags overwrite config options. The only config options that can't be set in the config is the shouldDebug and specifing the path to the config
|
// all of the argument parsing is done after so flags overwrite config options. The only config options that can't be set in the config is the shouldDebug and specifing the path to the config
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--verbose") == 0) {
|
if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--verbose") == 0) {
|
||||||
@@ -62,7 +61,7 @@ int main(int argc, char *argv[]) {
|
|||||||
size_t readBytes = fread(data, 1, size, f); // 1 --> size of each item
|
size_t readBytes = fread(data, 1, size, f); // 1 --> size of each item
|
||||||
|
|
||||||
if (readBytes!=size) {free(data);fclose(f);}
|
if (readBytes!=size) {free(data);fclose(f);}
|
||||||
error(readBytes!=size, "program", "Failed to read config file (&zu bytes read, expected %ld)", readBytes, size);
|
error(readBytes!=size, "program", "Failed to read config file (%s) (%zu bytes read, expected %ld)", configPath, readBytes, size);
|
||||||
data[size] = '\0';
|
data[size] = '\0';
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
@@ -75,18 +74,18 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
cJSON *dirJson = cJSON_GetObjectItem(json, "directory");
|
cJSON *dirJson = cJSON_GetObjectItem(json, "directory");
|
||||||
char *notesDirectoryString = malloc(PATH_MAX);
|
char *notesDirectoryString = malloc(PATH_MAX);
|
||||||
if (dirJson && cJSON_IsString(dirJson) && dirJson->valuestring != NULL) {
|
if (dirJson && cJSON_IsString(dirJson) && cJSON_GetStringValue(dirJson) != NULL) { // we replaced all the ->valuestr and ->valueint to cJSON_GetStringValue() and cJSON_GetNumberValue()
|
||||||
char *rawPath = dirJson->valuestring;
|
char *rawPath = cJSON_GetStringValue(dirJson);
|
||||||
if (rawPath[0] == '~') { // expands ~ in the path
|
if (rawPath[0] == '~') { // expands ~ in the path
|
||||||
snprintf(notesDirectoryString, PATH_MAX, "%s/%s", homedir, rawPath+1);
|
snprintf(notesDirectoryString, PATH_MAX, "%s/%s", homedir, rawPath+1);
|
||||||
} else {
|
} else {
|
||||||
notesDirectoryString = rawPath;
|
notesDirectoryString = rawPath;
|
||||||
}
|
}
|
||||||
debug("config.json's vault's directory is %s", notesDirectoryString);
|
debug("In %s, \"directory\" was set to %s.", configPath, notesDirectoryString);
|
||||||
} else {
|
} else {
|
||||||
// default vault path if it is not set in the config
|
// default vault path if it is not set in the config
|
||||||
snprintf(notesDirectoryString, PATH_MAX, "%s/Documents/Notes/", homedir);
|
snprintf(notesDirectoryString, PATH_MAX, "%s/Documents/Notes/", homedir);
|
||||||
debug("the vault's directory is not set in the config file. Using default %s", notesDirectoryString);
|
debug("In %s, \"directory\" wasn't set or we encountered a abnormal type. Defaulting to %s.", configPath, notesDirectoryString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch the render and jumpToEnfOfFileOnLaunch bools
|
// fetch the render and jumpToEnfOfFileOnLaunch bools
|
||||||
@@ -94,43 +93,58 @@ int main(int argc, char *argv[]) {
|
|||||||
cJSON *shouldRenderJSON = cJSON_GetObjectItem(json, "render");
|
cJSON *shouldRenderJSON = cJSON_GetObjectItem(json, "render");
|
||||||
if (shouldRenderJSON && cJSON_IsBool(shouldRenderJSON)) {
|
if (shouldRenderJSON && cJSON_IsBool(shouldRenderJSON)) {
|
||||||
shouldRender = cJSON_IsTrue(shouldRenderJSON) ? 1 : 0;
|
shouldRender = cJSON_IsTrue(shouldRenderJSON) ? 1 : 0;
|
||||||
} else {debug("config.json did not contained a correct \"render\" value. The default is 1.");}
|
debug("In %s, \"render\" was set to %d.", configPath, shouldRender);
|
||||||
|
} else {
|
||||||
|
debug("In %s, \"render\" wasn't set. Defaulting to true.", configPath);
|
||||||
|
}
|
||||||
|
|
||||||
int shouldJumpToEnd = 1;
|
int shouldJumpToEnd = 1;
|
||||||
cJSON *shouldJumpToEndJSON = cJSON_GetObjectItem(json, "jumpToEndOfFileOnLaunch");
|
cJSON *shouldJumpToEndJSON = cJSON_GetObjectItem(json, "jumpToEndOfFileOnLaunch");
|
||||||
if (shouldJumpToEndJSON && cJSON_IsBool(shouldJumpToEndJSON)) {
|
if (shouldJumpToEndJSON && cJSON_IsBool(shouldJumpToEndJSON)) {
|
||||||
shouldJumpToEnd = cJSON_IsTrue(shouldJumpToEndJSON) ? 1 : 0;
|
shouldJumpToEnd = cJSON_IsTrue(shouldJumpToEndJSON) ? 1 : 0;
|
||||||
} else {debug("config.json did not contained a correct \"jumpToEndOfFileOnLaunch\" value. The default is 1.");}
|
debug("In %s, \"jumpToEndOfFileOnLaunch\" was set to %d.", configPath, shouldJumpToEnd);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
debug("In %s, \"jumpToEndOfFileOnLaunch\" wasn't set or we encountered a abnormal type. Defaulting to true.", configPath);
|
||||||
|
}
|
||||||
|
|
||||||
char *editorToOpen = "neovim"; // default
|
char *editorToOpen = "neovim"; // default
|
||||||
cJSON *editorToOpenJSON = cJSON_GetObjectItem(json, "editor");
|
cJSON *editorToOpenJSON = cJSON_GetObjectItem(json, "editor");
|
||||||
if (editorToOpenJSON && cJSON_IsString(editorToOpenJSON)) {
|
if (editorToOpenJSON && cJSON_IsString(editorToOpenJSON)) {
|
||||||
debug("Editor in config.json is %s", editorToOpenJSON->valuestring);
|
editorToOpen = strdup(cJSON_GetStringValue(editorToOpenJSON)); // we must strdup and not just = as we will free all the json after (before parsing args)
|
||||||
error(!isStringInArray(editorToOpenJSON->valuestring, supportedEditor, numEditors), "user", "%s (fetched from config.json) is not a supported editor.", editorToOpenJSON->valuestring);
|
debug("In %s, \"editor\" was set to %s.", configPath, editorToOpen);
|
||||||
editorToOpen = strdup(editorToOpenJSON->valuestring); // we must strdup and not just = as we will free all the json after (before parsing args)
|
error(!isStringInArray(editorToOpen, supportedEditor, numEditors), "user", "%s (fetched from config.json) is not a supported editor.", editorToOpen);
|
||||||
} else {debug("config.json did not contained a correct \"editor\" value. The default is neovim.");}
|
} else {
|
||||||
|
debug("In %s, \"editor\" wasn't set or we encountered a abnormal type. Defaulting to %s.", configPath, editorToOpen);
|
||||||
|
}
|
||||||
|
|
||||||
cJSON *journalRegexJSON = cJSON_GetObjectItem(json, "journalRegex");
|
cJSON *journalRegexJSON = cJSON_GetObjectItem(json, "journalRegex");
|
||||||
char *journalRegex = ".*journal.*"; // default regex pattern for the journal
|
char *journalRegex = ".*journal.*"; // default regex pattern for the journal
|
||||||
if (journalRegexJSON && cJSON_IsString(journalRegexJSON)) {
|
if (journalRegexJSON && cJSON_IsString(journalRegexJSON)) {
|
||||||
debug("The regex in config.json is %s", journalRegexJSON->valuestring);
|
journalRegex = strdup(cJSON_GetStringValue(journalRegexJSON));
|
||||||
journalRegex = strdup(journalRegexJSON->valuestring);
|
debug("In %s, \"journalRegex\" was set to %s.", configPath, journalRegex);
|
||||||
} else {debug("config.json did not contained a correct \"journalRegex\" value. The default is .*journal.*");}
|
} else {
|
||||||
|
debug("In %s, \"journalRegex\" wasn't set or we encountered a abnormal type. Defaulting to %s.", configPath, journalRegex);
|
||||||
|
}
|
||||||
|
|
||||||
char *timeFormat = "# \%a \%d \%m \%Y";// default
|
char *timeFormat = "# \%Y \%m \%d \%a";// default
|
||||||
cJSON *timeFormatJSON = cJSON_GetObjectItem(json, "dateEntry");
|
cJSON *timeFormatJSON = cJSON_GetObjectItem(json, "dateEntry");
|
||||||
if (timeFormatJSON && cJSON_IsString(timeFormatJSON)) {
|
if (timeFormatJSON && cJSON_IsString(timeFormatJSON)) {
|
||||||
debug("The time format in config.json is %s", timeFormatJSON->valuestring);
|
timeFormat = strdup(cJSON_GetStringValue(timeFormatJSON));
|
||||||
timeFormat = strdup(timeFormatJSON->valuestring);
|
debug("In %s, \"dateEntry\" was set to %s.", configPath, timeFormat);
|
||||||
} else {debug("config.json did not contained a correct \"dateEntry\" value. The default is \"# \%a \%d \%m \%Y\".");}
|
} else {
|
||||||
|
debug("In %s, \"dateEntry\" wasn't set or we encountered a abnormal type. Defaulting to %s.", configPath, timeFormat);
|
||||||
|
}
|
||||||
int newLineOnOpening = 1;
|
int newLineOnOpening = 1;
|
||||||
cJSON *newLineOnOpeningJSON = cJSON_GetObjectItem(json, "newLineOnOpening");
|
cJSON *newLineOnOpeningJSON = cJSON_GetObjectItem(json, "newLineOnOpening");
|
||||||
if (newLineOnOpeningJSON && cJSON_IsBool(newLineOnOpeningJSON)) {
|
if (newLineOnOpeningJSON && cJSON_IsBool(newLineOnOpeningJSON)) {
|
||||||
debug("The value for newLineOnOpening in config.json is %d", cJSON_IsTrue(newLineOnOpeningJSON));
|
debug("The value for newLineOnOpening in config.json is %d", cJSON_IsTrue(newLineOnOpeningJSON));
|
||||||
newLineOnOpening = cJSON_IsTrue(newLineOnOpeningJSON) ? 1 : 0;
|
|
||||||
} else {debug("config.json did not contained a correct \"newLineOnOpening\" value. The default is true.");}
|
|
||||||
|
|
||||||
|
newLineOnOpening = cJSON_IsTrue(newLineOnOpeningJSON) ? 1 : 0;
|
||||||
|
debug("In %s, \"newLineOnOpening\" was set to %d.", configPath, newLineOnOpening);
|
||||||
|
} else {
|
||||||
|
debug("In %s, \"newLineOnOpening\" wasn't set or we encountered a abnormal type. Defaulting to true.", configPath);
|
||||||
|
}
|
||||||
|
|
||||||
int doesBackup = 0;
|
int doesBackup = 0;
|
||||||
int interval = 0; // this is an int. But some times it will be inputed a string. We must translate it.
|
int interval = 0; // this is an int. But some times it will be inputed a string. We must translate it.
|
||||||
@@ -143,34 +157,37 @@ int main(int argc, char *argv[]) {
|
|||||||
debug("doesBackup is set to %d", doesBackup);
|
debug("doesBackup is set to %d", doesBackup);
|
||||||
cJSON *pathToBackupJSON = cJSON_GetObjectItem(backupJSON, "directory");
|
cJSON *pathToBackupJSON = cJSON_GetObjectItem(backupJSON, "directory");
|
||||||
if (pathToBackupJSON && cJSON_IsString(pathToBackupJSON)) {
|
if (pathToBackupJSON && cJSON_IsString(pathToBackupJSON)) {
|
||||||
if (pathToBackupJSON->valuestring[0] == '~') { // expands ~
|
char *temp = cJSON_GetStringValue(pathToBackupJSON); // we name it temp. As we can't directly set pathToBackup because snprintf doesn't like when a pointer is both an arg and the destination // temp should be freed when free(json), because cJSON_GetStringValue returns a pointer.
|
||||||
char *temp = pathToBackupJSON->valuestring;
|
if (temp[0] == '~') { // expands ~
|
||||||
temp++;
|
temp++; // we shift by one to remove ~
|
||||||
snprintf(pathToBackup, PATH_MAX, "%s/%s", homedir, temp);
|
snprintf(pathToBackup, PATH_MAX, "%s/%s", homedir, temp);
|
||||||
debug("~ was expanded to %s\nThe backup path is %s", homedir, pathToBackup);
|
debug("~ was expanded to %s\nThe backup path is %s", homedir, pathToBackup);
|
||||||
} else {
|
} else {
|
||||||
pathToBackup = strndup(pathToBackupJSON->valuestring, PATH_MAX);
|
pathToBackup = strndup(temp, PATH_MAX); // temp will be freed later so strndup
|
||||||
debug("Directory for backup is set to %s in config.json", pathToBackup); // (TODO LATER) Maybe when in debug message when we say config.json get the actual config name.
|
debug("Directory for backup is set to %s in config.json", pathToBackup);
|
||||||
}
|
}
|
||||||
} else {error(1, "user", "config.json did not contained a directory inside the backup section or the value is from an unexpected type");}
|
} else {error(1, "user", "config.json did not contained a directory inside the backup section or the value is from an unexpected type");}
|
||||||
cJSON *intervalJSON = cJSON_GetObjectItem(backupJSON, "interval");
|
cJSON *intervalJSON = cJSON_GetObjectItem(backupJSON, "interval");
|
||||||
if (intervalJSON && cJSON_IsString(intervalJSON)) {
|
if (intervalJSON && cJSON_IsString(intervalJSON)) {
|
||||||
if (strcmp(intervalJSON->valuestring, "daily") == 0) {
|
char *temp = cJSON_GetStringValue(intervalJSON); // se comment higher. temp will be freed when calling free(json)
|
||||||
|
if (strcmp(temp, "daily") == 0) {
|
||||||
interval = DAILY;
|
interval = DAILY;
|
||||||
debug("interval in config.json is set to \"daily\" which is %d", DAILY);
|
debug("interval in config.json is set to \"daily\" which is %d", DAILY);
|
||||||
} else if (strcmp(intervalJSON->valuestring, "weekly") == 0) {
|
} else if (strcmp(temp, "weekly") == 0) {
|
||||||
interval = WEEKLY;
|
interval = WEEKLY;
|
||||||
debug("interval in config.json is set to \"weekly\" which is %d", WEEKLY);
|
debug("interval in config.json is set to \"weekly\" which is %d", WEEKLY);
|
||||||
} else if (strcmp(intervalJSON->valuestring, "monthly") == 0) {
|
} else if (strcmp(temp, "monthly") == 0) {
|
||||||
interval = MONTHLY;
|
interval = MONTHLY;
|
||||||
debug("interval in config.json is set to \"monthly\" which is %d", MONTHLY);
|
debug("interval in config.json is set to \"monthly\" which is %d", MONTHLY);
|
||||||
} else {error(1, "user", "Unexpected string %s for entry \"interval\" in config.json. You must put an int (number of seconds) or \"daily\" or \"weekly\" or \"monthly\".", intervalJSON->valuestring);}
|
} else {error(1, "user", "Unexpected string %s for entry \"interval\" in config.json. You must put an int (number of seconds) or \"daily\" or \"weekly\" or \"monthly\".", intervalJSON->valuestring);}
|
||||||
} else if (intervalJSON && cJSON_IsNumber(intervalJSON)) {
|
} else if (intervalJSON && cJSON_IsNumber(intervalJSON)) {
|
||||||
interval = intervalJSON->valueint; // (TODO LATER) "writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead". we should pass all of these JSON->value... to the designed functions
|
interval = (int)cJSON_GetNumberValue(intervalJSON);
|
||||||
debug("interval in config.json is set to %d", interval);
|
debug("interval in config.json is set to %d", interval);
|
||||||
} else {error(1, "user", "config.json did not contained an interval value inside the backup section or the value is from an unexpected type");}
|
} else {error(1, "user", "config.json did not contained an interval value inside the backup section or the value is from an unexpected type");}
|
||||||
} else{error(1, "user", "config.json did not contained a enable value inside the backup section or the value is from an unexpected type");}
|
} else{error(1, "user", "config.json did not contained a enable value inside the backup section or the value is from an unexpected type");}
|
||||||
} else {debug("config.json did not contained a correct \"backup\" section. The default is {\"enable\": false}");}
|
} else {
|
||||||
|
debug("In %s, \"backup\" wasn't set or we encountered a abnormal type. Defaulting to {\"enable\": false}.", configPath);
|
||||||
|
}
|
||||||
//cleans up
|
//cleans up
|
||||||
cJSON_Delete(json);
|
cJSON_Delete(json);
|
||||||
free(data);
|
free(data);
|
||||||
@@ -182,8 +199,11 @@ int main(int argc, char *argv[]) {
|
|||||||
// (TODO LATER) maybe add a way to combine flags (such which rm -fr?)
|
// (TODO LATER) maybe add a way to combine flags (such which rm -fr?)
|
||||||
// (TODO LATER) add a version flag
|
// (TODO LATER) add a version flag
|
||||||
debug("Parsing the attribute flags.\n This flags might overwrite the options in the config file.");
|
debug("Parsing the attribute flags.\n This flags might overwrite the options in the config file.");
|
||||||
char *bypassVaultSelection = HASH_MACRO; // (TODO LATER) find a better idea. If later it detects other string than that 256 string. It will bypass the selection
|
// thoses bypasses are used if some specific flags are passed as args. This allows to bypass the TUI selectors
|
||||||
char *bypassNoteSelection = HASH_MACRO;
|
int bypassSelectionVault = 0;
|
||||||
|
char *bypassSelectionVaultValue = NULL;
|
||||||
|
int bypassSelectionNote = 0;
|
||||||
|
char *bypassSelectionNoteValue = NULL;
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--directory") == 0) {
|
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--directory") == 0) {
|
||||||
error(i+1==argc, "user", "Missing argument. Please use -d <path/to/directory> or --directory <path/to/directory>.");
|
error(i+1==argc, "user", "Missing argument. Please use -d <path/to/directory> or --directory <path/to/directory>.");
|
||||||
@@ -216,9 +236,10 @@ int main(int argc, char *argv[]) {
|
|||||||
} else if (strcmp(argv[i], "-J") == 0 || strcmp(argv[i], "--no-jump") == 0) {
|
} else if (strcmp(argv[i], "-J") == 0 || strcmp(argv[i], "--no-jump") == 0) {
|
||||||
debug("-j or --jump set jumpToEnfOfFileOnLaunch to false");
|
debug("-j or --jump set jumpToEnfOfFileOnLaunch to false");
|
||||||
shouldJumpToEnd = 0;
|
shouldJumpToEnd = 0;
|
||||||
} else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--note") == 0) { // (TODO LATER) Broken if we put the -v flag after the -n flag
|
} else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--note") == 0) {// if -n is set and not -v -> problems. We verify this case at the end of the parsing.
|
||||||
error(i+1==argc, "user", "Missing argument. Please user -n <note's name> or --note <note's name>.");
|
error(i+1==argc, "user", "Missing argument. Please user -n <note's name> or --note <note's name>.");
|
||||||
bypassNoteSelection = argv[i+1];
|
bypassSelectionNote = 1;
|
||||||
|
bypassSelectionNoteValue = argv[i+1]; // if somehow we pass a flag like -v it will create a new note with the name. So no need to worry if something is invalid. Just verifing that there is an arg after is good.
|
||||||
} else if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--render") == 0) {
|
} else if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--render") == 0) {
|
||||||
debug("-r or --render set shouldRender to true");
|
debug("-r or --render set shouldRender to true");
|
||||||
shouldRender = 1;
|
shouldRender = 1;
|
||||||
@@ -227,7 +248,8 @@ int main(int argc, char *argv[]) {
|
|||||||
debug("-r or --render set shouldRender to false");
|
debug("-r or --render set shouldRender to false");
|
||||||
} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--vault") == 0) {
|
} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--vault") == 0) {
|
||||||
error(i+1==argc, "user", "Missing argument. Pleaase use -v <vault's name> or --vault <vault's name>");
|
error(i+1==argc, "user", "Missing argument. Pleaase use -v <vault's name> or --vault <vault's name>");
|
||||||
bypassVaultSelection = argv[i+1]; // (TODO LATER) Add security checks pass ti strndup. and if vault don't exist create one. SEE (TODO LATER) where bypassVaultSelection is checked (TODO LATER) Add check if vault exist
|
bypassSelectionVault = 1;
|
||||||
|
bypassSelectionVaultValue = argv[i+1]; // (TODO LATER) Add security checks pass ti strndup. and if vault don't exist create one. SEE (TODO LATER) where bypassVaultSelection is checked (TODO LATER) Add check if vault exist
|
||||||
} else if (strcmp(argv[i], "--version") == 0) {
|
} else if (strcmp(argv[i], "--version") == 0) {
|
||||||
printf("There is still no released version\n\n Copyright (C) 2026 Tomás Rivera\n License GPLv3: GNU GPL version 3 <https://gnu.org/licenses/gpl.html>.\n This is free software: you are free to change and redistribute it.\n There is NO WARRANTY, to the extent permitted by law.\n\n Written by Tomás Rivera.\n");
|
printf("There is still no released version\n\n Copyright (C) 2026 Tomás Rivera\n License GPLv3: GNU GPL version 3 <https://gnu.org/licenses/gpl.html>.\n This is free software: you are free to change and redistribute it.\n There is NO WARRANTY, to the extent permitted by law.\n\n Written by Tomás Rivera.\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -235,8 +257,8 @@ int main(int argc, char *argv[]) {
|
|||||||
error(1, "user", "unexpected argument \"%s\" found\nFor more information, try \"--help\".", argv[i]);
|
error(1, "user", "unexpected argument \"%s\" found\nFor more information, try \"--help\".", argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if -n or --note is set but note -v or --vaults
|
// if -n or --note is set but not -v or --vaults it gives an error
|
||||||
error(strcmp(bypassVaultSelection, HASH_MACRO) == 0 && strcmp(bypassNoteSelection, HASH_MACRO) != 0, "user", "If you want to specify the note, you must also specify the vault with -v <vault's name> or --vault <vault's name>.");
|
error(!bypassSelectionVault && bypassSelectionNote, "user", "If you want to specify the note, you must also specify the vault with -v <vault's name> or --vault <vault's name>.");
|
||||||
|
|
||||||
|
|
||||||
error(!doesEditorExist(editorToOpen, shouldDebug), "user", "%s is either not in your path or not installed.", editorToOpen);
|
error(!doesEditorExist(editorToOpen, shouldDebug), "user", "%s is either not in your path or not installed.", editorToOpen);
|
||||||
@@ -249,8 +271,25 @@ int main(int argc, char *argv[]) {
|
|||||||
int shouldExit = 0;
|
int shouldExit = 0;
|
||||||
while(!shouldExit) {
|
while(!shouldExit) {
|
||||||
// this loop is the vault selector
|
// this loop is the vault selector
|
||||||
|
// select a vault
|
||||||
|
char *vaultSelected = NULL;
|
||||||
|
|
||||||
size_t vaultsCount = 0;
|
size_t vaultsCount = 0;
|
||||||
char **vaultsArray = getVaultsFromDirectory(notesDirectoryString, &vaultsCount, shouldDebug);
|
char **vaultsArray = getVaultsFromDirectory(notesDirectoryString, &vaultsCount, shouldDebug);
|
||||||
|
|
||||||
|
// bypass if -v or --vault is set
|
||||||
|
if (bypassSelectionVault) {
|
||||||
|
// bypasses the vault selection if the flag is -v. If the vault doesn't exist, just create a new one
|
||||||
|
vaultSelected = bypassSelectionVaultValue;
|
||||||
|
debug("bypassing vault selection");
|
||||||
|
if (!isStringInArray(bypassSelectionVaultValue, (const char **)vaultsArray, vaultsCount)) { // we pass just vaultsCount and not vaultsCount + extraOptions to avoid matching with the extraOptions.
|
||||||
|
debug("[BYPASS] %s did not exist. Creating a new vault");
|
||||||
|
goto vault_creation;
|
||||||
|
} else {
|
||||||
|
goto note_selection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qsort(vaultsArray, vaultsCount, sizeof(const char *), compareString); // sorts the vaults alphabetically
|
qsort(vaultsArray, vaultsCount, sizeof(const char *), compareString); // sorts the vaults alphabetically
|
||||||
debug("Available vaults");
|
debug("Available vaults");
|
||||||
if (shouldDebug) {
|
if (shouldDebug) {
|
||||||
@@ -266,14 +305,8 @@ int main(int argc, char *argv[]) {
|
|||||||
vaultsArray[vaultsCount] = "Create a new vault"; // some more options that are not vaults
|
vaultsArray[vaultsCount] = "Create a new vault"; // some more options that are not vaults
|
||||||
vaultsArray[vaultsCount+1] = "Settings";
|
vaultsArray[vaultsCount+1] = "Settings";
|
||||||
vaultsArray[vaultsCount+2] = "Quit (Ctrl+C)";
|
vaultsArray[vaultsCount+2] = "Quit (Ctrl+C)";
|
||||||
// select a vault
|
|
||||||
char *vaultSelected = NULL;
|
|
||||||
|
|
||||||
if (strcmp(bypassVaultSelection, HASH_MACRO) != 0) {
|
|
||||||
// bypasses the vault selection if the flag is -v (TODO LATER) use isStringInArray() to check if the vault really exists
|
|
||||||
vaultSelected = bypassVaultSelection;
|
|
||||||
goto note_selection;
|
|
||||||
}
|
|
||||||
vaultSelected = ncursesSelect(vaultsArray, "Select vault to open (Use arrows or WASD, Enter to select):", vaultsCount, extraOptions, " ", "Or select an option below", "", shouldDebug);
|
vaultSelected = ncursesSelect(vaultsArray, "Select vault to open (Use arrows or WASD, Enter to select):", vaultsCount, extraOptions, " ", "Or select an option below", "", shouldDebug);
|
||||||
|
|
||||||
// now that we won't use vaultsArray in this iteration of the loop, we should free it and all its elements. (As this is memory in the heap and not the stack and thus is our responsability to manage)
|
// now that we won't use vaultsArray in this iteration of the loop, we should free it and all its elements. (As this is memory in the heap and not the stack and thus is our responsability to manage)
|
||||||
@@ -287,7 +320,7 @@ int main(int argc, char *argv[]) {
|
|||||||
debug("Selected vault: %s", vaultSelected);
|
debug("Selected vault: %s", vaultSelected);
|
||||||
if (strcmp(vaultSelected,"Create a new vault") != 0 && strcmp(vaultSelected,"Settings") != 0 && strcmp(vaultSelected,"Quit (Ctrl+C)") != 0) {
|
if (strcmp(vaultSelected,"Create a new vault") != 0 && strcmp(vaultSelected,"Settings") != 0 && strcmp(vaultSelected,"Quit (Ctrl+C)") != 0) {
|
||||||
note_selection:
|
note_selection:
|
||||||
bypassVaultSelection = HASH_MACRO; // we must reset bypassVaultSelection to not get stuck in a infinite loop of bypassing
|
bypassSelectionVault = 0; // we must reset bypassSelectionVault to not get stuck in a infinite loop of bypassing
|
||||||
int shouldChangeVault = 0;
|
int shouldChangeVault = 0;
|
||||||
while (!shouldExit && !shouldChangeVault) {
|
while (!shouldExit && !shouldChangeVault) {
|
||||||
// this loop is the note selector
|
// this loop is the note selector
|
||||||
@@ -319,10 +352,11 @@ note_selection:
|
|||||||
filesArray[filesCount+2] = "Delete vault";
|
filesArray[filesCount+2] = "Delete vault";
|
||||||
filesArray[filesCount+3] = "Quit (Ctrl+C)";
|
filesArray[filesCount+3] = "Quit (Ctrl+C)";
|
||||||
char *noteSelected;
|
char *noteSelected;
|
||||||
if (strcmp(bypassNoteSelection, HASH_MACRO) != 0) {
|
// if we set to bypass the note selector
|
||||||
|
if (bypassSelectionNote) {
|
||||||
// (TODO LATER) Add shouldDebug info
|
// (TODO LATER) Add shouldDebug info
|
||||||
noteSelected = bypassNoteSelection;
|
noteSelected = bypassSelectionNoteValue;
|
||||||
if (isStringInArray(noteSelected, (const char **)filesArray, filesCount + extraNotesOptions)) {// (TODO LATER) Handle the case where the note name is one of the extraOptions
|
if (isStringInArray(noteSelected, (const char **)filesArray, filesCount)) {// we just give filesCount and not filesCount + extraOptions to avoid matching with an extra options.
|
||||||
goto open_note;
|
goto open_note;
|
||||||
} else { // if the specified note doesn't exist. We creat it
|
} else { // if the specified note doesn't exist. We creat it
|
||||||
goto note_creation;
|
goto note_creation;
|
||||||
@@ -339,7 +373,7 @@ note_selection:
|
|||||||
debug("Selected note: %s", noteSelected);
|
debug("Selected note: %s", noteSelected);
|
||||||
if (strcmp(noteSelected, "Create new note") != 0 && strcmp(noteSelected,"Back to vault selection") != 0 && strcmp(noteSelected, "Delete vault") != 0 && strcmp(noteSelected,"Quit (Ctrl+C)") != 0) {
|
if (strcmp(noteSelected, "Create new note") != 0 && strcmp(noteSelected,"Back to vault selection") != 0 && strcmp(noteSelected, "Delete vault") != 0 && strcmp(noteSelected,"Quit (Ctrl+C)") != 0) {
|
||||||
open_note:
|
open_note:
|
||||||
bypassNoteSelection = HASH_MACRO; // we must reset bypassNoteSelection to avoid getting into an infinite loop of bypassing the note selection
|
bypassSelectionNote = 0; // we must reset bypassSelectionNote to avoid getting into an infinite loop of bypassing the note selection
|
||||||
char *fullPath = malloc(PATH_MAX); // (TODO LATER) Find a more appropriate and descriptive name for the variable
|
char *fullPath = malloc(PATH_MAX); // (TODO LATER) Find a more appropriate and descriptive name for the variable
|
||||||
sprintf(fullPath, "%s/%s/%s", notesDirectoryString, vaultSelected, noteSelected); // (TODO LATER) change all sprintf to snprintf which checks for buffer size
|
sprintf(fullPath, "%s/%s/%s", notesDirectoryString, vaultSelected, noteSelected); // (TODO LATER) change all sprintf to snprintf which checks for buffer size
|
||||||
// if it is a journal we must update it before
|
// if it is a journal we must update it before
|
||||||
@@ -358,7 +392,7 @@ open_note:
|
|||||||
free(fullPath);
|
free(fullPath);
|
||||||
} else if (strcmp(noteSelected,"Create new note") == 0) {
|
} else if (strcmp(noteSelected,"Create new note") == 0) {
|
||||||
note_creation:
|
note_creation:
|
||||||
noteSelected = createNewNote(notesDirectoryString, vaultSelected, bypassNoteSelection, journalRegex, shouldDebug);
|
noteSelected = createNewNote(notesDirectoryString, vaultSelected, bypassSelectionNote, bypassSelectionNoteValue, journalRegex, shouldDebug);
|
||||||
// we can just go back to open_note
|
// we can just go back to open_note
|
||||||
goto open_note;
|
goto open_note;
|
||||||
} else if (strcmp(noteSelected,"Back to vault selection") == 0) {
|
} else if (strcmp(noteSelected,"Back to vault selection") == 0) {
|
||||||
@@ -382,9 +416,10 @@ note_creation:
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (strcmp(vaultSelected,"Create a new vault") == 0) {
|
} else if (strcmp(vaultSelected,"Create a new vault") == 0) {
|
||||||
createNewVault(notesDirectoryString, shouldDebug);
|
vault_creation:
|
||||||
|
createNewVault(notesDirectoryString, bypassSelectionVault, bypassSelectionVaultValue, shouldDebug);
|
||||||
|
bypassSelectionVault = 0; // we need to reset bypassSelectionVault to avoid getting into an infinite loop of bypassing
|
||||||
} else if (strcmp(vaultSelected,"Settings") == 0) {
|
} else if (strcmp(vaultSelected,"Settings") == 0) {
|
||||||
// (TODO LATER) add a way to modify the path to config.json
|
|
||||||
openEditor(configPath, editorToOpen, 0, 0, shouldDebug); // as this is not a md file we set render and jumptoEnfOfFile to 0
|
openEditor(configPath, editorToOpen, 0, 0, shouldDebug); // as this is not a md file we set render and jumptoEnfOfFile to 0
|
||||||
} else if (strcmp(vaultSelected,"Quit (Ctrl+C)") == 0) {
|
} else if (strcmp(vaultSelected,"Quit (Ctrl+C)") == 0) {
|
||||||
debug("The program was exited");
|
debug("The program was exited");
|
||||||
|
|||||||
@@ -1,33 +1,39 @@
|
|||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void createNewVault(char *dirToVault, int shouldDebug) {
|
void createNewVault(char *dirToVault, int bypass, char *bypassvalue, int shouldDebug) {
|
||||||
// (TODO LATER) warn if it matches the regex for the journal
|
// (TODO LATER) warn if it matches the regex for the journal
|
||||||
//(TODO LATER) add a way to go back to vault selection
|
//(TODO LATER) add a way to go back to vault selection
|
||||||
int duplicateWarning = 0; // set to 1 later if the vault you tried to create already existed
|
int duplicateWarning = 0; // set to 1 later if the vault you tried to create already existed
|
||||||
input_screen:
|
input_screen:
|
||||||
char vaultName[256];
|
char *vaultName = malloc(PATH_MAX);
|
||||||
initscr();
|
if (!bypass) { // if won't bypass (if -v or --vault weren't set)
|
||||||
echo();
|
initscr();
|
||||||
keypad(stdscr, FALSE);
|
echo();
|
||||||
// color code from https://stackoverflow.com/a/73396575
|
keypad(stdscr, FALSE);
|
||||||
start_color();
|
// color code from https://stackoverflow.com/a/73396575
|
||||||
clear();
|
start_color();
|
||||||
use_default_colors();
|
clear();
|
||||||
init_pair(1, COLOR_WHITE, -1); // -1 is blank
|
use_default_colors();
|
||||||
init_pair(2, COLOR_RED, -1);
|
init_pair(1, COLOR_WHITE, -1); // -1 is blank
|
||||||
attron(COLOR_PAIR(1));
|
init_pair(2, COLOR_RED, -1);
|
||||||
printw("Enter the name of the new vault: ");
|
attron(COLOR_PAIR(1));
|
||||||
mvprintw(3, 0, "Unsafe characters such as \\ and / will be replaced by _");
|
printw("Enter the name of the new vault: ");
|
||||||
attroff(COLOR_PAIR(1));
|
mvprintw(3, 0, "Unsafe characters such as \\ and / will be replaced by _");
|
||||||
if (duplicateWarning) {
|
attroff(COLOR_PAIR(1));
|
||||||
attron(COLOR_PAIR(2));
|
if (duplicateWarning) {
|
||||||
mvprintw(4, 0, "A vault with this name already exists. Please input another name");
|
attron(COLOR_PAIR(2));
|
||||||
attroff(COLOR_PAIR(2));
|
mvprintw(4, 0, "A vault with this name already exists. Please input another name");
|
||||||
|
attroff(COLOR_PAIR(2));
|
||||||
|
}
|
||||||
|
move(1, 1); // replace cursor
|
||||||
|
wgetnstr(stdscr, vaultName, sizeof(vaultName)-1);
|
||||||
|
refresh();
|
||||||
|
endwin();
|
||||||
|
} else {
|
||||||
|
strncpy(vaultName, bypassvalue, PATH_MAX -2); // -2 (and later -1) because indexing
|
||||||
|
vaultName[PATH_MAX-1] = '\0'; // (TODO LATER) if bypassvalue << PATH_MAX, we loose a lot of space. maybe check strlen(bypassvalue) and append there a \0
|
||||||
}
|
}
|
||||||
move(1, 1); // replace cursor
|
|
||||||
wgetnstr(stdscr, vaultName, sizeof(vaultName)-1);
|
|
||||||
refresh();
|
|
||||||
endwin();
|
|
||||||
error(strcmp(vaultName, "") == 0, "user", "vaultName is empty"); // (TODO LATER) replace that with a warning
|
error(strcmp(vaultName, "") == 0, "user", "vaultName is empty"); // (TODO LATER) replace that with a warning
|
||||||
debug("Inputed vaultName=%s", vaultName);
|
debug("Inputed vaultName=%s", vaultName);
|
||||||
sanitize(vaultName);
|
sanitize(vaultName);
|
||||||
@@ -43,15 +49,16 @@ input_screen:
|
|||||||
duplicateWarning = 1;
|
duplicateWarning = 1;
|
||||||
goto input_screen;
|
goto input_screen;
|
||||||
}
|
}
|
||||||
|
free(vaultName);
|
||||||
|
// (TODO LATER) after creating we should automatically select this vault
|
||||||
}
|
}
|
||||||
|
|
||||||
char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, char *bypass, char *journalRegex, int shouldDebug) {
|
char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, int bypass, char *bypassvalue, char *journalRegex, int shouldDebug) {
|
||||||
// (TODO LATER) Add code to create journal
|
// (TODO LATER) Add code to create journal
|
||||||
// (TODO LATER) Add check. If the user creates a note with a name that already exists. it erases the old one
|
// (TODO LATER) Add check. If the user creates a note with a name that already exists. it erases the old one
|
||||||
// input from user for the name
|
// input from user for the name
|
||||||
char *fileName = malloc(BUFFER_SIZE);
|
char *fileName = malloc(BUFFER_SIZE);
|
||||||
if (strcmp(bypass, HASH_MACRO) == 0) {
|
if (!bypass) { // if we don't bypass. (if -n or --note weren't set.)
|
||||||
initscr();
|
initscr();
|
||||||
echo();
|
echo();
|
||||||
keypad(stdscr, FALSE);
|
keypad(stdscr, FALSE);
|
||||||
@@ -63,8 +70,8 @@ char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, char *bypass,
|
|||||||
wgetnstr(stdscr, fileName, BUFFER_SIZE-4); //limits the buffer to prevent overflow (-4 to account indexing and from ".md" in case we need to add it later)
|
wgetnstr(stdscr, fileName, BUFFER_SIZE-4); //limits the buffer to prevent overflow (-4 to account indexing and from ".md" in case we need to add it later)
|
||||||
refresh();
|
refresh();
|
||||||
endwin();
|
endwin();
|
||||||
} else { // bypasses user input if we bypass is different than HASH_MACRO
|
} else { // bypasses user input if we bypass is set to 1
|
||||||
strncpy(fileName, bypass, BUFFER_SIZE-1); // (TODO LATER) Maybe add a warning if string is too big. It gets truncated
|
strncpy(fileName, bypassvalue, BUFFER_SIZE-1); // (TODO LATER) Maybe add a warning if string is too big. It gets truncated
|
||||||
fileName[BUFFER_SIZE-1] = '\0';
|
fileName[BUFFER_SIZE-1] = '\0';
|
||||||
}
|
}
|
||||||
// (TODO LATER) add a way to go back to note selection
|
// (TODO LATER) add a way to go back to note selection
|
||||||
|
|||||||
@@ -15,13 +15,15 @@
|
|||||||
/*Uses ncurses to get an input from the user.
|
/*Uses ncurses to get an input from the user.
|
||||||
Creates a new note with this input.
|
Creates a new note with this input.
|
||||||
also can create a journal if the name matches with journalRegex.
|
also can create a journal if the name matches with journalRegex.
|
||||||
returns the path to the note. */
|
returns the path to the note.
|
||||||
char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, char *bypass, char *journalRegex, int debug);
|
If you want to bypass the input TUI set bypass to 1 and bypassvalue to the note name
|
||||||
|
*/
|
||||||
|
char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, int bypass, char *bypassvalue, char *journalRegex, int debug);
|
||||||
/*Uses ncurses to get an input from the user.
|
/*Uses ncurses to get an input from the user.
|
||||||
Creates a new vault with this input.
|
Creates a new vault with this input.
|
||||||
If vault already exists, prints a warning.
|
If vault already exists, prints a warning.
|
||||||
returns nothing. */
|
returns nothing. */
|
||||||
void createNewVault(char *dirToVault, int debug);
|
void createNewVault(char *dirToVault, int bypass, char *bypassvalue, int debug);
|
||||||
/*this function is used multiple times let the user select one options from many with ncurses in a TUI.
|
/*this function is used multiple times let the user select one options from many with ncurses in a TUI.
|
||||||
options is the array of strings with all the options.
|
options is the array of strings with all the options.
|
||||||
optionsText is the text that will be printed at the top (For example: "Please select ...").
|
optionsText is the text that will be printed at the top (For example: "Please select ...").
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
_altDebug(shouldDebug, message, ##__VA_ARGS__)
|
_altDebug(shouldDebug, message, ##__VA_ARGS__)
|
||||||
#define error(condition, type, message, ...) \
|
#define error(condition, type, message, ...) \
|
||||||
_error(shouldDebug, condition, type, __FILE__, __LINE__, __func__, message, ##__VA_ARGS__)
|
_error(shouldDebug, condition, type, __FILE__, __LINE__, __func__, message, ##__VA_ARGS__)
|
||||||
#define HASH_MACRO "0ea1d20bcdd52c46c086d3dba125b9b83ad8cbea2e026d5646775f48bae8f867" // if the user inputs this hash. The program brokes. It was the best way i found to see if some values were unchanged
|
|
||||||
// you must edit this two values if you want to add suport for an editor
|
// you must edit this two values if you want to add suport for an editor
|
||||||
extern const char *supportedEditor[]; // array of supported editors
|
extern const char *supportedEditor[]; // array of supported editors
|
||||||
extern const int numEditors; // number of supported editors
|
extern const int numEditors; // number of supported editors
|
||||||
|
|||||||
Reference in New Issue
Block a user