Skip to content

Commit 627360c

Browse files
authored
Merge pull request #322 from python-cmd2/tilde
Fixed how we complete ~
2 parents 4f63fdf + 083080b commit 627360c

File tree

2 files changed

+38
-20
lines changed

2 files changed

+38
-20
lines changed

cmd2.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,6 @@ def path_complete(text, line, begidx, endidx, dir_exe_only=False, dir_only=False
323323
if endidx == len(line) or (endidx < len(line) and line[endidx] != os.path.sep):
324324
add_trailing_sep_if_dir = True
325325

326-
add_sep_after_tilde = False
327-
328326
# Readline places begidx after ~ and path separators (/) so we need to extract any directory
329327
# path that appears before the search text
330328
dirname = line[prev_space_index + 1:begidx]
@@ -342,14 +340,18 @@ def path_complete(text, line, begidx, endidx, dir_exe_only=False, dir_only=False
342340
if not dirname:
343341
dirname = os.getcwd()
344342
elif dirname == '~':
345-
# If tilde was used without separator, add a separator after the tilde in the completions
346-
add_sep_after_tilde = True
343+
# If a ~ was used without a separator between text, then this is invalid
344+
if text:
345+
return []
346+
# If only a ~ was entered, then complete it with a slash
347+
else:
348+
return [os.path.sep]
347349

348350
# Build the search string
349351
search_str = os.path.join(dirname, text + '*')
350352

351-
# Expand "~" to the real user directory
352-
search_str = os.path.expanduser(search_str)
353+
# Expand "~" to the real user directory
354+
search_str = os.path.expanduser(search_str)
353355

354356
# Find all matching path completions
355357
path_completions = glob.glob(search_str)
@@ -376,9 +378,6 @@ def path_complete(text, line, begidx, endidx, dir_exe_only=False, dir_only=False
376378
# If it is a file and we are at the end of the line, then add a space
377379
if os.path.isfile(path_completions[0]) and endidx == len(line):
378380
completions[0] += ' '
379-
# If tilde was expanded without a separator, prepend one
380-
elif os.path.isdir(path_completions[0]) and add_sep_after_tilde:
381-
completions[0] = os.path.sep + completions[0]
382381

383382
completions.sort()
384383
return completions

tests/test_completion.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ def test_path_completion_cwd():
359359
completions_empty = path_complete(text, line, begidx, endidx)
360360

361361
# Run path complete with path set to the CWD
362-
cwd = os.getcwd()
362+
cwd = os.getcwd() + os.path.sep
363363
line = 'shell ls {}'.format(cwd)
364364
endidx = len(line)
365365
begidx = endidx - len(text)
@@ -382,29 +382,48 @@ def test_path_completion_doesnt_match_wildcards(request):
382382
# Currently path completion doesn't accept wildcards, so will always return empty results
383383
assert path_complete(text, line, begidx, endidx) == []
384384

385-
def test_path_completion_user_expansion():
385+
def test_path_completion_invalid_syntax():
386+
# Test a missing separator between a ~ and path
387+
text = ''
388+
line = 'shell fake ~Desktop'
389+
endidx = len(line)
390+
begidx = endidx - len(text)
391+
392+
assert path_complete(text, line, begidx, endidx) == []
393+
394+
def test_path_completion_just_tilde():
386395
# Run path with just a tilde
387396
text = ''
388-
if sys.platform.startswith('win'):
389-
line = 'shell dir ~{}'.format(text)
390-
else:
391-
line = 'shell ls ~{}'.format(text)
397+
line = 'shell fake ~'
392398
endidx = len(line)
393399
begidx = endidx - len(text)
394400
completions_tilde = path_complete(text, line, begidx, endidx)
395401

396-
# Run path complete on the user's home directory
397-
user_dir = os.path.expanduser('~')
402+
# Path complete should return a slash
403+
assert completions_tilde == [os.path.sep]
404+
405+
def test_path_completion_user_expansion():
406+
# Run path with a tilde and a slash
407+
text = ''
398408
if sys.platform.startswith('win'):
399-
line = 'shell dir {}'.format(user_dir)
409+
cmd = 'dir'
400410
else:
401-
line = 'shell ls {}'.format(user_dir)
411+
cmd = 'ls'
412+
413+
line = 'shell {} ~{}'.format(cmd, os.path.sep)
414+
endidx = len(line)
415+
begidx = endidx - len(text)
416+
completions_tilde_slash = path_complete(text, line, begidx, endidx)
417+
418+
# Run path complete on the user's home directory
419+
user_dir = os.path.expanduser('~') + os.path.sep
420+
line = 'shell {} {}'.format(cmd, user_dir)
402421
endidx = len(line)
403422
begidx = endidx - len(text)
404423
completions_home = path_complete(text, line, begidx, endidx)
405424

406425
# Verify that the results are the same in both cases
407-
assert completions_tilde == completions_home
426+
assert completions_tilde_slash == completions_home
408427

409428
def test_path_completion_directories_only(request):
410429
test_dir = os.path.dirname(request.module.__file__)

0 commit comments

Comments
 (0)