VIM, Windows, quickfix
Є інструментальний комп'ютер з Windows та асемблер для одного чудового, але специфічного процесора. Для зручності було налаштовано робоче середовище на базі VIM — підсвічування синтаксису, виклик препроцесора, асемблера та лінкера через make з розбором повідомлень про помилки, ctags зі стрибанням за кодом. Але є нюанс — видача повідомлень: make йде українською. Зрозуміло, консольною українською, CP866. А вихідники на асемблері та локаль VIM - CP1251. І як бути? Наводити все кодування - текстових файлів і локалі VIM - до cp866 через один компілятор? Навіть не смішно. Чи здогадуватися з контексту про сенс помилки? Досі так і робив. Набридло. Треба розібратися, витратити пару вечорів і забути про це неприємне непорозуміння.
Система quickfix працює: висновок make потрапляє у файл помилок, з нього виколупуються номери неправильних рядків коду та вид помилки, курсор після компіляції відразу ставиться у потрібне місце. Ось тільки зрозуміти суть помилки непросто:

І команда: cope не допомагає в читанні, хоча за помилковими рядками коду стрибати дозволяє:

Примітка: Для прикладу використана опція makeef=error.err (щоб скоротити рядок команди make, що відображається), хоча зазвичай вона у мене порожня за замовчуванням, і файл помилок make створюється в TEMP.
Здавалося б — нісенітниця яка! Ща поправимо опцію encoding ... А ні - вона, зараза, глобальна. Тому кодування зміниться всюди, у всіх відкритих буферах, включаючи вікно вихідного коду. Коментар українською хана. Повідомлення самого VIM — теж.


Можна спробувати :set encoding=cp866 вручну, можна встромити це в $VIM/vimfile/ftplugin/qf.vim, щоб спрацювало за командою :cope. Можна навітьспробувати: setlocal - не допоможе.
Якщо змінити кодування в одному окремо взятому буфері не виходить, спробуємо перекодувати сам файл помилок. Для цього заглянемо в довідку, і виявимо, що при виклику :make виконується така послідовність:
- При включеній опції autowrite виконується запис всіх змінених буферів.
- Ім'я файлу помилок обчислюється відповідно до значення опції 'makeef'. Якщо значення опції 'makeef' не містить "##", вже існуючий файл з таким ім'ям буде видалено.
- Запускається програма з ім'ям, заданим у значенні опції makeprg (за замовчуванням: make) з необов'язковим набором [аргументів], висновок якої перенаправляється у файл помилок (у Unix висновок також відображається на екрані).
- Читання файлу помилок з використанням значення опції 'errorformat'.
- Якщо модифікатор [!] не заданий, відбувається переміщення до першої помилки зі списку.
- Файл помилок видаляється.
- Тепер ви можете переміщатися за списком помилок за допомогою команд на зразок :cnext та :cprevious.
Виходить, при відкритті qf буфера за командою :cope файл помилок вже не існує. Можна спробувати повернути його невитонченим способом – у $VIM/vimfile/ftplugin/qf.vim записати
Тобто при відкритті буфера qf командою :cope змінити кодування, вставити кодування для файлу, записати новий файл помилок і повернути кодування назад. До речі, місцеве місце тут можна опустити — все одно марно. Тепер можна вручну встановити новий файл помилок :cf ./error.err.

Некрасиво, незручно та купа зайвих рухів руками. Виходить, після кожної компіляції треба спочатку: cope, потім: cl, потім: cf. / error.err і знову: cope. Якщо спробувати вставити все це в qf.vim, то виникнешалена рекурсія, яку VIM задушить самостійно. І :cope поводиться якось дивно: зайві палиці на початку рядків додаються, навіть не хочеться розбиратися в причинах.

Гаразд, тоді спробуємо ловити момент біля читання файлу помилок, а ближче до висновку компілятора. Знову подивимося довідку:
Команда ":make" виконує програму, задану у значенні опції 'makeprg'. Це відбувається шляхом виклику команди з оболонки, заданої значення опції 'shell'. Іншими словами, відбувається практично те саме, що і при введенні команди
Тут це рядкове значення опції makeprg. Ви можете використовувати будь-яку необхідну програму, не тільки make.
Виявилося, що мій VIM за промовчанням shellpipe=>%s 2>$1. Схоже, є можливість взяти зовнішню утиліту командного рядка і якось засунути її в серединку цієї самої shellpipe.
Візьмемо iconv, яка є в проекті GnuWin32 на сторінці libiconv. Вона може приймати дані з файлу або консольного потоку. Я поклав її в C:\bin\, де вже лежать make, ctags, 7z, пара допоміжних командних файлів та пара-трійка dll. Не забуваємо і про залежності (Dependencies, а саме libintl3.dll лежить на сторінці утиліти).
Погрався з командним рядком окремо від VIM, щоб розібратися зі способом подачі даних на вхід та опціями. Потім спробував те саме, але вже в командному рядку VIM. Десь із другої чи третьої спроби вийшло щось таке:
Символ вертикальної риси, прогалини та зворотні слеші в повному шляху до утиліти екрануються зворотними слешами. Щодо повного шляху — можна, звичайно, так не перекручуватися, а прописати шлях до iconv у PATH, але особисто я з деяких пір не люблю цей спосіб: чотири IDE/CAD на робочому комп'ютері мають у своєму складі make, не цілкомсумісні між собою і всі прописані в PATH. Повні шляхи надійніші.
Загалом, запрацювало. Зазначений рядок я записав (без двокрапкового початку) у файл $VIM/vimfile/ftplugin/a6403.vim. Тепер «труба оболонки» змінюється на перекодуючу тільки при відкритті цього хитрого типу файлу. Ось результат:


Більш вдалого способу в різних інтернетах я не знайшов. Взагалі, ніякого способу не знайшов. Може, це мені так не пощастило? Але якщо комусь допоможе хоча б сама ідея впровадження в ланцюжок команди — мені буде приємно.
Хардкорна конфа за С++. Ми запрошуємо лише профі.