นีโอวิม

วิธีสร้างคีย์แมปแบบกำหนดเองใน Neovim ด้วย Lua

เรียนรู้วิธีสร้างการเชื่อมโยงคีย์แบบกำหนดเองใน Neovim โดยใช้รันไทม์ Lua ในตัวที่เป็นตัวเลือก และทิ้ง VimScript ที่เก่าแก่และคลุมเครือไปเพื่อประโยชน์ของ Lua!

Neovim (หรือแม้แต่ Vim) เป็นซอฟต์แวร์ที่ยอดเยี่ยมสำหรับนักพัฒนาทุกคน ความสามารถในการสร้างการผูกคีย์แบบกำหนดเองและทำทุกอย่างได้
ข้อพิสูจน์ถึงความนิยมของ Vim และหากคุณเคยใช้ Vim มาก่อน คุณควร
ตระหนักถึงสิ่งที่เป็นไปได้ผ่านการผูกคีย์ Vim แบบกำหนดเองเช่นกัน

สำหรับผู้ที่ไม่ได้ฝึกหัด ความเปิดกว้างของ Vim ในการสร้างการเชื่อมโยงคีย์แบบกำหนดเองนั้น
แทบไม่มีการแข่งขันเลย ด้วยเหตุนี้ จินตนาการของคุณเท่านั้นที่เป็น
ขีดจำกัดของสิ่งที่คุณสามารถสร้างได้โดยใช้การผูกคีย์แบบกำหนดเอง

ผู้ใช้ Vim จำเป็นต้องมีความรู้เกี่ยวกับ Vimscript ในการทำงาน (ซึ่งเป็นภาษาสคริปต์ที่สร้างขึ้นสำหรับการกำหนดค่า Vim) มันไม่ใช่ภาษา
ที่หรูหราที่สุด และไม่มีการนำไปใช้ใดๆ นอกเหนือจาก Vim นอกจากนี้ สำหรับ
คุณหลายๆ คน การสละเวลาและความพยายามในการเลือกภาษาการเขียนโปรแกรมที่ซ้ำซ้อนอาจไม่เกิดประสิทธิผลเช่นกัน โชคดีที่ Neovim v0.5+ ทำให้ชุมชนได้รับการอัปเดตที่สำคัญให้ทดลองใช้ และนั่นคือรันไทม์ Lua ที่ฝังมาในตัว

รันไทม์เสริมของ Lua ยังเข้ากันได้แบบย้อนหลัง ซึ่งหมายความว่าคุณยังสามารถลองใช้รันไทม์เสริมได้จากภายใน Vimscript เราจะไม่พูดถึงวิธีการเขียนโค้ด Lua ภายใน Vimscript เนื่องจากอยู่นอกเหนือขอบเขตของบทความนี้ แต่อย่าลังเลที่จะอ้างอิงถึง Neovim-Lua Guide ที่น่าทึ่งนี้บน GitHub เพื่อเป็นข้อมูลอ้างอิงอย่างรวดเร็ว

หากสิ่งนั้นกระตุ้นความสนใจของคุณ และคุณต้องการเรียนรู้ต่อไปว่า
การสร้างปุ่มลัดแบบกำหนดเองใน Neovim เป็นประสบการณ์ที่น่าพึงพอใจได้อย่างไร โปรดอ่าน
ล่วงหน้า ส่วนที่เหลือของบทความจะเริ่มต้นด้วยการแนะนำสั้นๆ เกี่ยวกับรันไทม์ Lua
ที่เป็นตัวเลือก ตามด้วยการสร้างฟังก์ชัน Lua สำหรับการแมปปุ่มลัดที่กำหนดเอง และในตอนท้ายของเรื่องทั้งหมด เราจะแนะนำแหล่งข้อมูลเพิ่มเติมที่คุณอาจต้องการดูเพื่อเรียนรู้เกี่ยวกับรันไทม์ Lua ของ Neovim ให้ดียิ่งขึ้น

ขอแนะนำรันไทม์ Lua เสริม

ก่อนที่เราจะเข้าสู่บทความเพิ่มเติม เรามาแนะนำรันไทม์ Lua
ใน Neovim กันก่อน การมีแนวคิดบางอย่างจะช่วยให้เข้าใจได้ดีขึ้นว่าจะสร้างได้อย่างไรและทำอะไรได้บ้าง

อย่างที่กล่าวไปแล้ว Neovim เปิดตัวพร้อมชุดฟีเจอร์ที่มีประโยชน์บางอย่าง คุณลักษณะหนึ่ง
ที่ทำให้ Neovim โดดเด่นคือ Builtin API การเข้าถึง API และรันไทม์ Lua ทางโปรแกรมหมายความว่าคุณสามารถปล่อยให้จินตนาการของคุณโลดแล่นได้หากต้องการ

และขอแจ้งให้ทราบว่า เช่นเดียวกับไฟล์กำหนดค่าอื่นๆ ที่ใช้ในการแฮ็ก Neovim/Vim โค้ด Lua จะต้องอยู่ใน runtimepath ด้วย (ดู “:h rtp” สำหรับข้อมูลเพิ่มเติม) ไฟล์กำหนดค่าเหล่านี้ (ที่มีนามสกุล .lua) จะถูกวางไว้ภายในไดเร็กทอรี
ที่มีชื่อว่า lua และ Neovim จะจัดหาทุกอย่างภายในไดเร็กทอรี
นั้นเมื่อถูกเรียกใช้

โปรดทราบว่าตำแหน่งของ Neovim runtimepath จะแตกต่างกันไปขึ้นอยู่กับตัวเลือกระบบปฏิบัติการของคุณ ดังนั้น สำหรับผู้ใช้ Linux ให้ตรวจสอบว่าระบบปฏิบัติการของคุณเป็นไปตามข้อกำหนด
XDG Base Directory หรือไม่ จากนั้นไฟล์ Lua ควรจะอยู่ที่: $HOME/.config/nvim/lua . และผู้ใช้ Windows คนอื่นๆ คุณควรตรวจสอบไฟล์ Lua ที่ %LOCALAPPDATA%\nvim\lua

หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับตำแหน่งที่จะวางไฟล์กำหนดค่า โปรดดูส่วน
ตำแหน่งที่จะวางไฟล์ Lua” ของคู่มือ Neovim-Lua บน GitHub

ด้วยการแนะนำเล็กๆ น้อยๆ เกี่ยวกับรันไทม์ Lua ที่เป็นตัวเลือก เรามา
มาดูวิธีกำหนดค่าการเชื่อมโยงคีย์ Neovim ด้วย Lua กัน ในอีกไม่กี่
ส่วนถัดไป เราจะมาดูกัน โดยเขียนตัวอย่างฟังก์ชัน Lua ตามด้วย
wrapper ฟังก์ชันจริงใน Lua wrapper ฟังก์ชันนี้จะถูกใช้เพื่อสร้างการเชื่อมโยงคีย์แบบกำหนดเองของเราทุกที่และทุกเวลาที่จำเป็น

วิธีเขียนฟังก์ชัน Lua สำหรับการผูกคีย์ Neovim

ย้อนกลับไปในวันที่ Neovim ไม่ใช่อะไรเลย Vim ได้จัดเตรียมคำสั่ง remap (และ noremap สำหรับการรีแมปแบบไม่เรียกซ้ำ ) สำหรับการปรับแต่งและการแมปการโยงคีย์ใหม่ ด้วยเหตุนี้ จึงเป็นเรื่องปกติที่จะเห็นคำสั่ง nnoremap กระจัดกระจายไปทั่วไฟล์ .vimrc นี่คือไฟล์
ตัวอย่าง .vimrc ไฟล์หนึ่งที่ฉันเลือกมาจากอินเทอร์เน็ต ไฟล์มีขนาดใหญ่มาก (~1,200 บรรทัดของโค้ด!) เทอะทะและฝันร้ายที่ต้องรักษา

และนี่คือข้อมูลโค้ดเล็กๆ น้อยๆ ที่ฉันเลือกมาจากไฟล์ .vimrc ด้านบน

โชคดีสำหรับเรา Neovim มีฟังก์ชันตัวช่วยผ่าน API ในตัว
มีชื่อว่า nvim_set_keymap() ซึ่งผู้ใช้คาดว่าจะใช้ฟังก์ชันนี้
โดยตรงหรือโดยการห่อด้วยรหัส Lua แนะนำให้ใช้วิธีภายหลังเนื่องจากวิธีนี้เป็นไปได้ที่จะปฏิบัติตามแนวทางการเขียนโค้ดมาตรฐาน การใช้โค้ด Lua ควบคู่กับ Neovim API ยังช่วยในการแยกการกำหนดค่า ทำให้การบำรุงรักษาง่ายขึ้นมากและรักษาสุขภาพจิตของคุณให้สมบูรณ์

การใช้ฟังก์ชัน wrapper ยังช่วยให้แน่ใจว่าการกำหนดค่าเป็น “DRY” & “SOLID” การปฏิบัติตามแนวทางปฏิบัติมาตรฐานการพัฒนาทั่วไปดังกล่าวหมายความว่าการกำหนดค่าดูสะอาดตาและเป็นระเบียบเช่นกัน

แล้วการกำหนดค่า Neovim ทั่วไปจะมีลักษณะอย่างไรเมื่อใช้กับ Lua
ต่อไปนี้คือตัวอย่าง:

เมื่อดูแวบแรก รหัส Lua อาจดูละเอียดเกินไปแต่ก็ยังดีที่
คุณจะเห็นเร็วๆ นี้

ในข้อมูลโค้ด Lua ที่เราแชร์ด้านบน เราได้กำหนดฟังก์ชันที่เรียกว่า map() ยอมรับพารามิเตอร์สี่ตัว ได้แก่ :

  1. โหมด (เช่นเดียวกับในโหมด Vim เช่น โหมด ปกติ/แทรก)
  2. lhs (ปุ่มลัดแบบกำหนดเองที่คุณต้องการ)
  3. rhs (คำสั่งหรือปุ่มลัดที่มีอยู่เพื่อปรับแต่ง)
  4. เลือก (ตัวเลือกเพิ่มเติม เช่น ‹silent›/‹noremap› โปรดดูที่ :h map-arguments สำหรับข้อมูลเพิ่มเติม)

ตามค่าเริ่มต้น พารามิเตอร์ opts ของฟังก์ชัน map() ถูกกำหนดให้กับตาราง
{ noremap = true. ในการทำเช่นนั้น อนุญาตให้ใช้การแมปแบบซ้อนและแบบเรียกซ้ำได้ (โปรดดู :h map-commands สำหรับข้อมูลเพิ่มเติม) คุณสามารถขยายตาราง opts เพิ่มเติมด้วย map-arguments เพิ่มเติมได้ตามที่คุณต้องการ และที่แกนกลางของ wrapper คือฟังก์ชัน vim.api.nvim_set_keymap() ซึ่งยอมรับรายการพารามิเตอร์ที่กล่าวถึงข้างต้น

ฟังก์ชันนี้สามารถนำกลับมาใช้ใหม่ได้ทุกที่ที่คุณต้องการ ดังที่คุณเห็นใน
ต่อไปเราสามารถทำให้การกำหนดค่า Neovim ของเราเป็นโมดูลมากยิ่งขึ้น!

การใช้ฟังก์ชัน Lua ในไฟล์รันไทม์ Neovim

ฟังก์ชัน wrapper ที่เราใช้ในส่วนด้านบนช่วยในการปรับแต่ง
การแมป Vim เริ่มต้นใหม่ แต่การกำหนดฟังก์ชัน wrapper แล้วนำไปใช้ในไฟล์ init.lua ของเรานั้นไม่เป็นไปตามหลักการ DRY และ/หรือ SOLID เลย เพื่อให้การกำหนดค่าสอดคล้องกับแนวทางปฏิบัติมาตรฐานของนักพัฒนามากขึ้น เราจะใช้ โมดูล Lua การใช้โมดูล Lua ช่วยให้มั่นใจได้ว่ามีการแยกตรรกะอย่างชัดเจนในการกำหนดค่าของเรา

และหากคุณต้องการทบทวนวิธีสร้างโมดูล Lua สำหรับ Neovim โปรดดู
ส่วน “โมดูล” ของคู่มือ Neovim-Lua บน GitHub

ดังที่กล่าวไว้ ให้สร้าง “utils.lua ใต้ไดเรกทอรี “lua” ใน runtimepath ของคุณ
โมดูล Lua จะถูกระบุหากมีบรรทัดโค้ดต่อไปนี้:

การอธิบายโมดูล Lua นั้นอยู่นอกเหนือขอบเขตของบทความนี้เช่นกัน ดังนั้นอาจอ้างอิงถึงเอกสารประกอบ Lua 5.1 ที่ลิงก์ด้านบนเพื่อเป็นข้อมูลอ้างอิง

สำหรับกรณีการใช้งานของเรา โมดูล Lua ที่เรากำหนดไว้จะมี wrapper การทำงานสำหรับการเชื่อมโยงคีย์แบบกำหนดเอง ด้วยเหตุนี้เนื้อหาของโมดูล “utils.lua ของเราจะมีลักษณะดังนี้:

เนื่องจาก Neovim แหล่งที่มาและโหลดไฟล์ Lua ใดๆ ที่อยู่ภายใต้ไดเร็กทอรี `lua` ใน runtimepath ฟังก์ชัน map() ของเราจึงสามารถนำเข้าจากที่อื่นได้เช่นกัน ดังนั้น ตอนนี้คุณสามารถนำเข้า Wrapper ลงในไฟล์ “init.lua และใช้มันเพื่อสร้างการรีแมปได้ ด้วยเหตุนี้ คุณจึงสามารถรักษาไฟล์ให้สะอาด บำรุงรักษาได้ และโหลดได้รวดเร็ว

ต่อไปนี้คือวิธีที่คุณสามารถเขียนไฟล์ “init.lua” ใหม่ได้โดยการนำเข้าไฟล์ “map()
ฟังก์ชันจากโมดูล “utils

เมื่อโค้ดถูกแยกส่วนอย่างเหมาะสมแล้ว การบำรุงรักษาก็ไม่น่าจะน่าเบื่อ & โอกาสที่โค้ดจะพังก็น้อยลงมาก นอกจากนี้ หากคุณต้องการขยายฟังก์ชัน map() พื้นฐานของเรานั้นทำได้ง่ายเพียงแค่ทำการเปลี่ยนแปลงที่จำเป็นใน “utils” โมดูล!

อย่างที่กล่าวไป มีโอกาสเป็นไปได้ว่าหากคุณใช้ Neovim มาระยะหนึ่งแล้ว คุณยัง
ต้องย้ายการกำหนดค่าของคุณไปยังโค้ด Lua และคุณจะดีใจที่ได้ยินว่าผู้พัฒนา Neovim พยายามอย่างหนักเพื่อรักษาความเข้ากันได้แบบย้อนหลัง หากการเปลี่ยนแปลงการย้ายจาก Vimscript ไปเป็นโค้ด Lua สำหรับการกำหนดค่าที่มีอยู่ทำให้คุณรู้สึกไม่สบายใจ ก็ไม่ต้องกังวลไป คุณสามารถใช้รหัส Lua ภายใน Vimscript ได้เช่นกัน! หากต้องการทราบข้อมูลเพิ่มเติม โปรดดูที่ “:h heredocs” เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนี้

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

คำพูดสุดท้ายและสิ่งที่ต้องตั้งตารอ

รันไทม์ Lua ที่เป็นตัวเลือกภายใน Neovim นั้นมาจากสวรรค์และเป็นฟีเจอร์หนึ่งที่ทำให้ Neovim โดดเด่นเป็นพิเศษจาก Vim แต่เนื่องจากคุณสมบัติ & Neovim นั้นค่อนข้างใหม่ ทรัพยากรเกี่ยวกับคุณสมบัติเหล่านี้จึงหาได้ยาก ต่อไปนี้เป็นแหล่งข้อมูลบางส่วนที่คุณอาจต้องการดูว่าการกำหนดค่า Neovim กับ Lua ทำให้คุณสนใจหรือไม่

  1. คำแนะนำในการใช้ Lua ใน Neovim
  2. h: lua” สำหรับคำแนะนำที่ครอบคลุมเกี่ยวกับวิธีใช้ Lua ภายใน Neovim
  3. และปลั๊กที่ไร้ยางอายเล็กน้อยคุณสามารถใช้บล็อกของฉันเป็นแหล่งข้อมูลอ้างอิงได้เช่นกัน ฉันได้เขียนบทความหนึ่งที่แนะนำประโยชน์ของการใช้ Lua สำหรับ Neovim ใน Vim หรือ Neovim? นี่คือเหตุผลที่คุณควรใช้อย่างหลัง. ยังมีบทความดังกล่าวอีกมากมายที่จะตามมา ดังนั้นจับตาดูให้ดี

ฉันพลาดแหล่งข้อมูลที่เป็นประโยชน์อื่น ๆ หรือไม่? แจ้งให้เราทราบหากฉันทำ!

และเพื่อสรุปบทความนี้ คุณคิดอย่างไรกับการใช้ Lua เพื่อกำหนดค่า
Neovim คุณกำหนดค่าปัจจุบันใน Vimscript หรือ Lua หรือไม่ และคุณสังเกตเห็นความแตกต่างในขณะที่ใช้งานหรือไม่?

ส่ง DM มาหาฉันที่ "Twitter Jarmosan" หรืออีเมลตามที่คุณต้องการ