Skip to content

Commit 57172d2

Browse files
committed
💥 Rewrite by OOP
1 parent d546f9b commit 57172d2

File tree

18 files changed

+463
-685
lines changed

18 files changed

+463
-685
lines changed

.pre-commit-config.yaml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ exclude: ^templates/
33

44
repos:
55
- repo: https://github.com/pre-commit/pre-commit-hooks
6-
rev: v5.0.0
6+
rev: v6.0.0
77
hooks:
88
- id: check-added-large-files
99
- id: fix-byte-order-marker
@@ -39,7 +39,7 @@ repos:
3939
args:
4040
- --msg-filename
4141
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
42-
rev: 3.2.1
42+
rev: 3.4.0
4343
hooks:
4444
- id: editorconfig-checker
4545
- repo: https://github.com/jumanjihouse/pre-commit-hooks
@@ -74,18 +74,13 @@ repos:
7474
- id: markdownlint-cli2
7575
additional_dependencies:
7676
- markdown-it-texmath
77-
- repo: https://github.com/Freed-Wu/pre-commit-hooks
78-
rev: 0.0.11
79-
hooks:
80-
- id: update-CITATION.cff
81-
- id: update-pyproject.toml
8277
- repo: https://github.com/astral-sh/ruff-pre-commit
83-
rev: v0.11.13
78+
rev: v0.13.0
8479
hooks:
85-
- id: ruff
80+
- id: ruff-check
8681
- id: ruff-format
8782
- repo: https://github.com/kumaraditya303/mirrors-pyright
88-
rev: v1.1.401
83+
rev: v1.1.405
8984
hooks:
9085
- id: pyright
9186

README.md

Lines changed: 62 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -39,92 +39,108 @@
3939
Python REPL plugin for automatic time tracking and metrics generated from your
4040
programming activity.
4141

42-
![screenshot](https://github.com/user-attachments/assets/b745d591-60ac-462e-9485-1828914706a1)
42+
![screen](https://github.com/user-attachments/assets/4e337cae-06a7-4164-be83-c7b73e8a0f63)
4343

44-
Supported REPLs:
44+
## REPLs
4545

46-
- [x] [python](https://github.com/python/cpython):
47-
- executes
48-
[`str(sys.ps1)`](https://docs.python.org/3/library/sys.html#sys.ps1) after
49-
every input.
50-
- configure file:
51-
[`$PYTHON_STARTUP`](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONSTARTUP).
46+
### [python](https://github.com/python/cpython)
47+
48+
[`$PYTHON_STARTUP`](https://docs.python.org/3/using/cmdline.html#envvar-PYTHONSTARTUP):
5249

5350
```python
54-
from repl_python_wakatime.python import install_hook
51+
import sys
52+
53+
from repl_python_wakatime.backends.wakatime import Wakatime
54+
from repl_python_wakatime.frontends.python import Python
5555

56-
install_hook()
56+
sys.ps1 = Python(Wakatime())
5757
```
5858

59-
- [x] [ptpython](https://github.com/prompt-toolkit/ptpython):
60-
- executes `get_ptpython().get_output_prompt()` after every output.
61-
- configure file: `.../ptpython/config.py`. `...` depends on OS.
59+
### [ptpython](https://github.com/prompt-toolkit/ptpython)
60+
61+
`${XDG_CONFIG_HOME:-$HOME/.config}/ptpython/config.py`:
6262

6363
```python
64-
from ptpython.repl import PythonRepl
65-
from repl_python_wakatime.ptpython import install_hook
64+
from repl_python_wakatime.backends.wakatime import Wakatime
65+
from repl_python_wakatime.frontends.ptpython import Ptpython
6666

6767

6868
def configure(repl: PythonRepl) -> None:
69-
install_hook(repl)
69+
repl.all_prompt_styles[repl.prompt_style] = Ptpython(
70+
Wakatime(), repl.all_prompt_styles[repl.prompt_style]
71+
)
7072
```
7173

72-
- [x] [ipython](https://github.com/ipython/ipython):
73-
- executes
74-
`c.TerminalInteractiveShell.prompts_class(shell).out_prompt_tokens()` after
75-
every output.
76-
- configure file: `~/.ipython/profile_default/ipython_config.py`.
74+
### [ipython](https://github.com/ipython/ipython)/[ptipython](https://github.com/prompt-toolkit/ptpython)
75+
76+
`~/.ipython/profile_default/ipython_config.py`:
7777

7878
```python
79-
from repl_python_wakatime.iptpython import install_hook
79+
from IPython.terminal.prompts import ClassicPrompts
80+
from repl_python_wakatime.backends.wakatime import Wakatime
81+
from repl_python_wakatime.frontends.ipython import Ipython
8082

81-
install_hook(c)
83+
c.TerminalInteractiveShell.prompts_class = lambda *args, **kwargs: Ipython(
84+
Wakatime(), ClassicPrompts(*args, **kwargs)
85+
)
8286
```
8387

84-
- [x] [gdb](https://sourceware.org/gdb/):
88+
### [gdb](https://sourceware.org/gdb/)
8589

8690
Your `gdb` must be compiled with
8791
[python port](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Python.html).
8892

8993
`~/.config/gdb/gdbinit`:
9094

9195
```gdb
92-
source /the/path/of/repl_python_wakatime/gdb.py
96+
source ~/.config/gdb/gdbinit.py
9397
```
9498

95-
See [GDB Hooks](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Hooks.html)
96-
to know more.
99+
`~/.config/gdb/gdbinit.py`:
100+
101+
```python
102+
from repl_python_wakatime.backends.wakatime import Wakatime
103+
from repl_python_wakatime.frontends.gdb import StopHook
97104

98-
Use environment variables `HOOK_NAMES=hook1:hook2` to defines which
99-
[hook](#configure) will be used.
105+
StopHook(Wakatime())
106+
```
100107

101-
- [x] [ptipython](https://github.com/prompt-toolkit/ptpython): Same as
102-
[ipython](https://github.com/ipython/ipython).
103108
- [ ] [bpython](https://github.com/bpython/bpython)
104109
- [ ] [xonsh](https://github.com/xonsh/xonsh)
105-
- [ ] [mypython](https://github.com/asmeurer/mypython): Won't fix.
106-
- configure file: non-exist.
110+
- [ ] [mypython](https://github.com/asmeurer/mypython): won't fix due to no any
111+
configuration.
112+
- [ ] vim/neovim with python support: see
113+
[vim-wakatime](https://github.com/wakatime/vim-wakatime)
114+
115+
## Hooks
107116

108-
`install_hook()` must be after the customization of the prompt string and best
109-
at the end of file.
117+
- [x] [wakatime](https://wakatime.com/)
118+
- [x] [codestats](https://codestats.net/)
119+
- [ ] [codetime](https://codetime.dev/)
120+
- [ ] [rescuetime](https://www.rescuetime.com/)
110121

111-
## Configure
122+
You can use many hooks at the same time:
112123

113124
```python
114-
from repl_python_wakatime.python import install_hook
125+
from repl_python_wakatime.backends.codestats import CodeStats
126+
from repl_python_wakatime.backends.wakatime import Wakatime
127+
from repl_python_wakatime.frontends.python import Python
115128

116-
install_hook(hook_function, args, kwargs)
129+
Python(Wakatime() | CodeStats()).install()
117130
```
118131

119-
will execute `hook_function(*args, **kwargs)` after every output/input. Other
120-
REPLs are similar. Currently, `hook_function` can be:
132+
## APIs
133+
134+
You can use this project to statistic the time of using any programs. Such as,
135+
[translate-shell](https://github.com/Freed-Wu/translate-shell/) is a translating
136+
program:
121137

122-
- `repl_python_wakatime.hooks.wakatime.wakatime_hook()`: By default.
123-
- `repl_python_wakatime.hooks.codestats.codestats_hook()`: for [codestats](https://codestats.net/)
124-
- Create your hooks for other similar projects, such as:
125-
- [codetime](https://codetime.dev/)
126-
- [rescuetime](https://www.rescuetime.com/)
127-
- ...
138+
```python
139+
from repl_python_wakatime.backends.wakatime import Wakatime
140+
141+
# after each translating
142+
Wakatime(language="translate-shell", category="translating")()
143+
```
128144

129145
## Similar projects
130146

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
r"""Backends
2+
============
3+
"""
4+
5+
import os
6+
from dataclasses import dataclass
7+
from pathlib import Path
8+
from typing import Self
9+
10+
11+
@dataclass
12+
class Hook:
13+
r"""Each frontend should pass its name and language. Such as:
14+
15+
Ptpython(frontend="ptpython", language="python", category="coding")
16+
Gdb(frontend="gdb", language="gdb", category="debugging")
17+
"""
18+
19+
frontend: str = "python"
20+
language: str = "python"
21+
category: str = "coding"
22+
hooks: tuple[Self, ...] = ()
23+
24+
@property
25+
def plugin(self) -> str:
26+
"""Plugin. ``plugin`` must be the format of ``repl-REPL_NAME-wakatime``
27+
to let wakatime detect correctly.
28+
29+
:param self:
30+
:rtype: str
31+
"""
32+
if self.category == "coding":
33+
return f"repl-{self.frontend}-{self.__class__.__name__.lower()}"
34+
return f"{self.language}-{self.__class__.__name__.lower()}"
35+
36+
@property
37+
def language_type(self) -> str:
38+
return f"Terminal ({self.language})"
39+
40+
@staticmethod
41+
def get_project(
42+
filenames: tuple[str, ...] = (".git/",),
43+
) -> str:
44+
"""Get project. Its function is like ``git rev-parse --show-toplevel``.
45+
46+
use current directory as a fallback.
47+
48+
:param filenames:
49+
:type filenames: tuple[str, ...]
50+
"""
51+
cwd = Path(os.getcwd())
52+
project = cwd
53+
for parent in project.parents:
54+
for filename in filenames:
55+
if (parent / filename).exists():
56+
return project.name
57+
return cwd.name
58+
59+
def __or__(self, hook: Self) -> "Hook":
60+
return Hook(hooks=(self, hook))
61+
62+
def __call__(self) -> None:
63+
r"""Run hook"""
64+
for hook in self.hooks:
65+
hook()

0 commit comments

Comments
 (0)