บทช่วยสอนโปรโตคอลเซิร์ฟเวอร์ภาษา: จาก VSCode ถึง Vim

เผยแพร่แล้ว: 2022-03-11

อาร์ติแฟกต์หลักของงานทั้งหมดของคุณน่าจะเป็นไฟล์ข้อความธรรมดา เหตุใดคุณจึงไม่ใช้ Notepad เพื่อสร้างมัน

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

ในบทช่วยสอนเกี่ยวกับโปรโตคอลเซิร์ฟเวอร์ภาษา เราจะสำรวจคำถามเหล่านี้เล็กน้อยและค้นหาว่าอะไรที่ทำให้โปรแกรมแก้ไขข้อความของเราใช้งานได้ ในท้ายที่สุด เราจะใช้เซิร์ฟเวอร์ภาษาพื้นฐานร่วมกับไคลเอ็นต์ตัวอย่างสำหรับ VSCode, Sublime Text 3 และ Vim ร่วมกัน

คอมไพเลอร์กับบริการด้านภาษา

เราจะข้ามไปที่การเน้นไวยากรณ์และการจัดรูปแบบในตอนนี้ ซึ่งได้รับการจัดการด้วยการวิเคราะห์แบบคงที่ ซึ่งเป็นหัวข้อที่น่าสนใจในตัวของมันเอง และเน้นที่คำติชมหลักที่เราได้รับจากเครื่องมือเหล่านี้ มีสองประเภทหลัก: คอมไพเลอร์และบริการภาษา

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

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

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

เดิมพันตัวแก้ไขข้อความสำหรับการเขียนโปรแกรม

ขอให้สังเกตว่าเรายังไม่ได้เรียกโปรแกรมแก้ไขข้อความเฉพาะออกมา มาอธิบายว่าทำไมด้วยตัวอย่าง

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

คุณสนับสนุนโปรแกรมแก้ไขโค้ด/ข้อความใดก่อน แล้วหลังจากนั้นล่ะ? คุณมีการต่อสู้ที่ยากเย็นแสนเข็ญเพื่อให้ผู้คนยอมรับมัน ดังนั้นคุณต้องการทำให้มันง่ายที่สุด คุณคงไม่อยากเลือกตัวแก้ไขที่ผิดและพลาดผู้ใช้ไป จะเป็นอย่างไรถ้าคุณอยู่ห่างจากผู้แก้ไขโค้ดและมุ่งความสนใจไปที่ความเชี่ยวชาญพิเศษของคุณ—ภาษาและคุณลักษณะของมัน

เซิร์ฟเวอร์ภาษา

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

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

โชคดีสำหรับเรา นี่ไม่ใช่สิ่งสมมุติ Microsoft ได้เริ่มต้นโดยการกำหนดโปรโตคอลเซิร์ฟเวอร์ภาษาแล้ว

เช่นเดียวกับแนวคิดที่ยอดเยี่ยมที่สุด แนวคิดนี้เกิดขึ้นจากความจำเป็นมากกว่าที่จะมองการณ์ไกล โปรแกรมแก้ไขโค้ดจำนวนมากได้เริ่มเพิ่มการรองรับคุณสมบัติภาษาต่างๆ แล้ว คุณลักษณะบางอย่างที่เอาต์ซอร์ซไปยังเครื่องมือของบุคคลที่สาม บางส่วนทำภายใต้ประทุนภายในบรรณาธิการ ปัญหาด้านความสามารถในการปรับขยายได้เกิดขึ้น และ Microsoft เป็นผู้นำในการแบ่งแยกสิ่งต่างๆ ใช่ Microsoft ปูทางที่จะย้ายคุณสมบัติเหล่านี้ออกจากตัวแก้ไขโค้ด แทนที่จะกักตุนไว้ใน VSCode พวกเขายังคงสร้างตัวแก้ไข ล็อกผู้ใช้—แต่พวกเขาปล่อยให้เป็นอิสระ

โปรโตคอลเซิร์ฟเวอร์ภาษา

โปรโตคอลเซิร์ฟเวอร์ภาษา (LSP) ถูกกำหนดในปี 2559 เพื่อช่วยแยกเครื่องมือและตัวแก้ไขภาษา ยังมีลายนิ้วมือ VSCode อยู่มากมาย แต่เป็นขั้นตอนสำคัญในทิศทางของการไม่เชื่อเรื่องพระเจ้าของบรรณาธิการ มาตรวจสอบโปรโตคอลกันสักหน่อย

ลูกค้าและเซิร์ฟเวอร์—คิดว่าเป็นผู้แก้ไขโค้ดและเครื่องมือภาษา—สื่อสารด้วยข้อความธรรมดา ข้อความเหล่านี้มีส่วนหัวเหมือน HTTP เนื้อหา JSON-RPC และอาจมาจากไคลเอนต์หรือเซิร์ฟเวอร์ โปรโตคอล JSON-RPC กำหนดคำขอ การตอบกลับ และการแจ้งเตือน และกฎพื้นฐานสองสามข้อที่อยู่รอบๆ คุณลักษณะสำคัญคือได้รับการออกแบบให้ทำงานแบบอะซิงโครนัส ดังนั้นไคลเอ็นต์/เซิร์ฟเวอร์จึงสามารถจัดการกับข้อความที่ไม่เป็นระเบียบและมีความเท่าเทียมกันในระดับหนึ่ง

กล่าวโดยย่อ JSON-RPC อนุญาตให้ไคลเอ็นต์ร้องขอโปรแกรมอื่นเพื่อเรียกใช้เมธอดที่มีพารามิเตอร์และส่งคืนผลลัพธ์หรือข้อผิดพลาด LSP สร้างขึ้นจากสิ่งนี้และกำหนดวิธีการที่มีอยู่ โครงสร้างข้อมูลที่คาดหวัง และกฎเพิ่มเติมสองสามข้อเกี่ยวกับธุรกรรม ตัวอย่างเช่น มีกระบวนการจับมือกันเมื่อไคลเอนต์เริ่มต้นเซิร์ฟเวอร์

เซิร์ฟเวอร์เป็นแบบเก็บสถานะและใช้เพื่อจัดการไคลเอ็นต์ทีละเครื่องเท่านั้น อย่างไรก็ตาม ไม่มีข้อจำกัดที่ชัดเจนในการสื่อสาร ดังนั้นเซิร์ฟเวอร์ภาษา จึงสามารถ ทำงานบนเครื่องอื่นที่ไม่ใช่ไคลเอนต์ได้ ในทางปฏิบัติ การตอบกลับแบบเรียลไทม์จะค่อนข้างช้า เซิร์ฟเวอร์ภาษาและไคลเอนต์ทำงานกับไฟล์เดียวกันและค่อนข้างพูดจาค่อนข้างดี

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

ประเภทข้อความ LSP

มีข้อความหลายกลุ่มที่กำหนดไว้ในโปรโตคอลเซิร์ฟเวอร์ภาษา พวกเขาสามารถแบ่งออกเป็น "ผู้ดูแลระบบ" และ "คุณสมบัติภาษา" อย่างคร่าวๆ ข้อความของผู้ดูแลระบบประกอบด้วยข้อความที่ใช้ในการจับมือไคลเอ็นต์/เซิร์ฟเวอร์ การเปิด/แก้ไขไฟล์ ฯลฯ ที่สำคัญนี่คือที่ที่ไคลเอ็นต์และเซิร์ฟเวอร์แชร์คุณลักษณะที่พวกเขาจัดการ แน่นอนว่า ภาษาและเครื่องมือต่างๆ นั้นมีคุณสมบัติที่แตกต่างกัน นอกจากนี้ยังช่วยให้มีการรับเลี้ยงบุตรบุญธรรมเพิ่มขึ้น Langserver.org ตั้งชื่อคุณลักษณะหลักจำนวนครึ่งโหลที่ไคลเอ็นต์และเซิร์ฟเวอร์ควรสนับสนุน ซึ่งจำเป็นอย่างน้อยหนึ่งรายการเพื่อสร้างรายการ

คุณลักษณะด้านภาษาเป็นสิ่งที่เราสนใจเป็นส่วนใหญ่ ในจำนวนนี้ มีคุณลักษณะหนึ่งที่ควรกล่าวถึงเป็นพิเศษ นั่นคือ ข้อความวินิจฉัย การวินิจฉัยเป็นหนึ่งในคุณสมบัติหลัก เมื่อคุณเปิดไฟล์ ส่วนใหญ่จะถือว่าไฟล์นี้ทำงาน บรรณาธิการของคุณควรบอกคุณว่ามีอะไรผิดปกติกับไฟล์หรือไม่ วิธีที่เกิดขึ้นกับ LSP คือ:

  1. ลูกค้าเปิดไฟล์และส่ง textDocument/didOpen ไปยังเซิร์ฟเวอร์
  2. เซิร์ฟเวอร์วิเคราะห์ไฟล์และส่งการแจ้งเตือน textDocument/publishDiagnostics
  3. ไคลเอนต์แยกวิเคราะห์ผลลัพธ์และแสดงตัวบ่งชี้ข้อผิดพลาดในตัวแก้ไข

นี่เป็นวิธีการรับข้อมูลเชิงลึกจากบริการภาษาของคุณ ตัวอย่างที่ใช้งานมากขึ้นคือการค้นหาข้อมูลอ้างอิงทั้งหมดสำหรับสัญลักษณ์ภายใต้เคอร์เซอร์ของคุณ สิ่งนี้จะเป็นดังนี้:

  1. ไคลเอนต์ส่ง textDocument/references ไปยังเซิร์ฟเวอร์ โดยระบุตำแหน่งในไฟล์
  2. เซิร์ฟเวอร์จะค้นหาสัญลักษณ์ ค้นหาข้อมูลอ้างอิงในไฟล์นี้และไฟล์อื่นๆ และตอบกลับด้วยรายการ
  3. ลูกค้าแสดงการอ้างอิงถึงผู้ใช้

เครื่องมือบัญชีดำ

เราสามารถเจาะลึกถึงรายละเอียดเฉพาะของ Language Server Protocol ได้ แต่ปล่อยให้เป็นไปสำหรับผู้ใช้ไคลเอนต์ เพื่อประสานแนวคิดของบรรณาธิการและการแยกเครื่องมือภาษา เราจะเล่นบทบาทของผู้สร้างเครื่องมือ

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

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

เซิร์ฟเวอร์ภาษา

ขั้นแรกให้เครื่องมือ เราจะอบสิ่งนี้ลงในเซิร์ฟเวอร์ภาษา เพื่อความเรียบง่าย นี่จะเป็นแอป Node.js แม้ว่าเราจะสามารถทำได้กับทุกเทคโนโลยีที่สามารถใช้สตรีมเพื่ออ่านและเขียนได้

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

 const getBlacklisted = (text) => { const blacklist = [ 'foo', 'bar', 'baz', ] const regex = new RegExp(`\\b(${blacklist.join('|')})\\b`, 'gi') const results = [] while ((matches = regex.exec(text)) && results.length < 100) { results.push({ value: matches[0], index: matches.index, }) } return results }

ตอนนี้ มาทำให้เป็นเซิร์ฟเวอร์กัน

 const { TextDocuments, createConnection, } = require('vscode-languageserver') const {TextDocument} = require('vscode-languageserver-textdocument') const connection = createConnection() const documents = new TextDocuments(TextDocument) connection.onInitialize(() => ({ capabilities: { textDocumentSync: documents.syncKind, }, })) documents.listen(connection) connection.listen()

ที่นี่เราใช้ vscode-languageserver ชื่อนี้ทำให้เข้าใจผิด เนื่องจากสามารถทำงานนอก VSCode ได้อย่างแน่นอน นี่เป็นหนึ่งใน "ลายนิ้วมือ" จำนวนมากที่คุณเห็นเกี่ยวกับที่มาของ LSP vscode-languageserver ดูแลโปรโตคอลระดับล่างและช่วยให้คุณมุ่งเน้นไปที่กรณีการใช้งาน ข้อมูลโค้ดนี้เริ่มต้นการเชื่อมต่อและเชื่อมโยงเข้ากับตัวจัดการเอกสาร เมื่อไคลเอ็นต์เชื่อมต่อกับเซิร์ฟเวอร์ เซิร์ฟเวอร์จะแจ้งว่าต้องการรับการแจ้งเตือนเมื่อมีการเปิดเอกสารข้อความ

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

 documents.onDidChangeContent(change => { connection.sendDiagnostics({ uri: change.document.uri, diagnostics: getDiagnostics(change.document), }) })

สุดท้าย เราเชื่อมโยงจุดต่างๆ ระหว่างเอกสารที่เปลี่ยนแปลง ตรรกะของเรา และการตอบสนองต่อการวินิจฉัย

 const getDiagnostics = (textDocument) => getBlacklisted(textDocument.getText()) .map(blacklistToDiagnostic(textDocument)) const { DiagnosticSeverity, } = require('vscode-languageserver') const blacklistToDiagnostic = (textDocument) => ({ index, value }) => ({ severity: DiagnosticSeverity.Warning, range: { start: textDocument.positionAt(index), end: textDocument.positionAt(index + value.length), }, message: `${value} is blacklisted.`, source: 'Blacklister', })

เพย์โหลดการวินิจฉัยของเราจะเป็นผลมาจากการเรียกใช้ข้อความของเอกสารผ่านฟังก์ชันของเรา จากนั้นจึงจับคู่กับรูปแบบที่ลูกค้าคาดหวัง

สคริปต์นี้จะสร้างทุกสิ่งให้คุณ

 curl -o- https://raw.githubusercontent.com/reergymerej/lsp-article-resources/revision-for-6.0.0/blacklist-server-install.sh | bash

หมายเหตุ: หากคุณไม่สะดวกใจกับคนแปลกหน้าที่เพิ่มโปรแกรมปฏิบัติการลงในเครื่องของคุณ โปรดตรวจสอบแหล่งที่มา มันสร้างโครงการ ดาวน์โหลด index.js และ npm link สำหรับคุณ

ผลลัพธ์ของคำสั่ง curl ด้านบน ติดตั้งโปรเจ็กต์ให้คุณ

แหล่งเซิร์ฟเวอร์ที่สมบูรณ์

แหล่งที่มา blacklist-server สุดท้ายคือ:

 #!/usr/bin/env node const { DiagnosticSeverity, TextDocuments, createConnection, } = require('vscode-languageserver') const {TextDocument} = require('vscode-languageserver-textdocument') const getBlacklisted = (text) => { const blacklist = [ 'foo', 'bar', 'baz', ] const regex = new RegExp(`\\b(${blacklist.join('|')})\\b`, 'gi') const results = [] while ((matches = regex.exec(text)) && results.length < 100) { results.push({ value: matches[0], index: matches.index, }) } return results } const blacklistToDiagnostic = (textDocument) => ({ index, value }) => ({ severity: DiagnosticSeverity.Warning, range: { start: textDocument.positionAt(index), end: textDocument.positionAt(index + value.length), }, message: `${value} is blacklisted.`, source: 'Blacklister', }) const getDiagnostics = (textDocument) => getBlacklisted(textDocument.getText()) .map(blacklistToDiagnostic(textDocument)) const connection = createConnection() const documents = new TextDocuments(TextDocument) connection.onInitialize(() => ({ capabilities: { textDocumentSync: documents.syncKind, }, })) documents.onDidChangeContent(change => { connection.sendDiagnostics({ uri: change.document.uri, diagnostics: getDiagnostics(change.document), }) }) documents.listen(connection) connection.listen()

บทช่วยสอนโปรโตคอลเซิร์ฟเวอร์ภาษา: เวลาสำหรับไดรฟ์ทดสอบ

หลังจากที่โปรเจ็กต์ถูก link ed แล้ว ให้ลองเรียกใช้เซิร์ฟเวอร์โดยระบุ stdio เป็นกลไกการขนส่ง:

 blacklist-server --stdio

ตอนนี้กำลังฟัง stdio สำหรับข้อความ LSP ที่เราพูดถึงก่อนหน้านี้ เราสามารถจัดเตรียมสิ่งเหล่านั้นด้วยตนเอง แต่ให้สร้างลูกค้าแทน

ไคลเอนต์ภาษา: VSCode

เนื่องจากเทคโนโลยีนี้มีต้นกำเนิดมาจาก VSCode จึงควรเริ่มต้นจากที่นั่น เราจะสร้างส่วนขยายที่จะสร้างไคลเอ็นต์ LSP และเชื่อมต่อกับเซิร์ฟเวอร์ที่เราเพิ่งสร้างขึ้น

มีหลายวิธีในการสร้างส่วนขยาย VSCode รวมถึงการใช้ Yeoman และตัวสร้างที่เหมาะสม generator-code ตัวสร้าง เพื่อความง่าย เรามาดูตัวอย่างแบร์โบนกัน

มาโคลนสำเร็จรูปและติดตั้งการพึ่งพา:

 git clone [email protected]:reergymerej/standalone-vscode-ext.git blacklist-vscode cd blacklist-vscode npm i # or yarn

เปิดไดเรกทอรี blacklist-vscode ใน VSCode

กด F5 เพื่อเริ่มอินสแตนซ์ VSCode อื่น การดีบักส่วนขยาย

ใน "คอนโซลดีบั๊ก" ของอินสแตนซ์ VSCode แรก คุณจะเห็นข้อความ "ดูสิ ม๊า ส่วนขยาย!”

อินสแตนซ์ VSCode สองรายการ ด้านซ้ายกำลังเรียกใช้ส่วนขยาย blacklist-vscode และแสดงเอาต์พุตคอนโซลการดีบัก ส่วนด้านขวาคือโฮสต์การพัฒนาส่วนขยาย

ตอนนี้เรามีส่วนขยาย VSCode พื้นฐานที่ทำงานได้โดยไม่ต้องมีเสียงระฆังและนกหวีด มาทำให้เป็นไคลเอนต์ LSP กันเถอะ ปิดทั้งอินสแตนซ์ VSCode และจากภายในไดเรกทอรี blacklist-vscode ให้เรียกใช้:

 npm i vscode-languageclient

แทนที่ extension.js ด้วย:

 const { LanguageClient } = require('vscode-languageclient') module.exports = { activate(context) { const executable = { command: 'blacklist-server', args: ['--stdio'], } const serverOptions = { run: executable, debug: executable, } const clientOptions = { documentSelector: [{ scheme: 'file', language: 'plaintext', }], } const client = new LanguageClient( 'blacklist-extension-id', 'Blacklister', serverOptions, clientOptions ) context.subscriptions.push(client.start()) }, }

สิ่งนี้ใช้ vscode-languageclient เพื่อสร้างไคลเอนต์ LSP ภายใน VSCode ต่างจาก vscode-languageserver สิ่งนี้เชื่อมโยงกับ VSCode อย่างแน่นหนา กล่าวโดยสรุป สิ่งที่เราทำในส่วนขยายนี้คือการสร้างไคลเอ็นต์และบอกให้ใช้เซิร์ฟเวอร์ที่เราสร้างขึ้นในขั้นตอนก่อนหน้านี้ เมื่อพิจารณาเฉพาะส่วนขยาย VSCode เราจะเห็นว่าเรากำลังบอกให้ใช้ไคลเอ็นต์ LSP นี้สำหรับไฟล์ข้อความธรรมดา

หากต้องการทดลองขับ ให้เปิดไดเร็กทอรี blacklist-vscode ใน VSCode กด F5 เพื่อเริ่มอินสแตนซ์อื่น การดีบักส่วนขยาย

ในอินสแตนซ์ VSCode ใหม่ ให้สร้างไฟล์ข้อความธรรมดาและบันทึก พิมพ์ “foo” หรือ “bar” แล้วรอสักครู่ คุณจะเห็นคำเตือนว่าสิ่งเหล่านี้ถูกขึ้นบัญชีดำ

อินสแตนซ์ VSCode ใหม่ที่เปิด test.txt แสดง "foo" และ "bar" พร้อมการขีดเส้นใต้ข้อผิดพลาด และข้อความเกี่ยวกับแต่ละรายการในบานหน้าต่างปัญหา โดยระบุว่าอยู่ในบัญชีดำ

แค่นั้นแหละ! เราไม่จำเป็นต้องสร้างตรรกะใดๆ ขึ้นมาใหม่ เพียงแค่ประสานงานกับไคลเอ็นต์และเซิร์ฟเวอร์

มาทำกันอีกครั้งสำหรับตัวแก้ไขอื่น คราวนี้ Sublime Text 3 กระบวนการจะค่อนข้างคล้ายกันและง่ายขึ้นเล็กน้อย

ไคลเอนต์ภาษา: ข้อความประเสริฐ 3

ขั้นแรก เปิด ST3 และเปิดจานคำสั่ง เราต้องการเฟรมเวิร์กเพื่อทำให้เอดิเตอร์เป็นไคลเอ็นต์ LSP พิมพ์ Package Control: Install Package แล้วกด Enter ค้นหาแพ็คเกจ “LSP” และติดตั้ง เมื่อเสร็จแล้ว เราก็ สามารถ ระบุไคลเอ็นต์ LSP ได้ มีสถานีที่ตั้งไว้ล่วงหน้ามากมาย แต่เราจะไม่ใช้มัน เราได้สร้างของเราเอง

เปิดจานคำสั่งอีกครั้ง ค้นหา "Preferences: LSP Settings" แล้วกด Enter ซึ่งจะเปิดไฟล์การกำหนดค่า LSP.sublime-settings สำหรับแพ็คเกจ LSP หากต้องการเพิ่มไคลเอ็นต์ที่กำหนดเอง ให้ใช้การกำหนดค่าด้านล่าง

 { "clients": { "blacklister": { "command": [ "blacklist-server", "--stdio" ], "enabled": true, "languages": [ { "syntaxes": [ "Plain text" ] } ] } }, "log_debug": true }

นี้อาจดูคุ้นเคยจากส่วนขยาย VSCode เรากำหนดไคลเอนต์ บอกให้ทำงานกับไฟล์ข้อความธรรมดา และระบุเซิร์ฟเวอร์ภาษา

บันทึกการตั้งค่า จากนั้นสร้างและบันทึกไฟล์ข้อความธรรมดา พิมพ์ “foo” หรือ “bar” แล้วรอ อีกครั้ง คุณจะเห็นคำเตือนว่าสิ่งเหล่านี้ถูกขึ้นบัญชีดำ การรักษา—วิธีแสดงข้อความในตัวแก้ไข—แตกต่างกัน อย่างไรก็ตาม ฟังก์ชันของเราก็เหมือนกัน ครั้งนี้เราแทบไม่ได้ทำอะไรเลยเพื่อเพิ่มการสนับสนุนให้กับบรรณาธิการ

ภาษา “ไคลเอนต์”: Vim

หากคุณยังคงไม่มั่นใจว่าการแยกข้อกังวลนี้ทำให้ง่ายต่อการแชร์คุณลักษณะต่างๆ ในโปรแกรมแก้ไขข้อความ ต่อไปนี้คือขั้นตอนในการเพิ่มฟังก์ชันการทำงานเดียวกันให้กับ Vim ผ่าน Coc

เปิด Vim แล้วพิมพ์ :CocConfig จากนั้นเพิ่ม:

 "languageserver": { "blacklister": { "command": "blacklist-server", "args": ["--stdio"], "filetypes": ["text"] } }

เสร็จแล้ว.

การแยกเซิร์ฟเวอร์ระหว่างไคลเอ็นต์ช่วยให้ภาษาและบริการภาษาเติบโตได้

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

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


ป้าย Microsoft Gold Partner

ในฐานะ Microsoft Gold Partner Toptal เป็นเครือข่ายผู้เชี่ยวชาญของ Microsoft ที่ยอดเยี่ยม สร้างทีมที่มีประสิทธิภาพสูงพร้อมผู้เชี่ยวชาญที่คุณต้องการ - ทุกที่และทุกเวลาที่คุณต้องการ!