mirror of
https://github.com/tomasriveral/NoteWrapper.git
synced 2026-08-12 10:20:46 +02:00
Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
292688296e | ||
|
|
4c18c2dda4 | ||
|
|
1bfb7f82a5 | ||
|
|
d8a11bbc16 | ||
|
|
1d95983d5d | ||
|
|
30449ca473 | ||
|
|
7af79c76b1 | ||
|
|
27b8b310cb | ||
|
|
4d228fb911 | ||
|
|
34a2546990 | ||
|
|
7231741f2d | ||
|
|
280c329339 | ||
|
|
f7c84136a5 | ||
|
|
77b5148489 | ||
|
|
d537357802 | ||
|
|
fd77eaa4de | ||
|
|
d6fa89785f | ||
|
|
30616b1b6f | ||
|
|
c9ee6ca032 | ||
|
|
2a09d4ee46 | ||
|
|
e370f98c5e | ||
|
|
6e6ddebb5e | ||
|
|
91d6db6c74 | ||
|
|
f85a32f97f | ||
|
|
bc306ca630 | ||
|
|
89c686652e | ||
|
|
8ee0096540 | ||
|
|
2d6787a91b | ||
|
|
2f688df3ec |
@@ -48,7 +48,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
gh pr create \
|
gh pr create \
|
||||||
--base main \
|
--base main \
|
||||||
--head release/v${{ inputs.version }} \
|
--head release/${{ inputs.version }} \
|
||||||
--title "[Automatic] Release PR ${{ inputs.version }}" \
|
--title "[Automatic] Release PR ${{ inputs.version }}" \
|
||||||
--body "Automated release PR.\nAfter the test's succesfull run, create manually a release with a new tag matching ${{ inputs.version }}"
|
--body "Automated release PR.\nAfter the test's succesfull run, create manually a release with a new tag matching ${{ inputs.version }}"
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# NoteWrapper
|
# NoteWrapper
|
||||||
|
|
||||||
Note: This project fullfills all my usecase for now, so my main source for features ideas dried out. So if you have good ideas, feel free to open an issue ;)
|
Note: This project fullfills all my usecases for now, so my main source for features ideas dried out. So if you have good ideas, feel free to open an issue ;)
|
||||||
|
|
||||||
[](https://deepwiki.com/tomasriveral/notewrapper)
|
[](https://deepwiki.com/tomasriveral/notewrapper)
|
||||||
|
|
||||||
|
|||||||
Generated
+4
-21
@@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1779508470,
|
"lastModified": 1779560665,
|
||||||
"narHash": "sha256-Ap9KJX+5xHIn3bPIpfNgT6MEXdAECECwo4/rmlQD74M=",
|
"narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "29916453413845e54a65b8a1cf996842300cd299",
|
"rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -34,27 +34,10 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notewrapper": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1779721342,
|
|
||||||
"narHash": "sha256-QbRzgD4HoUUemaVCIZ2VfiW+SUjzFY2rL51CLOxQLvk=",
|
|
||||||
"owner": "tomasriveral",
|
|
||||||
"repo": "NoteWrapper",
|
|
||||||
"rev": "e370f98c5ebc3c037dec4e7e35f26230724b70d3",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "tomasriveral",
|
|
||||||
"repo": "NoteWrapper",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs"
|
||||||
"notewrapper": "notewrapper"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
|
|||||||
@@ -4,22 +4,18 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
notewrapper = {
|
|
||||||
url = "github:tomasriveral/NoteWrapper";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils, notewrapper }:
|
outputs = { self, nixpkgs, flake-utils}:
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
in {
|
in {
|
||||||
packages.default = pkgs.stdenv.mkDerivation (finalAttrs: {
|
packages.default = pkgs.stdenv.mkDerivation (finalAttrs: {
|
||||||
pname = "notewrapper";
|
pname = "notewrapper";
|
||||||
version = "v2.1";
|
version = "v2.2";
|
||||||
|
|
||||||
src = notewrapper;
|
src = ./.;
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|||||||
+13
-5
@@ -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
|
||||||
@@ -717,6 +718,13 @@ backup_config_end:
|
|||||||
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) {
|
||||||
|
|||||||
@@ -130,16 +130,16 @@ char *createNewNote(char dirToVault[PATH_MAX], char *vaultFromDir, int bypass, c
|
|||||||
free(fileFullPath);
|
free(fileFullPath);
|
||||||
} else { // if it is a unified journal
|
} else { // if it is a unified journal
|
||||||
char *fileFullPath = malloc(PATH_MAX);
|
char *fileFullPath = malloc(PATH_MAX);
|
||||||
snprintf(fileFullPath, PATH_MAX, "%s/%s/%s", dirToVault, vaultFromDir, fileName);
|
// we append .md directly to fileName and not only to fileFullPath to avoid passing the wrong fileName later.
|
||||||
int len = strlen(fileFullPath);
|
int lenName = strlen(fileName);
|
||||||
if (fileFullPath[len - 3] != '.' || fileFullPath[len - 2] != 'm' || fileFullPath[len - 1] != 'd') { // there might be a cleaner way to do this
|
if (fileName[lenName - 3] != '.' && fileName[lenName - 2] != 'm' && fileName[lenName - 2] != '1') {
|
||||||
error(len > PATH_MAX - 3, "user", "%s is too big (greater than PATH_MAX-3) and we can't append .md", fileFullPath);
|
strcat(fileName, ".md");
|
||||||
strncat(fileFullPath, ".md", PATH_MAX);
|
debug("We just appended .md to %s", fileName);
|
||||||
// we checked before if fileName didn't already exist.
|
|
||||||
// we must redo it as we add a .mode
|
|
||||||
struct stat st;
|
|
||||||
error(stat(fileFullPath, &st) == 0, "user", "%s already exists", fileFullPath);
|
|
||||||
}
|
}
|
||||||
|
snprintf(fileFullPath, PATH_MAX, "%s/%s/%s", dirToVault, vaultFromDir, fileName);
|
||||||
|
// we verify if the file doesn't already exist as we might just have changed the fileName and (by extension) the file path.
|
||||||
|
struct stat metadata;
|
||||||
|
error(stat(fileFullPath, &metadata) == 0, "user", "%s already exists", fileFullPath);
|
||||||
FILE *filePointer;
|
FILE *filePointer;
|
||||||
filePointer = fopen(fileFullPath, "w"); // creates and opens the file
|
filePointer = fopen(fileFullPath, "w"); // creates and opens the file
|
||||||
error(filePointer == NULL, "program", "The %s couldn't be created.", fileFullPath);
|
error(filePointer == NULL, "program", "The %s couldn't be created.", fileFullPath);
|
||||||
@@ -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