mirror of
https://github.com/tomasriveral/NoteWrapper.git
synced 2026-08-12 10:20:46 +02:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e666ca32de | ||
|
|
2a8392ac2e | ||
|
|
292688296e | ||
|
|
4c18c2dda4 | ||
|
|
1bfb7f82a5 | ||
|
|
a32f97d229 | ||
|
|
6555b7247e | ||
|
|
2b2a3455d2 |
@@ -13,7 +13,7 @@
|
|||||||
in {
|
in {
|
||||||
packages.default = pkgs.stdenv.mkDerivation (finalAttrs: {
|
packages.default = pkgs.stdenv.mkDerivation (finalAttrs: {
|
||||||
pname = "notewrapper";
|
pname = "notewrapper";
|
||||||
version = "v2.2";
|
version = "v2.2.1";
|
||||||
|
|
||||||
src = ./.;
|
src = ./.;
|
||||||
|
|
||||||
|
|||||||
+22
-6
@@ -644,12 +644,13 @@ backup_config_end:
|
|||||||
altDebug("└------------------------------\n");
|
altDebug("└------------------------------\n");
|
||||||
}
|
}
|
||||||
// adds options
|
// adds options
|
||||||
int extraNotesOptions = 4;
|
int extraNotesOptions = 5;
|
||||||
filesArray = realloc(filesArray, (filesCount + extraNotesOptions) * sizeof(char *)); // resize filesArray to fit the extra options
|
filesArray = realloc(filesArray, (filesCount + extraNotesOptions) * sizeof(char *)); // resize filesArray to fit the extra options
|
||||||
filesArray[filesCount] = "Create new note";
|
filesArray[filesCount] = "Create new note";
|
||||||
filesArray[filesCount + 1] = "Back to vault selection";
|
filesArray[filesCount + 1] = "Search inside the vault";
|
||||||
filesArray[filesCount + 2] = "Delete vault";
|
filesArray[filesCount + 2] = "Back to vault selection";
|
||||||
filesArray[filesCount + 3] = "Quit (Ctrl+C)";
|
filesArray[filesCount + 3] = "Delete vault";
|
||||||
|
filesArray[filesCount + 4] = "Quit (Ctrl+C)";
|
||||||
char *noteSelected;
|
char *noteSelected;
|
||||||
// if we set to bypass the note selector
|
// if we set to bypass the note selector
|
||||||
if (bypassSelectionNote) {
|
if (bypassSelectionNote) {
|
||||||
@@ -680,7 +681,7 @@ backup_config_end:
|
|||||||
free(filesArray);
|
free(filesArray);
|
||||||
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 &&
|
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) {
|
strcmp(noteSelected, "Quit (Ctrl+C)") != 0 && strcmp(noteSelected, "Search inside the vault") != 0) {
|
||||||
open_note:
|
open_note:
|
||||||
bypassSelectionNote = 0; // we must reset bypassSelectionNote to avoid getting into an infinite
|
bypassSelectionNote = 0; // we must reset bypassSelectionNote to avoid getting into an infinite
|
||||||
// loop of bypassing the note selection
|
// loop of bypassing the note selection
|
||||||
@@ -694,12 +695,18 @@ backup_config_end:
|
|||||||
|
|
||||||
int *journalWasUpdated = malloc(sizeof(int));
|
int *journalWasUpdated = malloc(sizeof(int));
|
||||||
*journalWasUpdated = 0;
|
*journalWasUpdated = 0;
|
||||||
|
|
||||||
|
// used to go back to note selection
|
||||||
|
int *returnNoteSelection = malloc(sizeof(int));
|
||||||
|
*returnNoteSelection = 0;
|
||||||
|
|
||||||
if (!regexReturn) { // if the regex matches -> it's a journal
|
if (!regexReturn) { // if the regex matches -> it's a journal
|
||||||
debug("%s is a journal. Updating it...", noteSelected);
|
debug("%s is a journal. Updating it...", noteSelected);
|
||||||
fullPath = updateJournal(fullPath, noteSelected, timeFormat, journalWasUpdated,
|
fullPath = updateJournal(fullPath, noteSelected, timeFormat, journalWasUpdated, returnNoteSelection,
|
||||||
shouldDebug); // we return the path. As if it is a divided journal we
|
shouldDebug); // we return the path. As if it is a divided journal we
|
||||||
// must point to the correct entry
|
// must point to the correct entry
|
||||||
}
|
}
|
||||||
|
if (!*returnNoteSelection) { // if we don't need to return to the note selection
|
||||||
if (newLineOnOpening) {
|
if (newLineOnOpening) {
|
||||||
if (*journalWasUpdated) {
|
if (*journalWasUpdated) {
|
||||||
appendToFile(fullPath, " \n",
|
appendToFile(fullPath, " \n",
|
||||||
@@ -712,11 +719,20 @@ backup_config_end:
|
|||||||
}
|
}
|
||||||
openEditor(fullPath, editorToOpen, shouldRender, shouldJumpToEnd, shouldDebug);
|
openEditor(fullPath, editorToOpen, shouldRender, shouldJumpToEnd, shouldDebug);
|
||||||
free(fullPath);
|
free(fullPath);
|
||||||
|
}
|
||||||
|
free(returnNoteSelection);
|
||||||
} else if (strcmp(noteSelected, "Create new note") == 0) {
|
} else if (strcmp(noteSelected, "Create new note") == 0) {
|
||||||
note_creation:
|
note_creation:
|
||||||
noteSelected = createNewNote(notesDirectoryString, vaultSelected, bypassSelectionNote, bypassSelectionNoteValue, 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, "Search inside the vault") == 0) {
|
||||||
|
char *vaultPath = malloc(PATH_MAX);
|
||||||
|
snprintf(vaultPath, PATH_MAX, "%s/%s/", notesDirectoryString, vaultSelected);
|
||||||
|
char *result = fzfSelect(vaultPath, "Input text to be searched", shouldDebug);
|
||||||
|
bypassSelectionNote = 1;
|
||||||
|
bypassSelectionNoteValue = result;
|
||||||
|
free(vaultPath);
|
||||||
} else if (strcmp(noteSelected, "Back to vault selection") == 0) {
|
} else if (strcmp(noteSelected, "Back to vault selection") == 0) {
|
||||||
shouldChangeVault = 1;
|
shouldChangeVault = 1;
|
||||||
} else if (strcmp(noteSelected, "Delete vault") == 0) {
|
} else if (strcmp(noteSelected, "Delete vault") == 0) {
|
||||||
|
|||||||
+5
-2
@@ -188,7 +188,7 @@ char **getVaultsFromDirectories(char **directoryStringArray, int directoryNumber
|
|||||||
return vaultsArray;
|
return vaultsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWasUpdated, int shouldDebug) {
|
char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWasUpdated, int *returnNoteSelection, int shouldDebug) {
|
||||||
path[PATH_MAX] = '\0'; // it assures it is a string (Most cases this does nothing). But rewriting at least
|
path[PATH_MAX] = '\0'; // it assures it is a string (Most cases this does nothing). But rewriting at least
|
||||||
// one bytes make the compile happy. He doesn't want to return an unchanged input.
|
// one bytes make the compile happy. He doesn't want to return an unchanged input.
|
||||||
debug("Handling the journal %s", path);
|
debug("Handling the journal %s", path);
|
||||||
@@ -221,13 +221,14 @@ char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWas
|
|||||||
that the Create new entry in journal is on top entryArray = realloc(entryArray,
|
that the Create new entry in journal is on top entryArray = realloc(entryArray,
|
||||||
sizeof(char*));*/
|
sizeof(char*));*/
|
||||||
// simpler to just malloc 2 and later realloc
|
// simpler to just malloc 2 and later realloc
|
||||||
const int extraOptions = 3;
|
const int extraOptions = 4;
|
||||||
char **entryArray = malloc(extraOptions * sizeof(char *));
|
char **entryArray = malloc(extraOptions * sizeof(char *));
|
||||||
char *createEntryMessage = malloc(PATH_MAX);
|
char *createEntryMessage = malloc(PATH_MAX);
|
||||||
snprintf(createEntryMessage, PATH_MAX, "Create new entry for the journal %s", journal);
|
snprintf(createEntryMessage, PATH_MAX, "Create new entry for the journal %s", journal);
|
||||||
entryArray[0] = createEntryMessage;
|
entryArray[0] = createEntryMessage;
|
||||||
entryArray[1] = "Open random entry";
|
entryArray[1] = "Open random entry";
|
||||||
entryArray[2] = "Search inside entries";
|
entryArray[2] = "Search inside entries";
|
||||||
|
entryArray[3] = "Return to the note selection";
|
||||||
int entryCount = extraOptions; // we need to count how many dirs there is to always readjust
|
int entryCount = extraOptions; // we need to count how many dirs there is to always readjust
|
||||||
// how many memory we alloc
|
// how many memory we alloc
|
||||||
// Refer https://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html
|
// Refer https://pubs.opengroup.org/onlinepubs/7990989775/xsh/readdir.html
|
||||||
@@ -301,6 +302,8 @@ char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWas
|
|||||||
snprintf(selectedOption, PATH_MAX, "%s/%s", path, temp);
|
snprintf(selectedOption, PATH_MAX, "%s/%s", path, temp);
|
||||||
path = strdup(selectedOption);
|
path = strdup(selectedOption);
|
||||||
free(selectedOption);
|
free(selectedOption);
|
||||||
|
} else if (strcmp(selectedOption, "Return to the note selection") == 0) {
|
||||||
|
*returnNoteSelection = 1;
|
||||||
} else { // we just recreate the path to the selected entry
|
} else { // we just recreate the path to the selected entry
|
||||||
// snprintf does not like to have the same variable as input and output so we use a
|
// snprintf does not like to have the same variable as input and output so we use a
|
||||||
// buffer
|
// buffer
|
||||||
|
|||||||
+2
-1
@@ -25,6 +25,7 @@ char **getVaultsFromDirectories(char **directoryStringArray, int directoryNumber
|
|||||||
// handles both type of journal (divided and unified).
|
// handles both type of journal (divided and unified).
|
||||||
// creates new entry with date.
|
// creates new entry with date.
|
||||||
// for divided select if we want to acces to a new entry or a old one.
|
// for divided select if we want to acces to a new entry or a old one.
|
||||||
|
// returnNoteSelection tells us if the user wants to go back to the note selection.
|
||||||
// returns the path to the file that needs to be opened.
|
// returns the path to the file that needs to be opened.
|
||||||
char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWasUpdated, int shouldDebug);
|
char *updateJournal(char *path, char *journal, char *timeFormat, int *journalWasUpdated, int *returnNoteSelection, int shouldDebug);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -179,13 +179,7 @@ char *fzfSelect(char *pathToFiles, char *selectText, int shouldDebug) {
|
|||||||
error(fd == -1, "program", "mkstemp failed");
|
error(fd == -1, "program", "mkstemp failed");
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
/*
|
|
||||||
* STEP 1:
|
|
||||||
* Build index once into temp file
|
|
||||||
* format: file:line:content
|
|
||||||
*/
|
|
||||||
snprintf(command, sizeof(command), "rg --line-number --no-heading --color=never . \"%s\" > %s", pathToFiles, indexFile);
|
snprintf(command, sizeof(command), "rg --line-number --no-heading --color=never . \"%s\" > %s", pathToFiles, indexFile);
|
||||||
|
|
||||||
debug("INDEX CMD: %s", command);
|
debug("INDEX CMD: %s", command);
|
||||||
|
|
||||||
if (system(command) != 0) {
|
if (system(command) != 0) {
|
||||||
@@ -193,45 +187,6 @@ char *fzfSelect(char *pathToFiles, char *selectText, int shouldDebug) {
|
|||||||
error(1, "program", "rg indexing failed");
|
error(1, "program", "rg indexing failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* STEP 2:
|
|
||||||
* Use fzf on the index file (NO rg anymore)
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
EXPLANATION:
|
|
||||||
|
|
||||||
cat %s
|
|
||||||
→ feeds prebuilt index file (format: file:line:content) into fzf
|
|
||||||
|
|
||||||
fzf --delimiter ':'
|
|
||||||
→ splits each line into fields:
|
|
||||||
{1} = file path
|
|
||||||
{2} = line number
|
|
||||||
{3} = content
|
|
||||||
|
|
||||||
--prompt
|
|
||||||
→ UI prompt text shown in fzf
|
|
||||||
|
|
||||||
--preview
|
|
||||||
→ runs a shell command for selected item:
|
|
||||||
file={1} → current file
|
|
||||||
line={2} → line number of match
|
|
||||||
|
|
||||||
nl -ba "$file"
|
|
||||||
→ prints file with line numbers
|
|
||||||
|
|
||||||
sed -n "$((line-5)),$((line+5))p"
|
|
||||||
→ extracts a window of 5 lines above and below match
|
|
||||||
|
|
||||||
sed "... -> ..."
|
|
||||||
→ highlights the matched line (middle of window) with red arrow
|
|
||||||
|
|
||||||
--preview-window=right:60%:hidden
|
|
||||||
→ preview appears on right, 60% width, initially hidden
|
|
||||||
|
|
||||||
--bind 'change:show-preview'
|
|
||||||
→ preview only appears after first selection change (not at startup)
|
|
||||||
*/
|
|
||||||
snprintf(command, sizeof(command),
|
snprintf(command, sizeof(command),
|
||||||
"cat %s | fzf --delimiter ':' --prompt='%s' "
|
"cat %s | fzf --delimiter ':' --prompt='%s' "
|
||||||
"--preview 'file={1}; line={2}; nl -ba \"$file\" | sed -n \"$((line-5)),$((line+5))p\" | "
|
"--preview 'file={1}; line={2}; nl -ba \"$file\" | sed -n \"$((line-5)),$((line+5))p\" | "
|
||||||
@@ -254,16 +209,25 @@ char *fzfSelect(char *pathToFiles, char *selectText, int shouldDebug) {
|
|||||||
buffer[strcspn(buffer, "\n")] = '\0';
|
buffer[strcspn(buffer, "\n")] = '\0';
|
||||||
result = strdup(buffer);
|
result = strdup(buffer);
|
||||||
}
|
}
|
||||||
|
debug("Buffer: %s", buffer);
|
||||||
|
debug("result: %s", result);
|
||||||
|
|
||||||
// cut at first ':'
|
// cut at first ':'
|
||||||
result = strtok(result, ":");
|
result = strtok(result, ":");
|
||||||
// cut at / (because we need the full paths before and we only need to return the journal entry)
|
// we need to cut out the whole pathToFiles
|
||||||
char *token = strtok(result, "/");
|
int pathToFilesLen = strlen(pathToFiles);
|
||||||
result = NULL;
|
int cutOut = 0;
|
||||||
while (token != NULL) {
|
for (int i = 0; i < pathToFilesLen; i++) {
|
||||||
result = token;
|
if (pathToFiles[i] == result[i]) {
|
||||||
token = strtok(NULL, "/"); // Passing NULL means “don’t start a new string, resume
|
cutOut = i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
result += cutOut + 1; // the + 1 cuts the first /
|
||||||
|
|
||||||
|
// in case we select a journal, we won't open the entry just yet. We only need to return the journal name (everything before [now the first] /
|
||||||
|
result = strtok(result, "/");
|
||||||
|
|
||||||
|
debug("Cleaned note: %s", result);
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
pclose(fzfPipe);
|
pclose(fzfPipe);
|
||||||
|
|||||||
Reference in New Issue
Block a user