YCMD هو خادم يوفر واجهات برمجة التطبيقات لإكمال التعليمات البرمجية وغيرها من حالات استخدام الكود مثل أوامر GOTO الدلالية (وغيرها). بالنسبة لبعض الأنواع ، يمكن لـ YCMD أيضًا توفير الأخطاء والتحذيرات التشخيصية.
كان YCMD في الأصل جزءًا من قاعدة بيانات YouCompleteme ، ولكن تم تقسيمها إلى مشروع منفصل بحيث يمكن استخدامه في محررين بخلاف VIM.
تحقق من وثائق API إذا كنت ترغب في تنفيذ عميل. طريقة جيدة لمعرفة كيفية التفاعل مع YCMD هي القراءة من خلال (وتشغيل) ملف example_client.py . راجع مجلد README للحصول على أمثلة للحصول على تفاصيل حول كيفية تشغيل عميل المثال.
لا تتردد في إرسال طلب سحب إضافة رابط إلى عميلك هنا إذا قمت ببناء واحد.
إذا كنت تتطلع إلى تطوير YCMD ، راجع إرشادات إجراء الاختبارات.
هذا كل شيء لأوبونتو لينكس. يمكن العثور على تفاصيل حول تشغيل YCMD على نظام التشغيل الآخر في تعليمات YCM (تجاهل الأجزاء الخاصة بـ VIM). لاحظ أن YCMD يعمل على Python 3.8.0+.
أولاً ، قم بتثبيت الحد الأدنى من التبعيات:
sudo apt install build-essential cmake python3-dev
بعد ذلك ، قم بتثبيت التبعيات الخاصة باللغة التي تحتاجها:
sudo apt install golang-go لـ Go.sudo apt install npm لجافا سكريبت و typeScript.sudo apt install mono-devel ل c#.sudo apt install openjdk-8-jre لجافا.عند استنساخ المستودع لأول مرة ، ستحتاج إلى تحديث العارض الفرعي:
git submodule update --init --recursive
ثم قم بتشغيل python3 build.py --all أو أي من المكملات المحددة المدرجة بواسطة python3 build.py --help . هذا يجب أن يجعلك تذهب.
لمزيد من الإرشادات التفصيلية حول بناء YCMD ، راجع تعليمات YCM (تجاهل الأجزاء الخاصة بـ VIM).
n .x-ycm-hmac HTTP. يتم حساب HMAC من السر المشترك الذي تم تمريره إلى الخادم عند بدء التشغيل وجسم الطلب/الاستجابة. خوارزمية Digest هي SHA-256. سيتضمن الخادم أيضًا HMAC في ردوده ؛ يجب التحقق من ذلك قبل استخدام الاستجابة. انظر example_client.py لمعرفة كيف يتم ذلك.هناك العديد من محركات الانتهاء في YCMD. الأكثر أساسية هو اكتمال قائم على المعرفات يجمع جميع المعرفات في الملف المقدم في طلب الإكمال ، والملفات الأخرى من نفس filetype التي تم توفيرها مسبقًا وأي ملفات علامات تنتجها CTAGs. هذا المحرك غير رديء.
هناك أيضا العديد من المحركات الدلالية في YCM. هناك اكتمال قائم على Clangd يوفر كلاهما إكمالًا دلسيًا للغات العائلة C. هناك أيضًا اكتمال قائم على JEDI لإكمال الدلال لـ Python ، وهو مكتمل يستند إلى OmnishArp لـ C#، وهو مكتمل يستند إلى GOPLS لـ GO (باستخدام GOPLS للقفز إلى التعريفات) ، وكامل مستند إلى TSServer لـ JavaScript و TypeScript ، وهو عبارة عن خادم JDT.LS المستند إلى JAVA ، واستنادا إلى RLS. سيتم إضافة المزيد مع مرور الوقت.
هناك أيضًا محركات إكمال أخرى ، مثل FilePath Complete (جزء من كمل المعرف).
سيقوم الخادم تلقائيًا باكتشاف محرك الإكمال سيكون الأفضل في أي موقف. في بعض الأحيان ، يستفسر العديد منهم في وقت واحد ، ويدمج المخرجات ويعرض النتائج.
يتم تشغيل المحركات الدلالية فقط بعد إدراج "المشغلات" الدلالية في الكود. إذا أظهر الطلب المستلم أن مؤشر المستخدم هو بعد الحرف الأخير في string foo; foo. في ملف C# ، سيؤدي ذلك إلى قيام المحرك الدلالي بفحص أعضاء foo بسبب . هو المشغل الدلالي الافتراضي لـ C# (يمكن تغيير المشغلات ديناميكيًا). إذا كان النص string foo; foo.zoo ، سيظل الانتهاء الدلالي قد يتم تشغيله (الزناد خلف كلمة zoo التي يكتبها المستخدم) وسيتم ترشيح النتائج باستخدام استعلام zoo .
يمكن أيضًا إجبار الإكمال الدلالي عن طريق تعيين force_semantic: true في بيانات JSON لطلب الإكمال ، ولكن يجب عليك القيام بذلك فقط إذا طلب المستخدم بشكل صريح الانتهاء الدلالي مع اختصار لوحة المفاتيح ؛ خلاف ذلك ، اترك الأمر حتى YCMD لتحديد وقت استخدام أي محرك.
السبب في عدم استخدام الإكمال الدلالي دائمًا حتى عند توفره هو أن المحركات الدلالية يمكن أن تكون بطيئة ولأن المستخدم في معظم الوقت ، لا يحتاج المستخدم فعليًا إلى إكمال دلالي.
هناك نوعان من حالات الاستخدام الرئيسية لإكمال الكود:
حالة الاستخدام الأولى هي الأكثر شيوعًا ويتم معالجتها بشكل تافه مع محرك إكمال المعرف (والذي يشرف على الشرق الأوسط). الثاني يحتاج إلى الانتهاء الدلالي.
من الأهمية بمكان أن نلاحظ أن تصفية الإكمال لا يعتمد على الإدخال كونه بادئة سلسلة من الإكمال (ولكن هذا يعمل أيضًا). يجب أن يكون المدخلات تطابقًا لاحقة من الانتهاء. هذه طريقة رائعة للقول إن أي أحرف إدخال يجب أن تكون موجودة في سلسلة إكمال بالترتيب الذي تظهر به في المدخلات. لذلك abc هو بعد xaybgc ، ولكن ليس من xbyxaxxc .
يزيل مرشح اللاحق أي إكمال لا يتطابق مع الإدخال ، ولكن بعد ذلك يبدأ نظام الفرز. إنه متورط بعض الشيء ، ولكن من المتحدث تقريبًا "حدود الكلمة" (WB) تطابقات الأحرف "تستحق" أكثر من تطابقات غير WB. في الواقع ، هذا يعني أنه بالنظر إلى مدخلات "GUA" ، سيتم تصنيف "GetUserAccount" في القائمة أعلى من إكمال "Fooguxa" (وكلاهما من المباريات اللاحقة). الحرف إلى الحدود كلمة كلها أحرف رأس المال ، والأحرف التي يسبقها السطح السفلي وحرف الحروف الأولى في سلسلة الانتهاء.
إذا لم يتلق الخادم أي طلبات لفترة من الوقت (يتم التحكم فيها بواسطة --idle_suicide_seconds YCMD علامة) ، فسيتم إغلاقه. هذا مفيد للحالات التي تم فيها وفاة العملية التي بدأت YCMD دون إخبار YCMD بالموت أيضًا أو إذا تم تعليق YCMD (يجب أن يكون هذا نادرًا للغاية).
إذا كنت تقوم بتنفيذ عميل لـ YCMD ، فتأكد من أن لديك نوعًا من خيط خلفية الاحتفاظ بالذات الذي يغطى بشكل دوري YCMD (فقط اتصل بـ /healthy Handler ، على الرغم من أن أي معالج سيفعله).
يمكنك أيضًا إيقاف تشغيل هذا عن طريق المرور --idle_suicide_seconds=0 ، على الرغم من أنه غير موصى به.
أثناء بدء التشغيل ، تحاول YCMD تحميل مكتبة ycm_core وتخرج مع أحد رموز الإرجاع التالية إذا لم تنجح:
ycm_core مفقودة ؛ycm_core عفا عليها الزمن. يمكنك توفير إعدادات إلى YCMD على بدء تشغيل الخادم. هناك ملف default_settings.json يمكنك تعديله. راجع قسم الخيارات في دليل مستخدم YCM للحصول على وصف لما يفعله كل خيار. تمرير المسار إلى ملف الإعدادات المعدلة إلى ycmd كـ --options_file=/path/to/file flag. لاحظ أنه يجب عليك تعيين إعداد hmac_secret (قم بتشفير القيمة بـ BASE64). نظرًا لأن الملف الذي تمرره يحتوي على رمز سري ، تأكد من قيامك بإنشاء الملف المؤقت بطريقة آمنة (مكالمة نظام Linux mkstemp() فكرة جيدة ؛ استخدم شيئًا مشابهًا لنظام التشغيل الآخر).
بعد بدء تشغيله ، ستقوم YCMD بحذف ملف الإعدادات الذي قدمته بعد قراءته.
ملف الإعدادات هو شيء يجب على المحرر إنتاجه بناءً على القيم التي قام المستخدم بتكوينها. هناك أيضًا ملف إضافي ( .ycm_extra_conf.py ) من المفترض أن يوفر المستخدم الخاص بك لتكوين بعض الكصفين الدلاليين. يمكن أيضًا العثور على مزيد من المعلومات حولها في القسم المقابل من دليل مستخدم YCM.
.ycm_extra_conf.py المواصفات قد تحدد وحدة .ycm_extra_conf.py الوظائف التالية:
Settings( **kwargs ) تتيح هذه الوظيفة للمستخدمين تكوين مكملات اللغة على أساس كل مشروع أو عالميًا. حاليًا ، يتطلب الأمر من قبل كمل Libclang المستند إلى Libclang واختياريًا للمكملات الأخرى. يمكن استرداد الحجج التالية من قاموس kwargs وهي شائعة في جميع المكملات:
language : معرف للكمل الذي يسمى الوظيفة. قيمتها هي python لكمل Python و cfamily لكمل العائلة C. هذه الوسيطة مفيدة لتكوين العديد من المكملات في وقت واحد. على سبيل المثال:
def Settings ( ** kwargs ):
language = kwargs [ 'language' ]
if language == 'cfamily' :
return {
# Settings for the libclang and clangd-based completer.
}
if language == 'python' :
return {
# Settings for the Python completer.
}
return {} filename : المسار المطلق للملف الذي تم تحريره حاليًا.
client_data : أي بيانات إضافية تم توفيرها بواسطة تطبيق العميل. راجع وثائق YouCompleteme للحصول على مثال.
قيمة الإرجاع هي قاموس يعتمد محتواه على الكمل.
غالبًا ما تدعم خوادم LSP تكوين المستخدم عبر طلب التهيئة. عادة ما يتم تقديمها كخيارات في واجهة المستخدم. يدعم YCMD هذا باستخدام .ycm_extra_conf.py من خلال السماح للمستخدم بتحديد القاموس الدقيق للإعدادات التي يتم تمريرها في رسالة تهيئة الخادم. يتم إرجاع هذه الخيارات من Settings تحت مفتاح ls . يتم تحويل قاموس Python إلى JSON وإدراج حرفي في طلب تهيئة LSP. من أجل تحديد مجموعة خيارات الخادم ، استشر ملف وثائق الخادم أو ملف package.json . كائن config_sections هو قاموس عبارة عن مفاتيح "أقسام" والقيم عبارة عن أجزاء من الإعدادات (عادة ما تكون موجودة في كائن ls ) المقابلة لتلك الأقسام. هذا أكثر تحديداً ويتطلب التجربة والخطأ لجعلها تعمل. إنه اختياري ومفيد فقط إذا قمت بوضوح بتمكين دعم workspace/configuration .
مثال على تكوين LSP:
def Settings ( ** kwargs ):
if kwargs [ 'language' ] == 'java' :
return { 'ls' : { 'java.rename.enabled' : False },
# `config_sections` is not used for java...
'config_sections' : { 'section0' : {} } بالإضافة إلى ذلك ، يمكن لـ YCMD استخدام أي خادم لغة ، بالنظر إلى نوع الملف وخط الأوامر. يمكن استخدام language_server لخيار المستخدم لتوصيل خادم LSP YCMD عادةً. القيمة هي قائمة القواميس التي تحتوي على:
name : السلسلة التي تمثل اسم الخادمcmdline : القائمة التي تمثل سطر الأوامر لتنفيذ الخادم (اختياري ؛ إلزامي إذا لم يتم تحديد المنفذ)port : اختياري. في حالة تحديد ، يتم استخدام اتصال TCP لهذا المنفذ. إذا تم تعيينه على * ، يتم تحديد منفذ locall غير المستخدم وتوافره في cmdline كـ ${port} (انظر الأمثلة أدناه).filetypes : قائمة من الأنواع المدعومة.project_root_files : يخبر YCMD ما الملفات التي تشير إلى جذر المشروع.capabilities' : يتجاوز إمكانات LSP الافتراضية لـ YCMD.workspace/configuration ، فتحقق من تفاصيل CONF الإضافية ، ذات الصلة بخوادم LSP.additional_workspace_dirs : يحدد مساحات عمل معروفة بشكل ثابت والتي يجب أن تكون مفتوحة على بدء تشغيل خادم LSP.triggerCharacters : تجاوز أحرف Trigger لخادم LSP لإكماله. يمكن أن يكون ذلك مفيدًا عندما يطلب الخادم بغيضًا إكمالًا على كل حرف أو على سبيل المثال على أحرف المساحة البيضاء. {
"language_server" : [ {
"name" : " gopls " ,
"cmdline" : [ " /path/to/gopls " , " -rpc.trace " ],
"filetypes" : [ " go " ],
"project_root_files" : [ " go.mod " ],
"triggerCharacters" : [ " . " ]
} ]
}أو ، لاستخدام اتصال TCP:
{
"language_server" : [ {
"name" : " godot " ,
"port" : " 6008 " ,
"filetypes" : [ " gdscript " ]
} ]
} أو ، لاستخدام منفذ محلي غير مستخدم ، قم بتعيين port على * واستخدام ${port} في cmdline :
{
"language_server" : [ {
"name" : " someserver " ,
"cmdline" : [ " /path/to/some/server " , " --port " , " ${port} " ],
"port" : " * " ,
"filetypes" : [ " somethign " ],
"project_root_files" : [ " somethingfile " ]
} ]
} عند توصيل مكمل بهذه الطريقة ، سيتم تعيين kwargs[ 'language' ] على قيمة مفتاح name ، أي gopls في المثال أعلاه.
يتم دعم عدد من مكملات LSP حاليًا بدون language_server ، USCH على النحو التالي:
يمكن للمرء أيضًا تجاوز دليل الجذر ، مع project_directory .
def Settings ( ** kwargs ):
return { 'project_directory' : 'src/' } # The path may be absolute as well.ملاحظة: إذا تم تكوين اكتمال قائمة على LSP للغة التي يتم دعمها "مدمجة" ، فإنها تتجاوز الدعم المدمج.
يتم استدعاء وظيفة Settings من قبل مكملين Libclang و Clangd للحصول على أعلام التحويل البرمجي لاستخدامها عند تجميع الملف الحالي. يمكن الوصول إلى المسار المطلق لهذا الملف ضمن مفتاح filename لقاموس kwargs .
قيمة الإرجاع المتوقعة من قبل كلا المكملين هي قاموس يحتوي على العناصر التالية:
flags : (إلزامي لـ libclang ، اختياري لـ clangd) قائمة بعلائم البرمجيات.
include_paths_relative_to_dir : (اختياري) الدليل الذي تتضمن مسارات في قائمة الأعلام نسبية إليه. الإعدادات الافتراضية لدليل عمل YCMD لـ Libclang Complete و .ycm_extra_conf.py لدليل Clangd.
do_cache : (اختياري) يجب أن يتم تخزين Boolean التي تشير إلى ما إذا كانت نتيجة هذه المكالمة (أي قائمة الأعلام) مخزنة مؤقتًا لاسم الملف. الافتراضات إلى True . إذا لم يكن متأكدًا ، يكون الافتراضي صحيحًا دائمًا.
يدعم الإكمال المستند إلى Libclang أيضًا العناصر التالية:
override_filename : (اختياري) سلسلة تشير إلى اسم الملف لتحليلها كوحدة ترجمة لاسم الملف المرفق. تتيح هذه الميزة المتقدمة إلى حد ما المشاريع التي تستخدم "بناء" على غرار الوحدة ، أو لملفات الرأس التي تعتمد عليها الأخرى في الملفات الأخرى.
flags_ready : (اختياري) منطقية تشير إلى أنه ينبغي استخدام الأعلام. الافتراضات إلى True . إذا لم يكن متأكدًا ، يكون الافتراضي صحيحًا دائمًا.
مثال على ذلك هو ببساطة إرجاع قائمة العلامات هو:
def Settings ( ** kwargs ):
return {
'flags' : [ '-x' , 'c++' ]
} يمكن تحديد التكوين من أجل Format الفرعي من خلال CONF إضافي لـ Java Substerver و TypeScript Substerver. يمكن العثور على خيارات التنسيق أدناه:
تدعم هذه الخوادم خيارات التنسيق المخصصة ليتم توفيرها بطريقة مختلفة عن الباقي. لهذا الغرض ، يمكن لدالة Settings إرجاع خاصية formatter .
مثال على تكوين Formatter سيكون:
def Settings ( ** kwargs ):
return {
'formatting_options' : {
'org.eclipse.jdt.core.formatter.lineSplit' : 30 ,
}
} تتيح وظيفة Settings للمستخدمين تحديد مترجم Python و sys.path المستخدم من قبل Completer لتوفير إكمال وفهم رمز. لا يتم تمرير حجج إضافية.
قيمة الإرجاع المتوقعة من قبل الكمل هي قاموس يحتوي على العناصر التالية:
interpreter_path : (اختياري) المسار إلى مترجم بيثون. ~ يتم توسيع متغيرات البيئة في المسار. إن لم يكن مسارًا مطلقًا ، فسيتم البحث عنه من خلال PATH .
sys_path : (اختياري) قائمة المسارات المسبقة إلى sys.path .
مثال الاستخدام:
def Settings ( ** kwargs ):
return {
'interpreter_path' : '~/project/virtual_env/bin/python' ,
'sys_path' : [ '~/project/third_party/module' ]
}PythonSysPath( **kwargs )اختياري لدعم بيثون.
تتيح هذه الوظيفة مزيد من التخصيص لمسار Python sys.path . معلماتها هي العناصر المحتملة التي يتم إرجاعها بواسطة وظيفة Settings لكمل Python:
interpreter_path : مسار إلى مترجم بيثون.
sys_path : قائمة مسارات Python من sys.path .
يجب أن تكون قيمة الإرجاع هي القائمة المعدلة لمسارات Python.
انظر ycmd الخاص .ycm_extra_conf.py للحصول على مثال.
يجب أن تعرض الوحدة الإضافية العالمية نفس الوظائف مثل وحدة .ycm_extra_conf.py مع الإضافات التالية:
YcmCorePreLoad()خياري.
يتم استدعاء هذه الطريقة ، إذا تم تعريفها ، بواسطة الخادم قبل استيراد المكون الإضافي C ++ Python. لا يلزم عادة واستخدامه للمستخدمين المتقدمين فقط.
Shutdown()خياري.
دعا قبل الخادم الخروج بشكل نظيف. لا يلزم عادة واستخدامه للمستخدمين المتقدمين فقط.
يتبع واجهة YCMD HTTP+JSON Semver. على الرغم من أن YCMD شهدت استخدامًا واسعًا على مدار السنوات القليلة الماضية كجزء من YCM ، فإن رقم الإصدار أقل من 1.0 لأن بعض أجزاء API قد تتغير قليلاً حيث يكتشف الأشخاص المشكلات المحتملة التي تدمج YCMD مع محررين آخرين. وبعبارة أخرى ، قد تكون واجهة برمجة التطبيقات الحالية عن غير قصد VIM. نحن لا نريد ذلك.
لاحظ أن واجهة برمجة تطبيقات YCMD الداخلية (أي أي شيء آخر غير HTTP+JSON) لا يتم تغطيتها بواسطة Semver وستتغير بشكل عشوائي تحتك. لا تتفاعل مع رمز Python/C ++/etc مباشرة!
بدون مصادقة HMAC ، من الممكن أن ينتحل موقع الويب الضار. لا تنسى أن Evil.com يمكنه إرسال طلبات إلى الخوادم التي تستمع إلى المضيف المحلي إذا قام المستخدم بزيارة Evil.com في متصفح.
هذا ليس مجرد مصدر قلق نظري . تم إنشاء استغلال تنفيذ رمز عن بُعد من إثبات المفهوم لـ YCMD الذي يعمل على مضيف محلي. تمت إضافة مصادقة HMAC لمنع ناقل الهجوم هذا.
يرجى ملاحظة أن هذا المشروع يتم إصداره باستخدام مدونة سلوك المساهم. من خلال المشاركة في هذا المشروع ، فإنك توافق على الالتزام بشروطه.
إذا كانت لديك أسئلة حول المكون الإضافي أو تحتاج إلى مساعدة ، فيرجى استخدام القائمة البريدية لمستخدمي مستخدمي YCMD.
الصفحة الرئيسية للمؤلف هي http://val.markovic.io.
هذا البرنامج مرخص بموجب ترخيص GPL V3. © 2015-2019 المساهمين YCMD