รูปแบบไวยากรณ์เป็นกลุ่มเพื่อเน้นอาร์กิวเมนต์คำหลักหลาม


17

ฉันกำลังดิ้นรนกับการเรียนรู้กลุ่ม regexps (ฉันไม่รู้ regexp อื่น ๆ ได้เป็นอย่างดีเช่นกัน) ดังนั้นปัญหาหลักคือการกำหนด regexp ที่จะจับคู่

some_function_call(simple_value, keyword=value)

คำสำคัญในตัวอย่างนี้

ดังนั้นควรจับคู่คำถ้ามันอยู่ใน parens และมีเครื่องหมายเท่ากับหลังจากนั้น

ปัญหาต่อไปคือวิธีการกำหนดไฟล์ไวยากรณ์ในกลุ่ม ฉันจะซาบซึ้งในความช่วยเหลือ แต่ไม่ควรเรียนรู้อย่างหนักดังนั้นฉันสามารถทำได้ด้วยตัวเอง

แก้ไขตามคำตอบฉันได้ทำความคุ้นเคยกับสคริปต์ไวยากรณ์ของตัวเองสำหรับหลาม รู้สึกอิสระที่จะลอง ป้อนคำอธิบายลิงก์ที่นี่


มีปัญหาแบบเปิดใน Github สำหรับการเน้นคำหลักที่จะรวมอยู่ในไฟล์ไวยากรณ์ Python ที่ทันสมัยที่สุดที่ฉันทราบ: github.com/hdima/python-syntax/issues/44คุณอาจต้องการตรวจสอบในภายหลัง หากคุณทราบวิธีการทำโปรดแจ้งให้ผู้คนที่นั่นทราบ (หรือส่งข้อความถึงฉันเพื่อให้ฉันสามารถสร้างคำขอดึง) สำหรับคุณลักษณะนี้ให้ทุกคนได้ใช้งาน
cbaumhardt

1
ใช่ฉันเป็นคนที่เปิดมัน
user1685095

คำตอบ:


12

ด้วยการตั้งค่าเหล่านี้:

syn region FCall start='[[:alpha:]_]\i*\s*(' end=')' contains=FCall,FCallKeyword
syn match FCallKeyword /\i*\ze\s*=[^=]/ contained
hi FCallKeyword ctermfg=yellow

ฉันเข้าใจ:

ป้อนคำอธิบายรูปภาพที่นี่

ที่นี่:

  1. ฉันกำหนดขอบเขตไวยากรณ์ภายในข้อโต้แย้งคำหลักที่สามารถพบได้ซึ่งจะเป็นการเรียกฟังก์ชั่น containsตัวเลือกที่ช่วยให้ฉันรังเรียกฟังก์ชัน
  2. ภายในภูมิภาคนั้นฉันจับคู่สตริงที่ทำจากตัวระบุที่ถูกต้อง ( \i*) ตามด้วย=แต่ไม่ใช่==เพื่อให้การทดสอบความเท่าเทียมกันไม่ตรงกัน

ด้วยการใช้ภูมิภาคต่างๆฉันจะสร้างการแข่งขันให้ได้มากที่สุดเท่าที่ฉันต้องการซึ่งจะมีความซับซ้อนมาก (เป็นไปไม่ได้?) ถ้าฉันไปเพื่อmatchแสดงออกด้วยการแสดงออกปกติ

ฉันเชื่อว่านิพจน์ทั่วไปที่ใช้ในการจับคู่การเรียกฟังก์ชันและคำหลักนั้นสามารถปรับปรุงได้ แต่การพิจารณาว่าอะไรถูกต้องใน Python 3นั่นไม่ใช่งานที่ฉันยินดีทำ

ฉันคิดว่าคุณสามารถใช้สิ่งนี้เพื่อเน้นการเรียกใช้ฟังก์ชันโดยใช้matchgroup:

syn region FCall matchgroup=FName start='[[:alpha:]_]\i*\s*(' end=')' contains=FCall,FCallKeyword
syn match FCallKeyword /\i*\ze\s*=[^=]/ contained
hi FCallKeyword ctermfg=yellow
hi FName ctermfg=blue

ป้อนคำอธิบายรูปภาพที่นี่


ฉันควรสร้างคำถามอื่น แต่คุณมีความคิดเกี่ยวกับวิธีการเน้นเฉพาะฟังก์ชั่นในตัว?
user1685095

@ user1685095 ฟังก์ชั่น Builtin มีการระบุไว้ออกมาในกลุ่มไวยากรณ์ในการเริ่มต้นpythonBuiltin syntax/python.vimแต่ก็ไม่เห็นความแตกต่างระหว่างการทำงานและ builtin ตัวแปร ( True, FalseและNoneยังอยู่ในpythonBuiltin) คุณอาจคัดลอกคำจำกัดความสำหรับการใช้งานของคุณ
muru

ฉันใช้ไวยากรณ์ที่ละเอียดมากขึ้นแล้วใช้ค่าเริ่มต้นเช่น hdima / python และ vim-polyglot พวกเขาทั้งหมดกำหนดฟังก์ชั่นในตัวเช่นคำหลักที่มีความสำคัญ ไม่เพียง แต่ฟังก์ชั่นในตัวเท่านั้นที่ถูกเน้น แต่เพียงตัวแปรที่มีชื่อและฟังก์ชั่นเดียวกันในโมดูลอื่นที่มีชื่อเดียวกันจะถูกเน้น เช่นเดียวกับquery(...).***filter***()ตัวกรองเป็นไฮไลต์ในขณะที่มันไม่ได้มีอะไรจะทำอย่างไรกับฟังก์ชั่นในตัวกรอง
user1685095

@ user1685095 เริ่มต้นsyntax.vimทำให้พวกเขาเป็นคำหลัก ดูgithub.com/vim/vim/blob/master/runtime/syntax/python.vim#L184
muru

1
@ user1685095 แปลก ฉันไม่มีsyntax/python.vimไฟล์เพิ่มเติม(เฉพาะค่าเริ่มต้นและฉันไม่เห็นพฤติกรรมที่คุณทำ: i.stack.imgur.com/LgF6F.pngและฉันเห็นด้วยกับคำจำกัดความของคำหลัก - มันเหมาะสมที่สุดและฉัน ไม่คิดว่าจะถูกจับคู่คำหลักในกรณีเช่นnonkeyword.keyword. ในฐานะที่เป็นตัวแปรทราบว่า builtins เหล่านี้เป็นตัวแปรที่พวกเขากำลังตัวแปรที่มีฟังก์ชั่นวัตถุและสามารถกำหนดให้เช่นเดียวกับตัวแปรอื่น ๆ . ป้องกันไม่มีอะไรที่คุณทำsorted = filterแล้วใช้sortedเช่นfilter.
muru

8

นี่คือที่ที่คุณสามารถเริ่มต้นจาก:

/([^,]\+,\s\(\w\+\)=.*)

เน่าเฟะ:

/(       start matching a (
[^,]\+   match multiple characters that are not ,
,\s      match a , and a space
\(       start a matching group
\w\+     match word characters
\)       end the matching group
=.*)      match an = and anything until the closing )

สิ่งนี้ต้องการการปรับปรุง แต่ให้ภาพรวมของวิธีที่คุณสามารถทำได้


6

นอกจากคำตอบ @ Nobe4 คุณสามารถทำสิ่งต่อไปนี้:

  • สร้างไฟล์ ~/.vim/after/syntax/python.vim
  • ใส่บรรทัดวิทยานิพนธ์ในไฟล์:

    syntax match PythonArg /(.*\,\s*\zs\w\+\ze\s*=.*)/
    hi PythonArg guibg=blue
    
  • ปรับตัวที่สองด้วยค่าที่คุณต้องการ

สิ่งนี้จะสร้างไฟล์ไวยากรณ์ที่จะเพิ่มการจับคู่ไวยากรณ์สำหรับอาร์กิวเมนต์ของคุณตามด้วย a =และตั้งค่าสไตล์ที่จะใช้ หัวข้อนี้:h mysyntaxfile-addน่าสนใจสำหรับคุณ

นอกจากนี้ฉันใช้ regex แตกต่างจากคำตอบอื่น ๆ นี่คือรายละเอียด (ฉันไม่รู้ว่าอันไหนดีกว่าดังนั้นคุณอาจต้องลอง):

(      Begin the pattern with a bracket
.*,    Look for any number of any character before a ,
\s*    Zero or more white spaces after the ,
\zs    Start the matching group (what will be highlighted)
\w\+   Match one or more word characters
\ze    End the matching group
\s*    Zero or more white spaces between your argument and the = sign
=      A literal = sign after your argument
.*)    Any number of any characters between your = sign and the closing bracket

ขอบคุณสำหรับความช่วยเหลือ ฉันไม่รู้ว่าฉันสามารถเพิ่มไวยากรณ์ที่กำหนดเองได้โดยไม่ต้องแก้ไขกฎที่มีอยู่ รูปแบบของคุณไม่ตรงกับอาร์กิวเมนต์คำหลักหากเป็นอาร์กิวเมนต์แรกในฟังก์ชัน ฉันจะพยายามแก้ไขด้วยตัวเอง (ตอนนี้ฉันกำลังเรียนรู้ regexps เพื่อทำสิ่งนั้น) ทันทีที่ฉันจะเรียนรู้วิธีการที่ฉันจะโพสต์ความคิดเห็น
user1685095

ฉันลอง regexp นี้ด้วยการค้นหาเสียงเรียกเข้าและฉันคิดว่ามันตรงกับคำสำคัญเพียงคำเดียวในการเรียกใช้ฟังก์ชัน ฉันต้องการมันเพื่อให้ตรงกับพวกเขาทั้งหมด '
user1685095

@ user1685095: ใช่คุณพูดถูกแบบของฉันไม่ดี ฉันจะพยายามปรับปรุงและแก้ไขคำตอบของฉัน
statox

3

ฉันพบว่าคำตอบของ @ Wolfieจับการเปิดโปงของ tuple เป็นคำหลักและยังมีปัญหาในการจับข้อโต้แย้งคำหลักของ linebroken

แรงบันดาลใจจาก regex ของเขาฉันมาด้วยต่อไปนี้เพื่อใส่ในpython.vimไฟล์ไวยากรณ์ของฉัน (จำไว้ว่าเดิมฉันใช้python.vimไฟล์ไวยากรณ์จากsheerun / vim-polyglot )

syn match pythonFunctionKeyword "\v\s{-}\zs\w+\ze\=(\=)@!(\_s)@!" display
syn cluster pythonExpression add=pythonFunctionKeyword
syn region pythonFunctionKwargs start=+(+ end=+)+ contains=@pythonExpression

และการแยก regex นั้นคล้ายกับคำตอบของ @ Wolfie มาก :

\v      set to very magic mode
\s{-}   capture whitespace, nongreedy
\zs     start of the match (what to actually highlight)
\w+     one or more alphanumeric character, underscore included
\ze     stop matching; anything after this is delimiting only
\=      one single equal sign
(\=)@!  ...not followed by another equal sign
(\_s)@! ...not followed by any whitespace or newline character

key = valueโปรดทราบว่านี้จะไม่สีอาร์กิวเมนต์คำหลักที่เขียนเป็น: ซึ่งผมคิดว่าเป็นสิ่งที่ดีเป็นที่ไปกับอย่างเป็นทางการ PEP-8 คำแนะนำช่องว่างสำหรับอาร์กิวเมนต์คำหลัก


2

เป็นของการเขียนคำตอบที่ได้รับการยอมรับยากจนไฮไลต์สำหรับสตริงภายในรายการอาร์กิวเมนต์ฟังก์ชั่นสำหรับผม (โดยสิ่งที่ขลังผมไม่ทราบ) ดังนั้นนี่คือรุ่นหวังว่าปลอดภัยมากขึ้นบนพื้นฐานของStatox หนึ่ง

syntax match PythonArg "\v[\(\,]\s{-}\zs\w+\ze\s{-}\=(\=)@!"
hi PythonArg ctermfg = 214 guifg = #ffaf00

ctermfgสำหรับเทอร์มินัลคอนโซลguifgสำหรับ gui แน่นอนว่าคุณสามารถเปลี่ยนสีเป็นสิ่งที่คุณต้องการได้ นี่เป็นรายการที่มีประโยชน์

และเช่นเคยคุณควรใส่สิ่งนี้ไว้ข้างใน ~/.vim/after/syntax/python.vim

สำหรับรายละเอียด regex ที่นี่คุณไป:

\v      set to very magic mode
[\(\,]  capture either a ( or a ,
\s{-}   capture whitespace, nongreedy
\zs     start of the match (what to actually highlight)
\w+     one or more alphanumeric character, underscore included
\ze     stop matching; anything after this is delimiting only
\s{-}   once again, capture whitespace.
\=      one single equal sign
(\=)@!  ...not followed by another equal sign

การตรวจสอบขั้นสุดท้ายจะหยุดการไฮไลต์จากการกำหนดสี คุณสามารถลบได้ถ้าต้องการ


ขออภัยคุณมาช้า ฉันได้ทำความสะอาดไฟล์ไวยากรณ์ให้กับตัวเองแล้ว
user1685095

ไม่เป็นไร; หากมีคนอื่นพบปัญหาเดียวกันฉันก็สามารถมองที่นี่ได้อย่างหวัง
Wolfie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.