diff --git a/changelog.md b/changelog.md index fa1d61d9..9642b374 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,8 @@ Upcoming (TBD) Bug Fixes -------- * Raise Boundary tunnel stabilization pause to 0.2 sec. +* Fix pathname completions not descending into directories. +* Fix pathname completions ignoring `~/` and `/` initial directories. Internal diff --git a/mycli/packages/filepaths.py b/mycli/packages/filepaths.py index ef9f770f..8a00e1c1 100644 --- a/mycli/packages/filepaths.py +++ b/mycli/packages/filepaths.py @@ -23,7 +23,7 @@ def list_path(root_dir: str) -> list[str]: for name in sorted(os.listdir(root_dir)): if name.startswith('.'): continue - elif os.path.isdir(name): + elif os.path.isdir(os.path.join(root_dir, name)): dirs.append(f'{name}/') # if .sql is too restrictive it can be made configurable with some effort elif name.lower().endswith('.sql'): @@ -85,7 +85,7 @@ def suggest_path(root_dir: str) -> list[str]: *list_path(os.curdir), ] - if root_dir[0] not in ('/', '~') and root_dir[0:2] != './': + if root_dir[0] not in ('/', '~') and root_dir[0:2] != './' and not os.path.dirname(root_dir): return list_path(os.curdir) if "~" in root_dir: diff --git a/test/pytests/test_filepaths.py b/test/pytests/test_filepaths.py index 97c69a51..32017de8 100644 --- a/test/pytests/test_filepaths.py +++ b/test/pytests/test_filepaths.py @@ -42,8 +42,7 @@ def test_default_socket_dirs_import_variants(monkeypatch: pytest.MonkeyPatch) -> assert windows.DEFAULT_SOCKET_DIRS == [] -def test_list_path_lists_sql_files_and_directories(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.chdir(tmp_path) +def test_list_path_lists_sql_files_and_directories(tmp_path: Path) -> None: (tmp_path / '.hidden.sql').write_text('select 1\n', encoding='utf-8') (tmp_path / 'visible.SQL').write_text('select 1\n', encoding='utf-8') (tmp_path / 'notes.txt').write_text('ignored\n', encoding='utf-8') @@ -90,8 +89,10 @@ def test_suggest_path_branches(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) nested = tmp_path / 'nested' nested.mkdir() (nested / 'inside.sql').write_text('select 1\n', encoding='utf-8') - assert filepaths.suggest_path(str(nested / 'missing.sql')) == ['inside.sql'] - assert filepaths.suggest_path('./nested/missing.sql') == ['inside.sql'] + (nested / 'child').mkdir() + assert filepaths.suggest_path(str(nested / 'missing.sql')) == ['inside.sql', 'child/'] + assert filepaths.suggest_path('./nested/missing.sql') == ['inside.sql', 'child/'] + assert filepaths.suggest_path('nested/') == ['inside.sql', 'child/'] def test_dir_path_exists(tmp_path: Path) -> None: diff --git a/test/pytests/test_smart_completion_public_schema_only.py b/test/pytests/test_smart_completion_public_schema_only.py index 070c7f3a..7811dc79 100644 --- a/test/pytests/test_smart_completion_public_schema_only.py +++ b/test/pytests/test_smart_completion_public_schema_only.py @@ -858,6 +858,28 @@ def test_source_eager_completion(completer, complete_event, tmp_path, monkeypatc raise AssertionError(error) +def test_source_completion_advances_into_nested_directories(completer, complete_event, tmp_path, monkeypatch): + monkeypatch.chdir(tmp_path) + nested = tmp_path / 'doc' / 'nested' + nested.mkdir(parents=True) + (nested / 'query.sql').touch() + special.register_special_command( + ..., + 'source', + '\\. ', + 'Execute commands from file.', + aliases=[special.SpecialCommandAlias('\\.', case_sensitive=False)], + ) + + text = 'source doc/' + result = list(completer.get_completions(Document(text=text, cursor_position=len(text)), complete_event)) + assert result == [Completion(text='doc/nested/', start_position=-4)] + + text = 'source doc/nested/' + result = list(completer.get_completions(Document(text=text, cursor_position=len(text)), complete_event)) + assert result == [Completion(text='doc/nested/query.sql', start_position=-11)] + + @pytest.mark.skipif(os.name == 'nt', reason='POSIX quoting expectations') def test_source_completion_quotes_paths_with_spaces(completer, complete_event, tmp_path, monkeypatch): monkeypatch.chdir(tmp_path)