تصور کنید تمام قدرت یک ترمینال مدرن و سریع را درست در قلب Emacs داشته باشید، بدون اینکه با کندی یا تداخل کلیدها دستوپنجه نرم کنید. اگر از کاربران حرفهای Emacs هستید، Ghostel دقیقاً همان حلقهی گمشدهای است که فاصله بین سرعت اجرای دستورات و مدیریت متن در بافر را از بین میبرد.
در جولای ۲۰۲۶، ابزاری به نام Ghostel معرفی شد که با جایگزینی موتورهای قدیمی با libghostty-vt، استانداردهای عملکردی را در محیط Emacs جابهجا کرد. این ابزار محدودیتهای همیشگی ترمینالهای داخلی Emacs را با سپردن مدیریت وضعیت ترمینال و رندرینگ به یک ماژول دینامیک بومی که با زبان Zig نوشته شده، حل کرده است.
همانطور که در تحلیلهای پیشین ما دربارهی بهینهسازی محیطهای توسعه اشاره کردیم، توازن بین سادگی و قدرت همیشه چالش اصلی کاربران Emacs بوده است. کاربران برای سالها بین سادگی shell و قدرت vterm مردد بودند؛ چرا که همواره یک «ناهمگونی» (Impedance Mismatch) بین جریان زندهی ترمینال و میل Emacs به مدیریت متن وجود داشت. Ghostel با استفاده از همان موتور VT که ترمینال مستقل Ghostty را میراند، تضمین میکند که پروتکلهای مدرن ترمینال خارج از حلقهی اصلی Elisp پردازش شوند.
معماری سرعت
به نقل از مستندات رسمی در dakra.github.io، ساختار Ghostel بر دو لایهی مجزا استوار است. یک ماژول بومی مسئول مدیریت وضعیتهای پیچیدهی ترمینال، رندرینگ و ورودی/خروجیهای محلی PTY است، در حالی که Elisp تنها تجربهی کاربری سطح بالا، نقشههای کلید (keymaps)، بافرها و ادغام فرآیندهای راه دور را مدیریت میکند. این رویکرد که از emacs-libvterm الهام گرفته شده، به دلیل بهرهگیری از موتور مدرن Ghostty، قابلیتهایی را فعال میکند که libvterm هرگز پشتیبانی نمیکرد.
بر اساس بررسی فنی این معماری، چندین دستاورد کلیدی در عملکرد مشاهده میشود:
- مسار PTY بومی: با استفاده از یک رشته (thread) پسزمینه برای مصرف خروجی، Emacs تنها زمانی که نیاز به بازترسیم (redraw) باشد مطلع میشود. این مکانیزم از خفه شدن فیلتر فرآیند Emacs توسط جریانهای حجیم لاگ جلوگیری میکند. این ویژگی توسط متغیر
ghostel-use-native-pty(مقدار پیشفرضt) کنترل میشود. - بازترسیم فوری: برای حذف تأخیر ۱۶ تا ۳۳ میلیثانیهای هنگام تایپ که در ترمینالهای شبیهساز رایج است، خروجیهایی که بلافاصله پس از یک ضربه کلید میرسند، از طریق
ghostel-immediate-redraw-interval(مقدار پیشفرض ۰.۰۵ ثانیه) تایمرهای استاندارد را دور میزنند. - جذب دادههای حجیم: این سیستم بهگونهای طراحی شده است که بتواند حجمهای عظیم داده، مانند اجرای دستور
catبرای یک فایل ۱۰ مگابایتی، را بدون منجمد کردن ادیتور مدیریت کند. - رندرینگ تطبیقی: Ghostel از بازترسیمهای افزایشی برای نادیده گرفتن ردیفهای بدون تغییر استفاده میکند و نرخ فریم تطبیقی را از طریق
ghostel-timer-delay(مقدار پیشفرض ۰.۰۳۳ ثانیه) تنظیم میکند.
قابلیتهای پیشرفتهی ترمینال
به دلیل استفاده از libghostty-vt، این ابزار ویژگیهایی را ارائه میدهد که پیش از این در گزینههای ترمینال Emacs مثل libvterm غیرممکن بودند:
- پروتکل گرافیکی Kitty: کاربران میتوانند تصاویر را بهصورت درونخطی در بافر رندر کنند. این قابلیت از جایگذاریهای سنتی (مانند
timgیاkitty +kitten icat) و همچنین جایگذاریهای جایگزین یونیکد (U+10EEEE) که توسط ابزارهایی مثل yazi استفاده میشود، پشتیبانی میکند. Ghostel برای پردازش PNGها ازstbimageداخلی استفاده کرده و مقادیر RGB/RGBA/Gray را به PPM تبدیل میکند. لازم به ذکر است که کانالهای آلفا در طول تبدیل حذف میشوند و برش مستطیلی منبع (source-rect cropping) پشتیبانی نمیشود. حد مجاز ذخیرهسازی گرافیکها درghostel-kitty-graphics-storage-limitپیشفرض ۳۲۰ میبایت است. به دلیل مسائل امنیتی، رسانههای غیرمستقیم (non-direct mediums) از طریقghostel-kitty-graphics-mediumsبه صورت اختیاری فعال میشوند. - خروجی همگامشده (دسامبر ۲۰۲۶): این پروتکل اثر «پلهای» یا تکهتکه شدن صفحه را که هنگام بازترسیم بخشهای بزرگ توسط عاملهای هوش مصنوعی مثل Claude Code دیده میشد، بهطور کامل حذف میکند.
- ویژگیهای متنی غنی: پشتیبانی کامل از رنگهای ۲۴ بیتی (True Color RGB)، استایلهای متنوع زیرخط (تک، دبل، موجدار/curly، نقطهچین و خطچین) و طیف کاملی از استایلهای مکاننما (بلاک، خط/bar، زیرخط، بلاک توخالی؛ که هر کدام میتوانند ثابت یا چشمکزن باشند).
- هایپرلینکهای OSC 8: لینکهای قابل کلیکی که توسط برنامههای ترمینال ارسال میشوند، کاملاً پشتیبانی میشوند. علاوه بر این،
ghostel-enable-url-detectionلینکهای متنی ساده http/https را بهصورت خودکار شناسایی و فعال میکند. - هوش رنگی: برنامههای TUI مثل
btopیاdeltaمیتوانند از طریق کوئریهای رنگی OSC 4، 10 و 11، تم Emacs را شناسایی کرده و پالت رنگی روشن یا تیره را بهصورت خودکار انتخاب کنند. ۱۶ رنگ ANSI بر اساس وجههایی (faces) که ازterm-color-*ارثبری میکنند، مدیریت میشوند. همچنینghostel-bold-colorاجازه میدهد متنهای Bold را به صورت یک رشته رنگی خاص #RRGGBB یا یک نسخه روشن تعریف کنید. - اعلانها و پیشرفت: پشتیبانی از پروتکلهای OSC 9 (iTerm2) و OSC 777 (rxvt) برای ارسال اعلانها به
ghostel-notification-function. اگر بستهalertنصب باشد، از بکاندهای بومی سیستمعامل مثلosascript(در macOS) یاlibnotify(در لینوکس) استفاده میکند. برای ردیابی پیشرفت، از پروتکل OSC 9;4 مربوط به ConEmu پشتیبانی شده و درصدها (مثلاً[42%]) یا یک انیمیشن چرخان (spinner) را از طریقspinner.elدر mode-line نمایش میدهد (تنظیمات درghostel-progress-function).
حالتهای ورودی هوشمند
Ghostel برای حل تداخل بین دستورات Emacs و کلیدهای ارسالی به شل، پنج حالت ورودی distinto تعریف کرده است. شما میتوانید حالت فعلی را از طریق نشانگر mode-line-process ردیابی کنید:
۱. Semi-char (پیشفرض): اکثر کلیدها به ترمینال میروند. استثناهایی مثل M-x, C-x, C-u, C-h و M-: برای Emacs رزرو شدهاند. انتقال به این حالت با C-c C-j انجام میشود. اکشنهای کلیدی شامل C-c C-c برای قطع (interrupt)، C-c C-z برای تعلیق (suspend)، C-c C-d برای EOF، C-c M-w برای کپی کل تاریخچه (scrollback) به kill ring و C-c M-l برای پاک کردن تاریخچه است.
۲. Char Mode: با C-c M-d وارد این حالت میشوید؛ در اینجا هر کلیدی بدون استثنا به ترمینال ارسال میشود. این حالت برای برنامههای TUI پیچیده که کلیدهایی مثل C-x یا M-x را برای خود رزرو کردهاند، ضروری است. تنها راه خروج M-RET (یا C-M-m) است.
۳. Emacs Mode: با C-c C-e فعال میشود. بافر فقط-خواندنی میشود اما زنده میماند. شما میتوانید از isearch-forward یا occur برای فیلتر کردن لاگهای جاری بدون متوقف کردن فرآیند استفاده کنید. کلیدهای تایپ شده به شل نمیرسند، مگر C-y که متن را از طریق bracketed paste میچسباند. برای پرش به اعلانها (prompts) در این حالت از C-c M-n یا C-c M-p استفاده کنید.
۴. Copy Mode: با C-c C-t فعال میشود. مشابه حالت Emacs است اما خروجی ترمینال را کاملاً منجمد میکند تا در هنگام استریم شدن لاگها، انتخاب متن پایدار بماند. این حالت بهطور خودکار خطوط جدید ناشی از wrapping نرم را از متن کپی شده حذف میکند و با هر کلید self-insert (از طریق ghostel-readonly-fast-exit) بهطور خودکار بسته میشود.
۵. Line Mode: با C-c C-l فعال میشود. بافر مانند یک فیلد متنی محلی عمل میکند که در آن میتوانید یک خط کامل را با تمام قدرت ویرایشی Emacs (از جمله M-b, M-DEL, C-y و transpose-words) ویرایش کنید. کل خط تنها پس از فشردن RET بهصورت یکجا ارسال میشود. اگر یک TUI تمامصفحه شروع شود، Ghostel بهطور خودکار به حالت semi-char رفته و پس از خروج از TUI دوباره به line mode باز میگردد. این حالت از تکمیل خودکار bash (از طریق ghostel-line-mode-use-bash-completion) پشتیبانی میکند و در صورت نبود مارکرهای OSC 133، از ghostel-prompt-regexp استفاده میکند.
تعامل با ماوس و مکاننما
منطق پیچیدهی ماوس در Ghostel باعث میشود ادیتور روان باقی بماند. یک کلیک و کشیدن (click-and-drag) یک ناحیه (region) ایجاد میکند و پس از رها کردن، Ghostel بسته به تنظیم ghostel-mouse-drag-input-mode (پیشفرض copy) حالت ورودی را تغییر میدهد تا خروجیهای جاری selection را بههم نریزند.
اگر یک TUI دارای ردیابی ماوس DEC (کدهای ۱۰۰۰/۱۰۰۲/۱۰۰۳ مثل htop یا lazygit) باشد، کلیک مستقیماً به برنامه ارسال میشود. علاوه بر این، مکانیزم ghostel-point-leave-input-mode تضمین میکند که هنگام استفاده از ابزارهایی مثل consult-line یا isearch مکاننما بهطور تصادفی هنگام بازترسیم به موقعیت کرسر ترمینال پرتاب نشود.
برای بستههای Jump سفارشی، دستور ghostel-maybe-leave-input را میتوان به عنوان یک hook (مثلاً flash-after-jump-hook) یا به عنوان advice با :after (مثلاً برای avy-action-goto) اضافه کرد تا موقعیت point خارج از کرسر زنده حفظ شود.
امنیت و ادغام راه دور
یکی از کاربردیترین بخشها، تشخیص اعلان رمز عبور (Password Prompt Detection) است. وقتی برنامهای مثل sudo یا ssh یا gpg درخواست رمز عبور میکند، Ghostel تشخیص میدهد که slave TTY در حالت canonical با echo خاموش است. سپس یک پنجره امن read-passwd باز میکند. برای جلوگیری از باقی ماندن رمز در heap حافظه، مقدار آن بلافاصله پس از ارسال پاک (clear-string) میشود. برای میزبانهای راه دور، سیستم به رگکس ردیف مکاننما (ghostel-password-prompt-regex) متکی است. این تشخیص از طریق ghostel-password-prompt-functions قابل گسترش است تا کاربر بتواند مدیریتکنندههای auth-source یا KeePass را اضافه کند.
اتصالات راه دور از طریق TRAMP مدیریت میشوند. Ghostel میتواند شلها را روی میزبانهای راه دور با استفاده از ghostel-tramp-shells اجرا کند. این متغیر اجازه پیکربندی بر اساس متد را میدهد، مثلاً ("docker" "/bin/sh"). شلهای شناخته شده مثل bash، zsh و fish بهطور پیشفرض به صورت login+interactive (-l -i) اجرا میشوند. ردیابی دایرکتوری (OSC 7) با TRAMP سازگار است، به این معنی که default-directory با تغییر مسیر در شل، به مسیر TRAMP متناظر بهروزرسانی میشود. اگر پیشوندی برای TRAMP وجود نداشته باشد، متد پیشفرض tramp-default-method یا ghostel-tramp-default-method در نظر گرفته میشود.
Ghostel برای اطمینان از اینکه برنامههای راه دور از مسیرهای سریع (fast paths) استفاده کنند، نصب فایل terminfo xterm-ghostty را مدیریت میکند:
- مدل TRAMP-launched: فایل terminfo کامپایل شده را از طریق اتصال موجود به یک دایرکتوری موقت در مقصد میفرستد. هر دو چیدمان لینوکس (x/, g/) و macOS (78/, 67/) پشتیبانی میشوند و هیچ چیزی روی مقصد باقی نمیماند.
- مدل Outbound SSH: یک Wrapper دستور
sshرا سایه میکند و با استفاده از کش در~/.cache/ghostel/ssh-terminfo-cacheبررسی میکند که آیا ورودی در مقصد وجود دارد یا خیر. در صورت نبود، آن را از طریقtic -x -در~/.terminfo/نصب میکند. توصیه میشود برای جلوگیری از درخواستهای متعدد احراز هویت، ازControlMasterدر SSH استفاده کنید.
کاربران میتوانند با تنظیم ghostel-ssh-install-terminfo روی nil این اتوماسیون را غیرفعال کرده و بهصورت دستی با دستور infocmp -x xterm-ghostty | ssh REMOTE 'mkdir -p ~/.terminfo && tic -x -' آن را منتقل کنند.
فراخوانی Elisp از داخل شل
Ghostel اجازه میدهد اسکریپتهای شل توابع Emacs را با استفاده از یک افزونه خصوصی OSC 52 (\e]52;e;<payload>\e\) تحریک کنند. با استفاده از کمکی به نام ghostel_cmd در شل، کاربر میتواند علیاسهایی بسازد تا فایلها در Emacs باز شوند.
برای مثال، افزودن کد زیر به .bashrc یا .zshrc اجازه میدهد شل، Magit یا Dired را برای دایرکتوری جاری باز کند:
if [[ "${INSIDE_EMACS%%,*}" = 'ghostel' ]]; then
e() { ghostel_cmd find-file-other-window "$@"; }
dow() { ghostel_cmd dired-other-window "${1:-$PWD}"; }
gst() { ghostel_cmd magit-status-setup-buffer "$(pwd)"; }
fi
برای امنیت، تنها توابعی که در لیست سفید ghostel-eval-cmds (مانند find-file, dired, message) قرار دارند اجازه اجرا مییابند.
افزونههای توسعهدهنده
Ghostel بهگونهای طراحی شده که سبک بماند و منطقهای تخصصی را به افزونهها بسپارد:
- Evil-mode: افزونه
evil-ghostelمکاننمای ترمینال را با point در Emacs در طول تغییرات وضعیت همگام میکند تا ناوبری باhjklدر حالت Normal ممکن شود. - Compilation Mode: افزونه
ghostel-compileجایگزین استانداردM-x compileمیشود و یک TTY واقعی ایجاد میکند. این باعث میشود ابزارهایی کهisatty(3)را بررسی میکنند، رنگها و نوارهای پیشرفت را نمایش دهند، در حالی کهghostel-compile-view-modeبرای ناوبری در خطاها حفظ میشود. دستوراتmake compile,recompileوproject-compileهمگی قابل تنظیم برای استفاده از ghostel هستند. - سایر ادغامها: پشتیبانی از Eshell از طریق
ghostel-eshell(متصل بهeshell-load) و Comint از طریق بستهghostel-comintفراهم شده است.
نصب و پیشنیازها
این ابزار به Emacs 28.1+ با پشتیبانی از ماژولهای دینامیک نیاز دارد و با macOS، لینوکس، FreeBSD و ویندوز (با استفاده از ConPTY) سازگار است. در ویندوز، DLL ماژول باید با معماری Emacs مطابقت داشته باشد. ترمینالهای محلی در ویندوز از runtime کنسول مایکروسافت (conpty.dll و OpenConsole.exe) استفاده میکنند و در صورت نبود، به API داخلی باز میگردند. ترمینالهای راه دور TRAMP از ویندوز محدود به مقصدهای POSIX هستند و در حال حاضر از تغییر اندازه دینامیک (dynamic resize) پشتیبانی نمیکنند.
جزئیات نصب
- MELPA: استفاده از
(use-package ghostel :ensure t). - VC (Emacs 30+): استفاده از
:vc (:url "https://github.com/dakra/ghostel" :lisp-dir "lisp" :rev :newest). - ماژول بومی: ماژول معمولاً بهصورت خودکار از طریق
ghostel-module-auto-install(پیشفرضask) دانلود میشود. کاربران میتوانند دستیM-x ghostel-download-moduleیاM-x ghostel-module-compileرا اجرا کنند. اگر مدیر بسته درخت فایلها را بازسازی کند،ghostel-module-directoryمیتواند به یک مکان پایدار مثل~/.config/emacs/ghostel/اشاره کند. - ساخت از منبع: نیازمند Zig 0.15.2 است. دستور ساخت
zig build --prefix . -Doptimize=ReleaseFastاست. در ویندوز، معمولاً از هدفx86_64-windows-gnuبرای مطابقت با بیلد بومی Emacs استفاده میشود.
برای شروع، کاربران باید بسته را نصب کرده و M-x ghostel را برای اولین نشست اجرا کنند. برای کاربران پیشرفته، تنظیمات از طریق M-x customize-group RET ghostel قابل تغییر است.
گام بعدی شما
- اگر از Emacs استفاده میکنید، بسته
ghostelرا نصب کرده و اولین نشست خود را باM-x ghostelآغاز کنید. - برای شخصیسازی دقیق رفتار ترمینال، گروه تنظیمات را با
M-x customize-group RET ghostelبررسی کنید. - اگر از TUIهای گرافیکی مثل yazi استفاده میکنید، پروتکل Kitty را در تنظیمات فعال کنید تا تصاویر را مستقیماً در بافر ببینید.
اما برای کسانی که به دنبال جایگزینی کامل محیط ترمینال با یک اکوسیستم هوشمندتر هستند، تحلیل ما دربارهی پروتکلهای جدید مدلهای استدلالی در تعامل با شل، قطعه گمشدهی این پازل است.




گفتگو