Skip to content

Commit d739d3f

Browse files
committed
fix #192 fix #193
1 parent 45bb8d5 commit d739d3f

File tree

6 files changed

+42
-8
lines changed

6 files changed

+42
-8
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ jobs:
666666
shell: powershell
667667
- name: Test CMD shell failure
668668
run: |
669-
uv run pytest ./tests/shellcompletion/test_shell_resolution.py::test_get_win_shell_failure
669+
uv run pytest --cov-append ./tests/shellcompletion/test_shell_resolution.py::test_get_win_shell_failure
670670
shell: cmd
671671
- name: Store coverage files
672672
uses: actions/upload-artifact@v4

doc/source/changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Change Log
77
v3.1.0 (2024-03-xx)
88
===================
99

10+
* Fixed `fish completion installs should respect XDG_CONFIG_HOME <https://github.com/django-commons/django-typer/issues/193>`_
11+
* Fixed `zsh completion installs should respect ZDOTDIR <https://github.com/django-commons/django-typer/issues/192>`_
1012
* Implemented `Support Django 5.2 <https://github.com/django-commons/django-typer/issues/188>`_
1113
* Implemented `Switch poetry -> uv <https://github.com/django-commons/django-typer/issues/185>`_
1214
* Implemented `Require tests to pass before release action runs. <<https://github.com/django-commons/django-typer/issues/173>`_

src/django_typer/shells/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ def uninstall(self):
237237
Deriving classes must implement this method to uninstall the completion script.
238238
"""
239239

240+
@abstractmethod
241+
def get_user_profile(self) -> Path:
242+
"""
243+
Most shells have a profile script that is sourced when the interactive shell
244+
starts. Deriving classes should implement this method to return the location
245+
of that script.
246+
"""
247+
240248
def process_rich_text(self, text: str) -> str:
241249
"""
242250
Removes rich text markup from a string if color is disabled, otherwise it

src/django_typer/shells/bash.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ class BashComplete(DjangoTyperShellCompleter):
4141
by default.
4242
"""
4343

44+
def get_user_profile(self) -> Path:
45+
"""
46+
Get .bashrc it is always located in the user's home directory.
47+
"""
48+
return Path.home() / ".bashrc"
49+
4450
@cached_property
4551
def install_dir(self) -> Path:
46-
install_dir = Path.home() / ".bash_completions"
52+
install_dir = self.get_user_profile().parent / ".bash_completions"
4753
install_dir.mkdir(parents=True, exist_ok=True)
4854
return install_dir
4955

@@ -84,7 +90,7 @@ def install(self) -> Path:
8490
assert self.prog_name
8591
Path.home().mkdir(parents=True, exist_ok=True)
8692
script = self.install_dir / f"{self.prog_name}.sh"
87-
bashrc = Path.home() / ".bashrc"
93+
bashrc = self.get_user_profile()
8894
bashrc_source = bashrc.read_text() if bashrc.is_file() else ""
8995
source_line = f"source {script}"
9096
if source_line not in bashrc_source:
@@ -100,7 +106,7 @@ def uninstall(self):
100106
if script.is_file():
101107
script.unlink()
102108

103-
bashrc = Path.home() / ".bashrc"
109+
bashrc = self.get_user_profile()
104110
if bashrc.is_file():
105111
bashrc_source = bashrc.read_text()
106112
bashrc.write_text(bashrc_source.replace(f"source {script}\n", ""))

src/django_typer/shells/fish.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from functools import cached_property
23
from pathlib import Path
34

@@ -36,9 +37,19 @@ class FishComplete(DjangoTyperShellCompleter):
3637
Fish does not support ansi control codes.
3738
"""
3839

40+
def get_user_profile(self) -> Path:
41+
"""
42+
Get the user's fish config file. It is located in the user's home directory by
43+
default unless the ``XDG_CONFIG_HOME`` environment variable is set.
44+
"""
45+
return (
46+
Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config"))
47+
/ "fish/config.fish"
48+
)
49+
3950
@cached_property
4051
def install_dir(self) -> Path:
41-
install_dir = Path.home() / ".config/fish/completions"
52+
install_dir = self.get_user_profile().parent / "completions"
4253
install_dir.mkdir(parents=True, exist_ok=True)
4354
return install_dir
4455

src/django_typer/shells/zsh.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,19 @@ class ZshComplete(DjangoTyperShellCompleter):
4444
by default.
4545
"""
4646

47+
def get_user_profile(self) -> Path:
48+
"""
49+
Get the user's .zshrc file. It is located in the user's home directory by
50+
default unless the ``ZDOTDIR`` environment variable is set.
51+
"""
52+
return Path(os.environ.get("ZDOTDIR", Path.home())) / ".zshrc"
53+
4754
@cached_property
4855
def install_dir(self) -> Path:
4956
"""
5057
The directory where completer scripts will be installed.
5158
"""
52-
install_dir = Path.home() / ".zfunc"
59+
install_dir = self.get_user_profile().parent / ".zfunc"
5360
install_dir.mkdir(parents=True, exist_ok=True)
5461
return install_dir
5562

@@ -60,7 +67,7 @@ def format_completion(self, item: CompletionItem) -> str:
6067
def install(self) -> Path:
6168
assert self.prog_name
6269
Path.home().mkdir(parents=True, exist_ok=True)
63-
zshrc = Path.home() / ".zshrc"
70+
zshrc = self.get_user_profile()
6471
zshrc_source = ""
6572
if zshrc.is_file():
6673
zshrc_source = zshrc.read_text()
@@ -94,7 +101,7 @@ def uninstall(self):
94101
if script.is_file():
95102
script.unlink()
96103

97-
zshrc = Path.home() / ".zshrc"
104+
zshrc = self.get_user_profile()
98105
if zshrc.is_file():
99106
zshrc_source = zshrc.read_text()
100107
zshrc.write_text(

0 commit comments

Comments
 (0)