@@ -108,6 +108,13 @@ def sorted_completions(completions):
108108 return list (sorted (completions , key = lambda x : x [0 ].lower ()))
109109
110110
111+ def int_or_float (string ):
112+ try :
113+ return int (string )
114+ except ValueError :
115+ return float (string )
116+
117+
111118def _settings ():
112119 return sublime .load_settings ("PackageDev.sublime-settings" )
113120
@@ -601,9 +608,7 @@ def value_completions(self, view, prefix, locations):
601608 typed_region = sublime .Region (value_region .begin (), point )
602609 typed = view .substr (typed_region ).lstrip ()
603610 # try to built the list of completions from setting's comment
604- completions = list (
605- self ._completions_from_comment (view , key , default , typed , prefix )
606- )
611+ completions = self ._completions_from_comment (view , key )
607612
608613 if not completions :
609614 if isinstance (default , bool ):
@@ -614,7 +619,7 @@ def value_completions(self, view, prefix, locations):
614619 completions [default ][0 ] += " (default)" # booleans are integers
615620 elif default :
616621 completions = [(
617- '{0 } \t default' .format (default ),
622+ "{ } \t {} (default)" .format (default , type ( default ). __name__ ),
618623 default
619624 )]
620625
@@ -628,16 +633,31 @@ def value_completions(self, view, prefix, locations):
628633 )
629634 # cursor already within quotes
630635 in_str = view .match_selector (point , 'string' )
631- l .debug ("Completing a string (%s) within a string (%s)" , is_str , in_str )
636+ l .debug ("completing a string (%s) within a string (%s)" , is_str , in_str )
632637
633638 if not in_str or not is_str :
634639 # jsonify completion values
635- completions = [(trigger , sublime .encode_value (value ))
636- for trigger , value in completions ]
640+ completions_tmp = []
641+ for trigger , value in completions :
642+ if isinstance (value , float ):
643+ # strip already typed text from float completions
644+ # because ST cannot complete past word boundaries
645+ # (e.g. strip `1.` of `1.234`)
646+ value_str = str (value )
647+ if value_str .startswith (typed ):
648+ offset = len (typed ) - len (prefix )
649+ completions .append ((
650+ '{0}\t float' .format (value ),
651+ value_str [offset :]
652+ ))
653+ else :
654+ completions_tmp .append ((trigger , sublime .encode_value (value )))
655+ completions = completions_tmp
637656 elif is_str and in_str :
638- # stringify values, just to be safe. Don't need quotation marks
639- completions = [(trigger , str (value ))
640- for trigger , value in completions ]
657+ # Strip completions of non-strings. Don't need quotation marks.
658+ completions = [(trigger , value )
659+ for trigger , value in completions
660+ if isinstance (value , str )]
641661 else :
642662 # We're within a string but don't have a string value to complete.
643663 # Complain about this in the status bar, I guess.
@@ -649,8 +669,8 @@ def value_completions(self, view, prefix, locations):
649669 # disable word completion to prevent stupid suggestions
650670 return sorted_completions (completions ), sublime .INHIBIT_WORD_COMPLETIONS
651671
652- def _completions_from_comment (self , view , key , default , typed , prefix ):
653- """Parse settings comments and return all possible values (generator) .
672+ def _completions_from_comment (self , view , key ):
673+ """Parse settings comments and return all possible values.
654674
655675 Many settings are commented with a list of quoted words representing
656676 the possible / allowed values. This method generates a list of these
@@ -661,35 +681,46 @@ def _completions_from_comment(self, view, key, default, typed, prefix):
661681 the view to provide completions for
662682 key (string):
663683 the settings key name to read comments from
664- default (any):
665- the default value of key
666- typed (string):
667- the value entered so far, which may differ from prefix if
668- user entered floating point numbers
669- prefix (string):
670- the completion prefix provided by ST.
671684
672685 Yields:
673686 list: [trigger, contents]
674687 The list representing one auto-completion item.
675688 """
676- is_float = isinstance (default , float )
677-
678- # TODO try backtick "quotes" first (less frequently used but more precise)
679- for match in re .finditer ('"([\.\w]+)"' , self .comments .get (key , '' )):
680- word , = match .groups ()
681- if is_float :
682- # provide completions for numbers which match the already
683- # entered value
684- if word .startswith (typed ):
685- # strip already entered '1.' from completions as ST doesn't
686- offset = len (typed ) - len (prefix )
687- yield ('{0} \t number' .format (word ), word [offset :])
689+ comment = self .comments .get (key , '' )
690+ if not comment :
691+ return
692+
693+ # must use list because "lists" as values are not hashable
694+ values = []
695+ for match in re .finditer ('`([^`\n ]+)`' , comment ):
696+ # backticks should wrap the value in JSON representation,
697+ # so we try to decode it
698+ value_str , = match .groups ()
699+ try :
700+ value = sublime .decode_value (value_str )
701+ except :
702+ value = value_str
703+ values .append (value )
704+
705+ for match in re .finditer ('"([\.\w]+)"' , comment ):
706+ # quotation marks either wrap a string, a numeric or a boolean
707+ # fall back to a str
708+ value , = match .groups ()
709+ if value == 'true' :
710+ value = True
711+ elif value == 'false' :
712+ value = False
688713 else :
689- yield (
690- '{0} \t string' .format (word ),
691- word
692- )
714+ try :
715+ value = int_or_float (value )
716+ except ValueError :
717+ pass # just use the string
718+ values .append (value )
719+
720+ completions = [("{} \t {}" .format (value , type (value ).__name__ ), value )
721+ for value in values ]
722+ l .debug ("compl %r" , completions )
723+ return sorted_completions (completions )
693724
694725 @staticmethod
695726 def _color_scheme_completions (view ):
0 commit comments