tpwo / pyzet Goto Github PK
View Code? Open in Web Editor NEWSimple note-taking with CLI & Git integration.
Home Page: https://pypi.org/project/pyzet/
License: Apache License 2.0
Simple note-taking with CLI & Git integration.
Home Page: https://pypi.org/project/pyzet/
License: Apache License 2.0
E.g.
pyzet add Foo bar
Should enter a text editor with title already included:
# Foo bar
Adding this will probably make #4 a problem again, so it will need a more clever resolution.
Also, pyzet add
can potentially also accept other kind of information like:
This would allow for more automated creation of zettels. Probably the nicest to have is the option with the image, because now it requires a lot of steps, including rebasing for cleaner Git history. But this should be discussed in a separate issue once this one is resolved.
Alphabets that use non-ASCII characters are annoying to grep for, and there should be a way to enable a convenient search patterns that deal with this problem.
A user used non-ASCII character in the zettel content, and would like to find it with using only ASCII characters
A user used ASCII character in the zettel content (any reason like laziness/mistake/copied text), and would like to find it also when looking for its non-ASCII counterpart
E.g. for Polish we have:
ą -- a
ć -- c
ę -- e
ł -- l
ń -- n
ó -- o
ś -- s
ź -- z
ż -- z
Of course, capital letters also should be supported.
grepping for zolta ges
should find żółta gęś
grepping for żółta gęś
should find zolta ges
-- (use case: we want to find a copied text from someone who haven't used diacritics)
probably controlled with a special flag or even multiple flags (i.e. there can be different modes: a single two-way or two one-way)
git grep
pattern should be probably modified in such a way that it looks for strings with OR
parts when one or the other character should match
However, multiple non-ASCII chars can map to a single ASCII, e.g. both ż
and ź
map to z
. In such case, all three should be detected when grepping for z
, but only two when grepping for ż
or ź
(because ż
and ź
shouldn't be treated as the same letter)
There are many languages, so hard-coding these rules for Polish doesn't seem like the best idea under the sun. I would prefer to create some kind of abstraction layer, so the rules can be added independently for each language. Maybe it can be even a part of a config file for custom mappings (to be checked is how YAML handles non-ASCII), but I think that built-in support for given languages can be included.
Above, I only wondered about a situation when we have char to char mapping. But there are examples when multiple ASCII characters map to a single non-ASCII char (e.g. German ß
maps to ss
). I'm not sure if this is trivial to extend it like that.
With almost 500 zettels in my ZK, pyzet list
takes 0.1 sec to execute in WSL2, and it will be only worse in the future.
I wonder if I could use git grep
to produce the same kind of output faster by using some flags with this command. E.g. ^#\s.*
can be used to match each title, as showed in #24.
I'm pretty sure that just calling git grep
will be faster, but additional processing in Python will be needed to provide the same kind of output as the current pyzet list
command with different flags etc.
Another idea is to replace pathlib
which is kinda slow. But it's hard to tell without earlier profiling.
The behavior seems very strange:
trivvz@la7400:~
> pz push
Everything up-to-date
trivvz@la7400:~
> pz status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
trivvz@la7400:~
> pz push
Everything up-to-date
trivvz@la7400:~
> pz push -- -v
Pushing to https://github.com/wojdatto/zet.git
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 381 bytes | 381.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0), pack-reused 0
POST git-receive-pack (564 bytes)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/wojdatto/zet.git
a084ee5..e2a7574 main -> main
updating local tracking ref 'refs/remotes/origin/main'
trivvz@la7400:~
> pz status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
It might be connected with the implementation of this command:
def push_to_remote(path: Path, options: list[str]) -> int:
subprocess.call([_get_git_cmd(), "-C", path, "push", *options])
return 0
Git itself with -C
flag seems to push fine.
OK, I found it during writing this issue. This what actually is going on:
trivvz@la7400:~
> git -C ./zet status .
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
trivvz@la7400:~
> git -C ./zet push .
Everything up-to-date
trivvz@la7400:~
> git -C ./zet push -v
Pushing to https://github.com/wojdatto/zet.git
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 317 bytes | 317.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
POST git-receive-pack (500 bytes)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/wojdatto/zet.git
2807853..9a00a28 main -> main
updating local tracking ref 'refs/remotes/origin/main'
This .
is the default value of options argument in push_to_remote()
function, and git seems to not like it for some reason. If I use any custom argument like -v
, the dot is replaced with it and push starts working.
Readme is already very long, so moving this section makes sense just to unclutter it a bit.
This probably means that the layout of files in docs
folder will be updated. I.e., a main file with summary of what's inside docs in separate files, and then the files themselves rather than the single README.md with the tutorial.
I can also think about some kind of GitHub Pages thingy to host the documentation in a more user-friendly way. But it's probably too early for that.
Currently, pyzet supports only the following layout with zettels
folder:
.
└── zettels
├── 20220416111040
├── 20220416171449
└── 20220416171827
But other similar ZK tools tend to prefer a flat layout without anything like zettels
folder (e.g. Rob's repo):
.
├── 20220416111040
├── 20220416171449
└── 20220416171827
My approach was done on purpose as GitHub repo loads noticeably longer with a lot of zettels in a flat layout (it cannot display more than 1000 elements, but it's still quite a big number).
Also, it's a bit hard to see a readme when you have to scroll pass by 1000 zettels...
Anyway, the things are like they are, so I suppose that pyzet should also support a flat layout.
I think that it can be implemented as another field that can be configured in YAML. By default it can use sane settings (i.e. current zettels
folder), but user can change it to any name we wishes or to an empty string to enforce a flat layout.
I'm not sure if adding more nesting (e.g. foo/bar
in YAML) should be allowed. But the implementation is really not a problem -- pathlib
supports it out of the box:
>>> pathlib.Path("zet", "foo/bar")
PosixPath('zet/foo/bar')
There is also a question of translating between layouts. Of course, it can be done in a naive way by just moving all zettels to a new location with a single commit, but this will mean that all commit messages aligned with zettel titles will be lost.
So, this is an open topic, but it should be discussed in a separate issue.
I believe that pip install
section in the readme should be at the very top, and now it's in the middle.
It should probably cover only the basic command (plus a variant with git+
), and manual or development installation should be covered later.
Configuration
)CONTRIBUTING.md
)This directly impacts the help output showed with -h/--help
flag. I think that similar commands can be grouped together. Also, help prompt should be one line if possible (currently not true for commands that interact with Git), with more information available under help for a given command.
Documentation for setup.py
https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#keywords
In setup.cfg
it seems to be very similar:
keywords = one, two
It can use a similar approach as the one presented in #24 to display a zettel title.
Basically, when multiple patterns would be supplied, the output should include only zettels that contain all the provided patterns (in the whole zettel, not a single line).
I noticed that with only a single pattern, pyzet grep
can return overwhelming number of matches in bigger ZK, and this feature would help to deal with it.
Zettel title pattern which is passed to git grep
is too simple. It's done here: https://github.com/wojdatto/pyzet/blob/01ecc8143c88eeeff9ed213028b3e54f1c5b5a1b/src/pyzet/main.py#L377
How to reproduce:
#
. In Markdown it's not recommended, but you can have a fenced code block with #
comments, co this should still work fine.I'm not sure if git grep
allows passing an argument to look for a single pattern only in a specific line. It should be applied for only the title match, as one pretty much always looks for other stuff when -t
flag is being used.
Still, it's better if shows too much stuff rather than too little.
E.g.
> pyzet add
INFO:root:20211026163450 was created
[main b5aa064] The correct approach to line endings in Git
1 file changed, 27 insertions(+)
create mode 100644 20211026163450/README.md
It is possible by using some git grep
flags:
$ git -C 'testing/zet/zettels' grep -Ii --heading --break --all-match -e '^#\s.*' --or -e 'hello'
20211016205158/README.md
# Zet test entry
Hello there!
20211016223643/README.md
# Another zet test entry
Hello everyone
^#\s.*
symbolizes the zettel title. --or
is used to provide git grep
with multiple patterns, and --all-match
has to be used, because otherwise all zettels would be matched (because every zettel contains a title).
The side effect of this approach is the fact that the first line is colored as matched (i.e. full red), but I don't see another way without messing with git grep
output in Python, which I'd like to avoid.
Because of that, this should be rather an optional flag rather than a normal behavior.
This seems like a basic functionality that is missing right now. The command should have an optional parameter that will be the target folder. By default, the one from config will be used.
Currently, pyzet edit <ID>
will always add ED:
to commit message, even if the file is not yet committed and tracked by git.
This is a problem when I try using my ZK repo with pre-commit. If the commit is rejected, I need to do pz edit
and fix the issues, and then the commit message is wrong (as there is only one commit).
So, pyzet edit
should check for the file in git, and add ED:
only if the file is already being tracked.
Currently, --
needs to be passed, so argparse doesn't consume flag, but passes it to git. This is a bit annoying when one wants to display a remote URL. It seems that the simplest solution is to just pass -v
flag by default (similar to pyzet pull
which automatically adds --rebase
flag).
Lack of config file is currently one of the biggest problems with pyzet.
I think that it should be a simple YAML file with only a few entries, at least for now.
I'd like to locate it under ~/.config/pyzet/pyzet.yaml
, so we don't have another dot file cluttering the home folder. Likewise, I think that this is a good path even on Windows (and some tools also use it, gitk
on my local machine for example).
I see that .config
is a part of XDG Base Directory Specification, so it's probably a good idea to be in line with it. Some reference: https://unix.stackexchange.com/q/312988
The current version has some integration, with Git push
, pull
, and status
commands being available.
But sometimes this is not enough. Usually, I can just cd
to ZK folder and fix the issue directly. Maybe it can be done in a better way?
E.g. it can be something like pyzet git
command which will accept an actual command with parameters:
pyzet git diff --staged
But I had some issues with that, as argparse always tries to parse the arguments unless there is --
before them:
If you have positional arguments that must begin with - and don’t look like negative numbers, you can insert the pseudo-argument '--' which tells parse_args() that everything after that is a positional argument.
E.g.
pyzet git diff -- --staged
Only then, --staged
won't be parsed and can be redirected to Git. Actually, pyzet push
& pyzet status
allow providing parameters only using this approach.
And I don't like it, so there must be a better way.
Reference:
https://docs.python.org/3/library/argparse.html#arguments-containing
One less dependency is always a nice thing, and it seems that the git grep
command features everything that I need right now.
This would make it similar to git clean
command which:
-f/--force
flag that must be used in order to remove anything-n/--dry-run
flag that blocks removing anything, even if -f
is used in the same command.For now, pyzet clean
has a dry run flag, and it's fine, but an additional -f/--force
flag should be added to make it similar to git clean
.
The problem is that the current values:
repo: ~/zet
editor: /usr/bin/vim
git: /usr/bin/git
will fail even with Git Bash on Windows, because git
is at /cmd/git
.
One solution might be something like:
pyzet sample-config windows
Then, Unix
should be probably the other allowed option:
pyzet sample-config unix
I see that I'm not the only one who is annoyed by the need to always include <>
in Markdown URLs in the zetetls:
https://github.com/rwxrob/zet/tree/c7165508d0522bb9ab45de09f4fb399c9ce5831c/20220411085733
But I don't like that this is against CommonMark specs (and they're even named autolinks):
https://spec.commonmark.org/0.30/#autolink
On the other hand, GFM (which is just a fork of CommonMark) supports them:
https://github.github.com/gfm/#extended-www-autolink
Their parser source code is there, so the detection heuristics can be always reimplemented:
https://github.com/github/cmark-gfm
Extended link detection is also supported by VS Code. Windows Terminal is generally also able to detect links in various (not only Markdown) contexts.
I'm not sure about the best solution there. For sure, <>
should be a valid option, and the question is whether to allow also for links without <>
.
It turned out that encoding is missing - Python handles it well inside the script, but to send it to the pipe, it needs to know how to encode it. And it cannot handle Polish characters.
Error:
Traceback (most recent call last):
File "C:\Users\trivvz\repos\github.com\trivvz\pyzet\venv\Scripts\pz-script.py", line 33, in <module>
sys.exit(load_entry_point('pyzet', 'console_scripts', 'pz')())
File "c:\users\trivvz\repos\github.com\trivvz\pyzet\src\pyzet\main.py", line 106, in main
return show_zet(config.repo_path, args.id[0])
File "c:\users\trivvz\repos\github.com\trivvz\pyzet\src\pyzet\main.py", line 154, in show_zet
print_zettel(zettel)
File "c:\users\trivvz\repos\github.com\trivvz\pyzet\src\pyzet\zettel.py", line 50, in print_zettel
print(line, end="")
File "C:\Program Files\Python39\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u015b' in position 13: character maps to <undefined>
More on that:
A bit related to the idea in #49 with the intention unclutter the readme file.
Note that the link and its description in the tutorial also should be updated:
https://github.com/wojdatto/pyzet/blob/5a0d90611716885d5e1408a59785a3d7664adbda/docs/README.md?plain=1#L126-L128
This would make the app much more user-friendly.
Also, with autocompletion, some redesign of the CLI can be done. I've got inspired by this: https://youtu.be/wjXxa6SiUA8
It should be similar to the current handling of pyzet push
and pyzet status
commands, e.g.:
pyzet grep foo -- --or -e bar
Additional options are passed after --
, and they're not parsed by argparse, but send directly to the command called in the background (git grep
in this case).
I'm using a relative link, and on PyPI there is a copy of README.md
that serves as a description of the package. I think that the best solution is to just remove this link because it doesn't bring much added value.
The current suggested link formatting is not ideal for longer links:
Refs:
* <http://described-example.com/> -- This is an example of a slightly longer description
* <http://example.com/>
A two line approach might be used instead if a link has description. Then, a blank line should be used between links for better readability in the source form. Description first seems like a better choice:
Refs:
* This is an example of a slightly longer description
<http://described-example.com/>
* <http://example.com/>
I guess that this blank line should be always used just to simplify the approach, even if there are only bare links:
Refs:
* <http://example.com/>
* <http://foobar.com/>
This will allow for easier handling of any automation if implemented as a part of pyzet
.
The help available under -h/--help
is probably not enough for the tool to be easy to use for pretty much anyone.
I'll write a quick introduction to pyzet explaining how to use the most basic commands.
GitHub Wiki might be a good place for that. Not really, I think that it's easier just to create docs
folder, and put Markdown file there.
The link probably should be global, though, as the main readme in showed also on PyPI.
It just looks for the README.md
inside, if it is gone, then the warning is raised, even if there are additional files in the same folder.
When trying to clean this folder with pyzet clean
nothing happens, as this command actually checks if the folder is empty, and proceeds only in such situation.
The solution is probably to add a new type of warning if there are additional files in the folder.
Zettels are currently linked using Markdown relative links and a custom syntax implemented with #21:
* [20220415172325](../20220415172325) -- An example zettel link
I think that I can safely get rid of --
saving three characters, and this shouldn't impact the readability both in source or rendered form:
* [20220415172325](../20220415172325) An example zettel link
In #30 I mentioned an idea to simplify the URL formatting, and theoretically it could be implemented here as well:
* An example zettel link
[20220415172325](../20220415172325)
* Another example zettel link
[20220415171650](../20220415171650)
But I'm not sure if this is a good idea.
This will be more important when links are being parsed for already created zettels. But then, there is also an issue with dealing with the legacy approach. Possibly some kind of conversion script would become handy (probably a more sophisticated one, so title-commit-messages are not lost after doing one big update commit).
Currently, it's basically a raw grep output:
zettels/20211016205158/README.md:3:Hello there!
zettels/20211016223643/README.md:3:Hello everyone
And it could be something like that:
20211016205158:3:Hello there!
20211016223643:3:Hello everyone
so longer lines can fit on screen, which is currently not always true.
The number in the middle (here: 3
) is the line number that was matched, so I think that it's good to have it there.
With a new approach in logging introduced in 334330f, it will be a good idea to allow for easy modification of the log level without changing the source code.
I like the idea with count
action in argparse which literally counts how many times a flag was passed. A simple proposal:
pyzet show
# 0 times, WARNING log level (because we sometimes show warnings to the user)
pyzet -v show
# 1 time, INFO log level
pyzet -vv show
# 2 times, DEBUG log level
pyzet -vvv show
# 3 times, still DEBUG log level because we don't want to go further
Currently, all pyzet
commands that interact with a single zettel require passing its ID, which is guaranteed to be unique, but is sometimes annoying, and usually requires an additional command or two to actually obtain it.
An alternative approach would be to try opening a zettel based on a keyword / set of keywords that are able to uniquely identify a zettel. If non-unique enough keywords were passed, pyzet
should enter an interactive mode, giving the user a choice to select from a list of matched zettels. E.g.:
$ pyzet edit foo bar
Found 3 matches:
[1] I like foo bar
[2] Two foos walk into the bar
[3] Baz foo bar foo
Counting starts from 1
as 0
is far away to the right, and it would be annoying. A user types one of the presented numbers and accepts it with Enter
.
Multiple modes can be implemented:
Things to consider:
-i, --ignore-case
flag should be included.the
in all zettels' contents. It can have a default reasonable value and a flag can be added to overwrite it in a given search.I think that git grep
can once again come to help. Search modes listed above can be probably implemented with the help of some regex, and git grep
output can alter to only show matched file names, which then can be parsed and displayed to the user by Python.
A presented list of matched zettels should for sure show their titles. Maybe also IDs, so they can be easily checked?
A single match would go straight away to the zettel interaction (just like ID).
This solution would be to display the list of matches to the user, and then quit. A user task is then to copy the zettel ID (so it has to be displayed along with the title) and use it in a new command.
This approach is less convenient, but can be introduced as a completely new command.
Actually, both of them can be implemented, leaving the choice to the user. The in-behind logic could be probably shared a lot here.
During accidental copy-paste, I've got this error. Probably it's a good idea to validate the zettel ID for add/edit etc. Or at least do a try..except
there.
$ pz edit ────────────────────────────────────────────────────────────────────────────────────────────────────────┤20220108134506
Traceback (most recent call last):
File "/home/trivvz/.local/bin/pyzet", line 8, in <module>
sys.exit(main())
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 40, in main
return _parse_args(args)
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 233, in _parse_args
return _parse_args_with_id(id_, args, config)
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 295, in _parse_args_with_id
_validate_id(id_, command, config)
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 401, in _validate_id
if not zettel_dir.is_dir():
File "/usr/lib/python3.8/pathlib.py", line 1422, in is_dir
return S_ISDIR(self.stat().st_mode)
File "/usr/lib/python3.8/pathlib.py", line 1198, in stat
return self._accessor.stat(self)
OSError: [Errno 36] File name too long: '/home/trivvz/zet/zettels/────────────────────────────────────────────────────────────────────────────────────────────────────────┤20220108134506'
Probably, there are a lot of ways to trigger it, e.g.:
$ pyzet list | git grep -l
fatal: not a git repository (or any of the parent directories): .git
Traceback (most recent call last):
File "/home/trivvz/.local/bin/pyzet", line 8, in <module>
sys.exit(main())
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 41, in main
return _parse_args(args)
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 193, in _parse_args
return _parse_args_without_id(args, config)
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 276, in _parse_args_without_id
return list_zettels(
File "/home/trivvz/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 341, in list_zettels
print(f"{representation} - {zettel.title}")
BrokenPipeError: [Errno 32] Broken pipe
Potential fix:
try:
return _parse_args(args)
except BrokenPipeError:
raise SystemExit("<more user friendly error msg>")
$ pyzet init /tmp/foo
Traceback (most recent call last):
File "/home/user/.local/bin/pyzet", line 8, in <module>
sys.exit(main())
File "/home/user/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 40, in main
return _parse_args(args)
File "/home/user/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 223, in _parse_args
return _parse_args_without_id(args, config)
File "/home/user/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 308, in _parse_args_without_id
return init_repo(config)
File "/home/user/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 478, in init_repo
_create_empty_folder(config.repo)
File "/home/user/.local/pipx/venvs/pyzet/lib/python3.8/site-packages/pyzet/main.py", line 488, in _create_empty_folder
if path.exists():
AttributeError: 'str' object has no attribute 'exists'
When a custom path is provided by the user, it should be converted from str
to pathlib.Path
.
I'm pretty sure that issues were automatically linked by GitHub at some point, and I even reversed my approach of manual linking in d1c7897 because of that.
Some investigation needs to be done, as there is no sense to go back, if this is a planned feature (that was maybe tested?).
Alternatively, there might exist a tool to do it automatically. Or, I can write it myself.
There is a check that stops committing a zettel if there is no output in git diff
(i.e. there were no changes between the recent version). This is good when I just enter and exit (with pyzet edit
) an already committed zettel without adding a thing.
But when pre-commit rejects committing a zettel, it is already staged. So, if I enter and exit the zettel with pyzet edit
it won't be committed.
I see a solution in checking for git diff --staged
if git diff
is empty. This should also check for this edge case. Another solution is to unstage zettel when pre-commit rejects it, but it's probably harder to implement. IDK at this point, and will decide later.
E.g. it can use git remote -v
to obtain a base URL, and then generate a link to a given zettel.
It can be either a part of pyzet show
or I can add a new command for it. Theoretically, Python can tell the browser to open a new card, but it can be hard with some configurations like WSL.
The current behavior of pyzet grep
is that it always uses --ignore-case
flag in git grep
which may be the most common use case, but at the same time it disables the ability of turning it off.
Instead, it should be an easily accessible -i
/ --ignore-case
flag that can be used in pyzet grep
directly. A shell alias can be then defined to always calls pyzet grep -i
for easy access to it.
As in the title: pz add
creates a file with only #
at the beginning, so that's why a warning is raised, because it's not a well-formed title.
I don't like it, but it might be a reasonable simple solution, although not pretty. If something goes wrong during pyzet add
, you would like to see this empty zettel and warning is desired.
Maybe a way to go is to hide this warning only if there's an ongoing python process in progress of pyzet add
? Ideally, it should also check the ID of currently created zettel and hide the warning only if matches the one that shows a warning.
Ideally, it should print a list of all zettels that link to a given zettel.
During migration from hackmd, one of my notes caused the following error:
> pz add
INFO:root:20211028212144 was created
Traceback (most recent call last):
File "C:\Users\trivvz\repos\github.com\trivvz\pyzet\venv\Scripts\pz-script.py", line 33, in <module>
sys.exit(load_entry_point('pyzet', 'console_scripts', 'pz')())
File "c:\users\trivvz\repos\github.com\trivvz\pyzet\src\pyzet\main.py", line 112, in main
return add_zettel(config)
File "c:\users\trivvz\repos\github.com\trivvz\pyzet\src\pyzet\main.py", line 189, in add_zettel
zettel = get_zettel(zettel_path.parent)
File "c:\users\trivvz\repos\github.com\trivvz\pyzet\src\pyzet\zettel.py", line 39, in get_zettel
contents = file.readlines()
File "C:\Program Files\Python39\lib\codecs.py", line 322, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xed in position 7528: invalid continuation byte
The link to the problematic note:
https://hackmd.io/d4GbNi4sR7yf7YQ-HZoHng
I found the root cause: 😉
So it seems that UTF-8 doesn't like emojis. Probably there's a simple workaround, so this can be fixed, I hope.
By default, git grep
supports only basic POSIX regex which is very limited, so I don't think that this is a good default in such a use case.
git grep
supports either extended POSIX or Perl-compatible regex.
Currently, this behavior can be forced by passing additional flags after --
:
pyzet grep foo bar -- -E
pyzet grep foo bar -- -P
One of them should be the default, but two others are probably also nice to have, so we need some more sophisticated logic on pyzet
side.
Probably I need to read more about differences between these two, and make this decision. Perl-compatible regex needs an optional Git compile-time dependency, so it may be a less portable solution.
The flag -b
/ --initial-branch
from git init
can be reused here.
It will also stop a warning from displaying if the user hasn't configured the default branch in their Git config.
It should be another simple interface to a Git command without any dedicated options.
One use case is adding a remote after initializing a new zet repo, e.g.:
pyzet remote add origin https://some-git-hosting/username/zet
I also plan another more complicated feature for displaying a direct Git remote link to a given zettel which is described in #20.
Probably via zettel title?
Because IDs tend to be very similar starting with a year, and then a month.
But all commands that interact with zettels only accept IDs. So it would require some more effort, probably.
OSError: [WinError 145] The directory is not empty
exception is raised right now.
The desired output is a standard Markdown link:
* [20220227205040](../20220227205040) -- <zettel title>
It can be just another flag to pyzet list
, which could be run as a Vim bang command like this:
:.!pyzet list --new-flag | grep <zettel ID or zettel title>
Often, I want to link the last zettel, and tail
is easier to use:
:.!pyzet list --new-flag | tail -1
Alternatively, it can be a new command that takes zettel ID as its input.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.