-
Notifications
You must be signed in to change notification settings - Fork 238
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Improve Batch iterator variable recognizing #348
Conversation
I don't know whether it's worth the complex to fix for loop variables, I will need some time to understand the code. @echo off
::out of tokens range
for /f "tokens=1 usebackq delims= " ^
%%a ^
in (
'1 2
3 4'
) ^
do ^
if "%~1" == "" ^
echo %%a %%b %%c %%~dpnd
:: . as text
for /L %%a in (1, 1, 3) do for /L %%j in (5, 1, 6) do (
echo 10.1.%%a.%%j
echo 10.1.%%~a.%%j
)
|
Besides the breaking line case, one more example: for %%^" in ("cmd.exe") do (
echo %%^"
echo %%^~^d^p^n^x^"
) Although it is not a usual case, but it is valid. |
BTW: reg delete "HKCR\.fdf" /f
reg delete "HKCR\AppID\{GUID}" /f
|
GetCurrentBlockStart() can be replaced with following changes. if (startPos != 0) {
// backtrack to the line starts outermost command.
BacktrackToStart(styler, BatchLineStateLineContinuation | (0xff << 8), startPos, length, initStyle);
}
StyleContext sc(startPos, length, initStyle, styler); after backtracking, other line states no longer make sense. |
Updated: Left: |
85cec18
to
f6e3699
Compare
Please rebase the code, I update variable highlighting in be819e7. I think with open('test.bat', 'w', newline='\r\n') as fd:
tokens = ','.join(map(str, range(1, 31)))
items = ' '.join(map(str, range(1, 35)))
fd.write(f"""@echo off
SetLocal EnableExtensions EnableDelayedExpansion
for /F "tokens={tokens},*" %%! ^
in ("{items}") ^
do (
""")
escape_map = {
'%': '%',
')': '^)',
'&': '^&',
'|': '^|',
'<': '^<',
'>': '^>',
}
lines = []
for code in range(33, 127):
ch = chr(code)
esc = escape_map.get(ch, '')
if esc:
if esc[0] == '^':
lines.append(f'echo {esc}: %%{esc}')
else:
lines.append(f':: invalid {esc}')
elif ch == '!':
lines.append(f'echo ^^!: %%!')
elif ch == '^':
lines.append(f'echo ^^: %%^^')
else:
lines.append(f'echo {ch}: %%{ch}')
fd.write('\t')
fd.write('\n\t'.join(lines))
fd.write("\n)\n") and the generated result: @echo off
SetLocal EnableExtensions EnableDelayedExpansion
for /F "tokens=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,*" %%! ^
in ("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34") ^
do (
echo ^^!: %%!
echo ": %%"
echo #: %%#
echo $: %%$
:: invalid %
echo ^&: %%^&
echo ': %%'
echo (: %%(
echo ^): %%^)
echo *: %%*
echo +: %%+
echo ,: %%,
echo -: %%-
echo .: %%.
echo /: %%/
echo 0: %%0
echo 1: %%1
echo 2: %%2
echo 3: %%3
echo 4: %%4
echo 5: %%5
echo 6: %%6
echo 7: %%7
echo 8: %%8
echo 9: %%9
echo :: %%:
echo ;: %%;
echo ^<: %%^<
echo =: %%=
echo ^>: %%^>
echo ?: %%?
echo @: %%@
echo A: %%A
echo B: %%B
echo C: %%C
echo D: %%D
echo E: %%E
echo F: %%F
echo G: %%G
echo H: %%H
echo I: %%I
echo J: %%J
echo K: %%K
echo L: %%L
echo M: %%M
echo N: %%N
echo O: %%O
echo P: %%P
echo Q: %%Q
echo R: %%R
echo S: %%S
echo T: %%T
echo U: %%U
echo V: %%V
echo W: %%W
echo X: %%X
echo Y: %%Y
echo Z: %%Z
echo [: %%[
echo \: %%\
echo ]: %%]
echo ^^: %%^^
echo _: %%_
echo `: %%`
echo a: %%a
echo b: %%b
echo c: %%c
echo d: %%d
echo e: %%e
echo f: %%f
echo g: %%g
echo h: %%h
echo i: %%i
echo j: %%j
echo k: %%k
echo l: %%l
echo m: %%m
echo n: %%n
echo o: %%o
echo p: %%p
echo q: %%q
echo r: %%r
echo s: %%s
echo t: %%t
echo u: %%u
echo v: %%v
echo w: %%w
echo x: %%x
echo y: %%y
echo z: %%z
echo {: %%{
echo ^|: %%^|
echo }: %%}
echo ~: %%~
)
|
f0bc77a
to
2d2fe4c
Compare
Updated, and tested with the attached cases and many 2 special cases was found: for /F "tokens=1-31,*" %%^" ^
in ("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34") ^
do (
echo ": %%"
echo ": %%^"
echo ^": %%^"
) I don't know why it is not variable in for /f "tokens=%msys2_shiftCounter%,* delims=,;= " %%i in ("!msys2_full_cmd!") do set SHELL_ARGS=%%j Dynamic tokens. Should all possible ones be treated as variables or not? |
I seems we to partial revert my previous commit be819e7, especial changes to
Sine we don't expand variables, stick with commas is a simple choice. |
I just tested, |
In the example, only |
Also, both |
Updated code in 398ffe1, |
Working on different branches for the same feature always generates conflicts. It would take time to resolve the conflicts, reconstruct codes, and redo tests. |
I'm sorry for that, I'm going to work on issue #33. |
Appreciate! I'm refactoring my previous |
efe331b
to
0076f92
Compare
More cases are explored and covered. |
I think the code can be simplified:
@echo off
for /f "tokens=1,3" %%A in ("1 2 3 4 5 6 7 8 9") do echo %%A %%B %%C %%D %%E %%F
for /f "tokens=1,3*" %%A in ("1 2 3 4 5 6 7 8 9") do echo %%A %%B %%C %%D %%E %%F
for /f "tokens=1-2,3*" %%A in ("1 2 3 4 5 6 7 8 9") do echo %%A %%B %%C %%D %%E %%F output
|
I thought about it, and chose
It is, after keyword
for ^
/f "Tokens=2" %%a in ("1 2 3 4 5") do (
echo 10.1.1.%%a
) This special case works. Thanks to we are not going to implement a real batch file interpreter, not all quirky cases need to be covered. Is there any failures by current solution?
I don't understand. Seems a total regenerating is needed. I'm trying to understand your suggestions, but not sure if I can catch up with you ... |
DetectBatchVariable has too many parameters, and you introduced a global variable (which should be avoid). |
I'm not experienced in C++. I'll have a try. |
0076f92
to
f01433d
Compare
Rebased and refactored. |
f01433d
to
0e20d50
Compare
New conflict is resolved. |
Thanks for the update. I feel it's not urgently to improve/fix highlighting for |
The batch lexer has been better than ever since the recent commits (#332).
This one focuses on improving the iterator like variable recognizing.
Here is the test cases:
Before and After:
