23
23
import re
24
24
import sys
25
25
import textwrap
26
- from typing import Dict , List , Optional , Pattern , Sequence , Set , Tuple
26
+ from typing import Dict , List , Match , Optional , Pattern , Sequence , Set , Tuple
27
27
28
28
# autogenerated by setuptools_scm
29
29
from ._version import __version__ as VERSION
@@ -680,18 +680,26 @@ def fix_case(word: str, fixword: str) -> str:
680
680
681
681
def ask_for_word_fix (
682
682
line : str ,
683
- wrongword : str ,
683
+ match : Match [ str ] ,
684
684
misspelling : Misspelling ,
685
685
interactivity : int ,
686
+ colors : TermColors ,
686
687
) -> Tuple [bool , str ]:
688
+ wrongword = match .group ()
687
689
if interactivity <= 0 :
688
690
return misspelling .fix , fix_case (wrongword , misspelling .data )
689
691
692
+ line_ui = (
693
+ f"{ line [:match .start ()]} "
694
+ f"{ colors .WWORD } { wrongword } { colors .DISABLE } "
695
+ f"{ line [match .end ():]} "
696
+ )
697
+
690
698
if misspelling .fix and interactivity & 1 :
691
699
r = ""
692
700
fixword = fix_case (wrongword , misspelling .data )
693
701
while not r :
694
- print (f"{ line } \t { wrongword } ==> { fixword } (Y/n) " , end = "" , flush = True )
702
+ print (f"{ line_ui } \t { wrongword } ==> { fixword } (Y/n) " , end = "" , flush = True )
695
703
r = sys .stdin .readline ().strip ().upper ()
696
704
if not r :
697
705
r = "Y"
@@ -709,7 +717,7 @@ def ask_for_word_fix(
709
717
r = ""
710
718
opt = [w .strip () for w in misspelling .data .split ("," )]
711
719
while not r :
712
- print (f"{ line } Choose an option (blank for none): " , end = "" )
720
+ print (f"{ line_ui } Choose an option (blank for none): " , end = "" )
713
721
for i , o in enumerate (opt ):
714
722
fixword = fix_case (wrongword , o )
715
723
print (f" { i } ) { fixword } " , end = "" )
@@ -743,30 +751,50 @@ def print_context(
743
751
print ("{} {}" .format (">" if i == index else ":" , lines [i ].rstrip ()))
744
752
745
753
754
+ def _ignore_word_sub (
755
+ text : str ,
756
+ ignore_word_regex : Optional [Pattern [str ]],
757
+ ) -> str :
758
+ if ignore_word_regex :
759
+ text = ignore_word_regex .sub (" " , text )
760
+ return text
761
+
762
+
746
763
def extract_words (
747
764
text : str ,
748
765
word_regex : Pattern [str ],
749
766
ignore_word_regex : Optional [Pattern [str ]],
750
767
) -> List [str ]:
751
- if ignore_word_regex :
752
- text = ignore_word_regex .sub (" " , text )
753
- return word_regex .findall (text )
768
+ return word_regex .findall (_ignore_word_sub (text , ignore_word_regex ))
769
+
770
+
771
+ def extract_words_iter (
772
+ text : str ,
773
+ word_regex : Pattern [str ],
774
+ ignore_word_regex : Optional [Pattern [str ]],
775
+ ) -> List [Match [str ]]:
776
+ return list (word_regex .finditer (_ignore_word_sub (text , ignore_word_regex )))
754
777
755
778
756
779
def apply_uri_ignore_words (
757
- check_words : List [str ],
780
+ check_matches : List [Match [ str ] ],
758
781
line : str ,
759
782
word_regex : Pattern [str ],
760
783
ignore_word_regex : Optional [Pattern [str ]],
761
784
uri_regex : Pattern [str ],
762
785
uri_ignore_words : Set [str ],
763
- ) -> None :
786
+ ) -> List [ Match [ str ]] :
764
787
if not uri_ignore_words :
765
- return
788
+ return check_matches
766
789
for uri in re .findall (uri_regex , line ):
767
790
for uri_word in extract_words (uri , word_regex , ignore_word_regex ):
768
791
if uri_word in uri_ignore_words :
769
- check_words .remove (uri_word )
792
+ # determine/remove only the first among matches
793
+ for i , match in enumerate (check_matches ):
794
+ if match .group () == uri_word :
795
+ check_matches = check_matches [:i ] + check_matches [i + 1 :]
796
+ break
797
+ return check_matches
770
798
771
799
772
800
def parse_file (
@@ -855,18 +883,18 @@ def parse_file(
855
883
# outside, it will still be a spelling error.
856
884
if "*" in uri_ignore_words :
857
885
line = uri_regex .sub (" " , line )
858
- check_words = extract_words (line , word_regex , ignore_word_regex )
886
+ check_matches = extract_words_iter (line , word_regex , ignore_word_regex )
859
887
if "*" not in uri_ignore_words :
860
- apply_uri_ignore_words (
861
- check_words ,
888
+ check_matches = apply_uri_ignore_words (
889
+ check_matches ,
862
890
line ,
863
891
word_regex ,
864
892
ignore_word_regex ,
865
893
uri_regex ,
866
894
uri_ignore_words ,
867
895
)
868
-
869
- for word in check_words :
896
+ for match in check_matches :
897
+ word = match . group ()
870
898
lword = word .lower ()
871
899
if lword in misspellings :
872
900
context_shown = False
@@ -878,7 +906,11 @@ def parse_file(
878
906
context_shown = True
879
907
print_context (lines , i , context )
880
908
fix , fixword = ask_for_word_fix (
881
- lines [i ], word , misspellings [lword ], options .interactive
909
+ lines [i ],
910
+ match ,
911
+ misspellings [lword ],
912
+ options .interactive ,
913
+ colors = colors ,
882
914
)
883
915
asked_for .add (lword )
884
916
0 commit comments