افزونهای کوچک برای Visual Studio 2026 (و 2022) که کامنتها و رشتههای ترکیبی فارسی + انگلیسی را داخل ادیتور، درست و خوانا نمایش میدهد.
ادیتور ویژوال استودیو متن را دقیقاً از چپ به راست، گلیف به گلیف، میچیند و الگوریتم دوجهتهی یونیکد (Unicode Bidirectional Algorithm) را اجرا نمیکند. نتیجه این میشود که یک کامنت مثل:
// مقدار Timeout را از appsettings.json بخوان (پیشفرض 30 ثانیه)بههمریخته دیده میشود؛ پرانتزها برعکساند و تکههای انگلیسی جای اشتباه میافتند.
BiDiForge برای هر خط، کل بخش کامنت/رشته را بهعنوان یک پاراگراف واحد برمیدارد و آن را با یک
TextBlock وپیاف که الگوریتم دوجهتهی کامل یونیکد را اجرا میکند، دوباره رندر میکند
(IntraTextAdornmentTag).
سه نکتهی حیاتی که کار را درست میکند:
۱. واحد کار، خط است نه توکن. Roslyn یک کامنت مستندات را به دهها span جدا میشکند
(///، <، summary، >، متن، …). اگر هر span جدا رندر شود، ترتیب داخل هر تکه درست میشود ولی
خودِ تکهها همچنان چپبهراست چیده میشوند — یعنی همان بههمریختگی اول. پس spanهای مجاورِ واجد شرایط
در یک گروه ادغام میشوند و با هم رندر میشوند.
۲. جزیرههای چپبهراست. هر رشتهی لاتین/فنی (<summary>، nameof، Application) پیش از رندر
داخل یک embedding صریح چپبهراست (U+202A…U+202C) قرار میگیرد. بدون این کار، < و > بهعنوان
کاراکتر خنثی جهت پاراگراف را میگیرند، آینه میشوند و تگ برعکس رندر میشود.
۳. مرز جزیرهها با دقت تعیین میشود. هر چیزی که داخل embedding چپبهراست بیفتد، ترتیب و
گلیف تحتاللفظی خودش را نگه میدارد؛ پس کاراکتری که اشتباهی داخل جزیره بیفتد، اشتباه رندر میشود:
- نقطهی پایان جمله بعد از
Sms.ir.مال جملهی فارسی است، نه مال نام دامنه. :یا؛که بند فارسی را از یک شناسه جدا میکند، مال بند فارسی است — هرچند در همان رشتهی کاراکترهای غیرفارسی قرار دارد.- پرانتز بستهای که یک پرانتز فارسی را میبندد باید خنثی بماند تا آینه شود؛ ولی پرانتزهای یک نمونهی کد که جفتشان داخل جزیره است نباید آینه شوند.
پس جزیره = بلندترین رشتهی غیرفارسی، منهای فاصله، منهای علائم پایان جمله، منهای براکتی که جفتش
داخلش نیست. و فقط وقتی جزیره حساب میشود که واقعاً چیز جهتداری داشته باشد: یک حرف/رقم لاتین، یا
عملگری مثل => که قاعدهی آینهشدن آن را به <= تبدیل میکند.
۴. رنگها حفظ میشود. گروه به Runهای هممرز با spanهای اصلی شکسته میشود، پس رنگبندی
دلیمیتر/نام تگ/متن دقیقاً همان چیزی میماند که ادیتور میدهد.
نکات دیگر:
- فایل شما دستنخورده میماند. هیچ کاراکتری در بافر تغییر نمیکند؛ فقط نحوهی نمایش عوض میشود.
- خطی که کرسر روی آن است، خام نمایش داده میشود تا تایپ، انتخاب و جابهجایی کرسر طبیعی بماند.
- مستقل از زبان برنامهنویسی. چون از
IClassifierاستفاده میکند، C#، VB، F#، JS/TS، CSS، XML، Razor و هر زبان دستهبندیشدهی دیگری بدون کد اضافه پشتیبانی میشود. - جهت پایهی هر خط بر اساس اینکه اکثر حروف آن خط فارسی است یا لاتین تعیین میشود؛ قاعدهی
«اولین کاراکتر قوی» برای خطی که با
<summary>شروع میشود جواب نمیدهد. - فونت فارسی از عضویت در جزیره پیروی میکند، نه از جنس کاراکتر. هرچه بیرون جزیرهی چپبهراست است
متن فارسی است —
؛و.و«و پرانتزهایش هم — پس فونت فارسی میگیرد. فقط جزیرهها با فونت مونواسپیس ادیتور میمانند. (اگر فونت را با «این Run حرف فارسی دارد یا نه» تصمیم بگیریم، یک نقطهی وسط جمله با فونت کد رندر میشود و مثل وصله میزند.) - پاپآپ Hover هم پوشش داده میشود. Quick Info و signature help از همان موتور رد میشوند.
src/BiDiForge/
Settings/ IBiDiSettings، صفحهی Options، مقادیر پیشفرض مشترک
Text/ تحلیل خالص متن: تشخیص RTL، جهت پایه، جداسازی دلیمیتر
Classification/ نگاشت نوع دستهبندی به سه اسکوپ کاربر
Rendering/ ساخت TextBlock دوجهته هماهنگ با تم
Tagging/ ITagger<IntraTextAdornmentTag> و MEF provider
Commands/ دستور Toggle
هر لایه فقط به اینترفیس لایهی پایینتر وابسته است و همهی وابستگیها از طریق سازنده تزریق میشوند؛ منطق تحلیل متن هیچ ارجاعی به تایپهای ادیتور یا WPF ندارد و مستقیماً قابل تست است.
۱. BiDiForge.sln را در Visual Studio 2026 باز کنید. برای بیلد باید ورکلود
Visual Studio extension development نصب باشد.
۲. کانفیگ Release را بیلد بگیرید.
۳. فایل src\BiDiForge\bin\Release\net472\BiDiForge.vsix را اجرا کنید تا نصب شود.
برای دیباگ کافی است F5 بزنید؛ یک نمونهی Experimental از ویژوال استودیو با افزونهی نصبشده بالا میآید.
مانیفست با
Version="[17.0,)"تعریف شده است، یعنی همان VSIX هم روی VS 2022 و هم روی VS 2026 نصب میشود (مدل سازگاری مبتنی بر نسخهی API در VS 2026).
Tools → Options → BiDiForge → General
| تنظیم | پیشفرض | توضیح |
|---|---|---|
| Enabled | روشن | کلید اصلی افزونه |
| Reveal raw text on the caret line | خاموش | خط زیر کرسر خام نمایش داده شود |
| Keep comment delimiter on the left | روشن | //، ///، /* و * سر جای خودشان بمانند |
| Comments / String literals / XML doc comments / Hover tooltips | روشن | دامنهی کار افزونه |
| Base direction | RightToLeft | Auto جهت هر خط را از اکثریت حروف همان خط میگیرد |
| Persian font family | Vazirmatn, Vazir, Tahoma |
فقط روی متن فارسی اعمال میشود؛ لیست با کاما یعنی زنجیرهی fallback |
| Persian font scale | 0.9 | ضریب اندازهی فونت، فقط روی متن فارسی |
میانبر: Ctrl+Alt+Shift+B (یا Tools → Toggle BiDiForge) افزونه را سریع خاموش/روشن میکند.
پیشفرض Vazirmatn, Vazir, Tahoma است. اگر Vazirmatn روی ویندوز نصب نباشد، WPF بیسروصدا به گزینهی
بعدی میرود. برای نصب: فونت را از مخزن رسمی Vazirmatn بگیرید، فایلهای TTF را انتخاب کنید و
Install for all users بزنید، بعد ویژوال استودیو را ببندید و باز کنید.
- انتخاب متن با ماوس داخل یک span رندرشده، مثل متن معمولی هایلایت نمیشود؛ به همین دلیل خط کرسر بهصورت پیشفرض خام نمایش داده میشود.
- کامنت بلوکی چندخطی، خطبهخط رندر میشود (یک adornment نمیتواند از شکست خط عبور کند).
- در Minimap و چاپ، متن خام دیده میشود.