Skip to content

Commit 230875f

Browse files
committed
Implement filename completion.
This will close issue bpython#40.
1 parent e94af94 commit 230875f

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

bpython/cli.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@
6060
from pygments.token import Token
6161
from bpython.formatter import BPythonFormatter, Parenthesis
6262

63-
# This for import completion
63+
# This for completion
6464
from bpython import importcompletion
65+
from glob import glob
6566

6667
# This for config
6768
from bpython.config import Struct, loadini, migrate_rc
@@ -495,6 +496,23 @@ def _callable_postfix(self, value, word):
495496
word += '('
496497
return word
497498

499+
def current_string(self):
500+
"""Return the current string.
501+
Note: This method will not really work for multiline strings."""
502+
inside_string = next_token_inside_string(self.s, self.inside_string)
503+
if inside_string:
504+
string = list()
505+
next_char = ''
506+
for (char, next_char) in zip(reversed(self.s),
507+
reversed(self.s[:-1])):
508+
if char == inside_string and next_char != '\\':
509+
return ''.join(reversed(string))
510+
string.append(char)
511+
else:
512+
if next_char == inside_string:
513+
return ''.join(reversed(string))
514+
return ''
515+
498516
def cw(self):
499517
"""Return the current word, i.e. the (incomplete) word directly to the
500518
left of the cursor"""
@@ -650,7 +668,7 @@ def complete(self, tab=False):
650668
self.list_win_visible = self._complete(tab)
651669
return
652670

653-
def _complete(self, unused_tab=False):
671+
def _complete(self, tab=False):
654672
"""Construct a full list of possible completions and construct and
655673
display them in a window. Also check if there's an available argspec
656674
(via the inspect module) and bang that on top of the completions too.
@@ -660,14 +678,26 @@ def _complete(self, unused_tab=False):
660678
self.argspec = None
661679

662680
cw = self.cw()
663-
if not (cw or self.argspec):
681+
cs = self.current_string()
682+
if not (cw or cs or self.argspec):
664683
self.scr.redrawwin()
665684
self.scr.refresh()
666685
return False
667686

668687
if not cw:
669688
self.matches = []
670689

690+
if cs and tab:
691+
self.matches = list()
692+
user_dir = os.path.expanduser('~')
693+
for filename in glob(os.path.expanduser(cs + '*')):
694+
if os.path.isdir(filename):
695+
filename += os.path.sep
696+
if cs.startswith('~'):
697+
filename = '~' + filename[len(user_dir):]
698+
self.matches.append(filename)
699+
return True
700+
671701
# Check for import completion
672702
e = False
673703
matches = importcompletion.complete(self.s, cw)
@@ -1531,11 +1561,11 @@ def tab(self):
15311561
self.print_line(self.s)
15321562
return True
15331563

1564+
self.complete(tab=True)
15341565
if not OPTS.auto_display_list and not self.list_win_visible:
1535-
self.complete(tab=True)
15361566
return True
15371567

1538-
cw = self.cw()
1568+
cw = self.current_string() or self.cw()
15391569
if not cw:
15401570
return True
15411571

0 commit comments

Comments
 (0)