Отвечая на вопрос о шрифтах Powerline в linux консоли (см. комментарии к этому посту), я привел варианты, как этого можно добиться. Ни один вариант для меня не подошел в силу разных обстоятельств. Добавлять новые символы в консоли оказалось вообще не просто и какого-то единого алгоритма попросту не существует. Но мне все-таки удалось с этим справиться, и здесь я хочу поведать об этой истории успеха. Все, что здесь будет сказано, относится к Fedora 17, для других дистрибутивов действия могут слегка отличаться.
Картинка большая и кликабельная. Символы из Powerline видны в статусной строке vim (там где им и положено находиться), а также внутри присваиваемого значения переменной PROMPTLINE в функции proml редактируемого файла .bashrc (курсор находится между словами function и proml, создавая впечатление, что это одно слово, соединенное символом подчеркивания). Цветов в статусной строке нет по той простой причине, что в дефолтной схеме Powerline используется 256-цветная палитра, которая не работает в linux консоли. Так что если вы хотите нормальную цветную статусную строку Powerline в linux консоли, вам придется изменить дефолтную цветовую схему Powerline, или создать новую (схемы находятся в директории $HOME/.vim/autoload/Powerline/Colorschemes/). Также хочу отметить, что эта картинка была получена с помощью замечательной программы fbgrab из пакета fbcat, который я взял отсюда (кликнув на строке Fedora 17).
Итак, что нам понадобится для создания нового шрифта с символами из Powerline для linux консоли? Прежде всего, понимание того, что нам нужен шрифт с весьма специфичным форматом PSF, который, хотя и поддерживает Unicode mapping, все же не может содержать более 512 символов. В Fedora 17 psf шрифты находятся в директории /lib/kbd/consolefonts/. При включении режима Unicode в консоли c помощью команды unicode_start, попросту загружается новый шрифт с необходимыми символами, в частности у меня в Fedora это /lib/kbd/consolefonts/UniCyr_8x16.psf.gz, который содержит всего 256 символов. Если в вашей консоли используется шрифт terminus, то название файла будет, естественно, другим. Таблица соответствия с символами Unicode прописана внутри файла шрифта, и просмотреть ее можно с помощью команды psfgettable. Таким образом, задача сводится к созданию нового psf файла, в который добавлены символы из Powerline, при этом общее количество символов в файле не должно превышать 512. В дальнейшем, в качестве базового шрифта я буду использовать UniCyr_8x16.psf.
Что нам понадобится из программного обеспечения? Первое - программа otf2bdf для создания шрифта в промежуточном формате bdf: ее в Fedora 17 можно установить с помощью yum. Второе - программа gbdfed для конвертации шрифта bdf в формат psf: она также устанавливается с помощью yum. Третье - пакет PSF tools для манипуляции с psf шрифтами: его я скачал отсюда. Четвертое - удобный текстовый редактор (например, vim) для удаления артефактов конвертации в текстовом представлении шрифта. Пятое - исходный файл с базовыми кириллическими символами, в который мы внедрим новые символы Powerline, как я уже говорил это будет файл UniCyr_8x16.psf из директории /lib/lbd/consolefonts/.
Итак, приступим. Первое, что мы сделаем - это выделим все символы из Powerline (всего их девять) в отдельный шрифт в формате bdf. Эта задача вполне по плечу программе otf2bdf. Исходный файл должен быть получен с помощью программы fontpatcher из плагина Powerline и иметь формат otf или ttf (см. подробности здесь). У меня данный файл называется DejaVuSansMonoForPowerline.ttf. Программа otf2bdf должна знать, какие символы нам нужны, а также соответствующие им значения Unicode. Для этого мы создадим вспомогательный файл dvusmpl.bdfmap (название не имеет значения), в котором зададим этот маппинг:
REGISTRY ISO10646
ENCODING 1
0x60 0x2B60
0x61 0x2B61
0x62 0x2B62
0x63 0x2B63
0x64 0x2B64
0x80 0x2B80
0x81 0x2B81
0x82 0x2B82
0x83 0x2B83
Строки REGISTRY и ENCODING могут содержать достаточно произвольные значения: в нашем случае они не будут важны. Далее прописан маппинг номер символа : значение Unicode. Номера символов в принципе тоже не имеют значения, однако здесь я сопоставил их со значениями Unicode, которые соответствуют символам Powerline. Первая попытка:
otf2bdf -v -c M -l '96_131' -o dvusmpl.bdf -m dvusmpl.bdfmap DejaVuSansMonoForPowerline.ttf
не увенчается успехом из-за размера сгенерированного шрифта, который окажется 12x20 вместо 8x16 (bdf формат имеет текстовое представление и размер шрифта можно найти в строке FONTBOUNDINGBOX в заголовке файла). otf2bdf позволяет настроить размер шрифта с помощью опций -rh и -rv, значения которых, однако, соответствуют не количеству пикселов по горизонтали и вертикали, а количеству точек на дюйм, поэтому поиск подходящих значений - задача творческая. После нескольких попыток я наконец подобрал подходящие значения для этих опций:
otf2bdf -v -c M -rh 66 -rv 86 -l '96_131' -o dvusmpl.bdf -m dvusmpl.bdfmap DejaVuSansMonoForPowerline.ttf
Опция -c M указывает на то, что мы хотим создать моноширинный шрифт, а опция -l '96_131' задает диапазон символов для генерации (десятиричное число 91 соответствует шестнадцатиричному 0x60, a 131 - 0x83).
Теперь у нас есть файл c символами Powerline в формате bdf. Открываем его в программе gbdfed, убеждаемся, что все 9 символов на месте (скорее всего gbdfed разобьет шрифт на 2 страницы, при этом первые 5 символов окажутся на первой, а оставшиеся 4 - на второй), и экспортируем его в формат PSF (в меню File программы). После экспорта файла у нас появится файл dvusmpl.psfu.
Следующий шаг - переводим файл dvusmpl.psfu в текстовый формат с помощью программы psf2txt из PSF Tools.
psf2txt dvusmpl.psfu dvusmpl.txt
Открываем dvusmpl.txt в текстовом редакторе и правим псевдографические изображения символов по своему вкусу: это необходимо, так как odf2bdf в процессе масштабирования шрифта исказила исходные символы (главным образом стрелки). Поскольку я все это уже проделал, то результат (с дополнительными правками - см. ниже) проще скачать отсюда.
Теперь берем исходный PSF файл UniCyr_8x16.psf.gz, раззиповываем его и переводим в текстовый формат:
psf2txt UniCyr_8x16.psf UniCyr_8x16ForPowerline.txt
В конец нового файла UniCyr_8x16ForPowerline.txt вставляем содержимое файла dvusmpl.txt, меняем строки // Character 0 .. 8 во вставленном участке на // Character 256 .. 264. Также добавляем во вставленном участке строки с Unicode информацией для каждого отдельного символа таким же образом, как это сделано для символов исходного psf шрифта. Если вы скачали выложенный мною файл dvusmpl.txt, то достаточно просто добавить его в конец файла UniCyr_8x16ForPowerline.txt, так как все необходимые изменения в нем уже есть. Теперь идем в начало файла, ищем строку Length: 256 и заменяем ее на Length: 265 (мы ведь добавили 9 новых символов).
Переводим UniCyr_8x16ForPowerline.txt в формат psf c помощью программы txt2psf из PSF Tools:
txt2psf UniCyr_8x16ForPowerline.txt UniCyr_8x16ForPowerline.psf
Можно убедиться, что новые символы присутствуют в UniCyr_8x16ForPowerline.psf:
psfgettable PowerLineSymbols1.psf | grep -i 2b80
Зипуем файл и кладем его в директорию /lib/kbd/consolefonts/. Логинимся в виртуальной консоли и загружаем новый шрифт:
unicode_start UniCyr_8x16ForPowerline
Теперь открываем vim и смотрим, присутствуют ли в статусной строке символы из Powerline.
Если есть желание загружать новый шрифт каждый раз при входе в систему из виртуальной консоли, то можно добавить строку unicode_start UniCyr_8x16ForPowerline для linux консоли в какой-нибудь файл из директории /etc/profile.d/ (см. подробно здесь). Кроме того, теперь и в linux консоли вы сможете сделать приглашение командной строки более привлекательным (см. здесь).
Update. Выяснилось, что дефолтный консольный Unicode шрифт в Fedora 17 - это latarcyrheb-sun16 (загляните внутрь скрипта /usr/bin/unicode_start и поймете почему). В шрифте определены 512 символов, поэтому, если брать его за основу, следует не добавлять дополнительные символы, а заменить те из существующих, которые вы вряд ли будете использовать, например в позициях 460 - 488 находятся символы арабского алфавита, и если вы не читаете тексты на арабском, то можете смело вставлять новые символы куда-нибудь внутрь этого диапазона.
Последние изменения. Картинка:
Все цвета в статусной строке присутствуют, Unicode символы на месте (в т.ч. стрелочки в окне tagbar), я специально вышел из vim, чтобы показать, что в строке приглашения тоже находятся символы из Powerline.
За базовый шрифт я взял /lib/kbd/consolefonts/latarcyrheb-sun16.psfu.gz. Распаковываем, переводим в текст с помощью psf2txt, заменяем символы с 460 по 472 этим. Переводим обратно в psf:
txt2psf latarcyrheb-sun16.txt latarcyrheb-sun16_vim-unicode.psfu
Зипуем latarcyrheb-sun16_vim-unicode.psfu и кладем в /lib/kbd/consolefonts/. Файл /etc/profile.d/console_unicode.sh теперь выглядит так:
if [ "$TERM" = "linux" ]; then
unicode_start latarcyrheb-sun16_vim-unicode
export CONSOLEFONT_HAS_VIM_UNICODE_SYMB=1
fi
Изменения в файле $HOME/.bashrc:
case $COLORTERM in
gnome*|mate*|konsole*)
TERM=xterm-256color
;;
esac
[ -n "$XTERM_SHELL" ] && COLORTERM=xterm-256color
function proml
{
case $COLORTERM in
gnome*|mate*|konsole*)
local PROMPTLINE="\[\033[38;5;167m\]\$(date +%d/%m/%y\ %H:%M)⮁⮁ \
\[\033[38;5;173m\]\u@\[\033[38;5;140m\]\h⮁⮁\[\033[38;5;173m\] \W ⮀\[\033[0m\] "
local PROMPTLINE2='\[\033[38;5;196m\]⮀\[\033[0m\] '
;;
xterm*)
local PROMPTLINE="\[\033[38;5;167m\](\$(date +%d/%m/%y\ %H:%M))\
\[\033[38;5;173m\][\u@\[\033[38;5;140m\]\h\[\033[38;5;173m\] \W]$\[\033[0m\] "
local PROMPTLINE2='\[\033[38;5;196m\]>\[\033[0m\] '
;;
*)
if [ "$TERM" = "linux" ] && \
[ -n "$CONSOLEFONT_HAS_VIM_UNICODE_SYMB" ] ; then
local PROMPTLINE="\[\033[32m\]\$(date +%d/%m/%y\ %H:%M)⮁⮁ \
\[\033[0m\]\u@\[\[\033[1;34m\]\h\[\033[0m\]⮁⮁\[ \W \033[32m\]⮀\[\033[0m\] "
local PROMPTLINE2='\[\033[31m\]⮀\[\033[0m\] '
else
local PROMPTLINE="(\$(date +%d/%m/%y\ %H:%M))[\u@\h \W]$ "
local PROMPTLINE2='> '
fi
;;
esac
PS1=$PROMPTLINE
PS2=$PROMPTLINE2
}
proml
unset proml
Изменения в $HOME/.vimrc:
" ---- Powerline settings
" ----
" disable Unicode symbols in linux console if font does not support them
let g:DisableUnicodeSymbols = &term =~? '^linux' &&
\ empty($CONSOLEFONT_HAS_VIM_UNICODE_SYMB)
let g:Powerline_theme = 'default'
" solarized theme is suitable for linux console
if &t_Co < 256
let g:Powerline_colorscheme = 'solarized'
else
let g:Powerline_colorscheme = 'default'
endif
" fancy symbols need patched font!
if g:DisableUnicodeSymbols
let g:Powerline_symbols = 'compatible'
else
let g:Powerline_symbols = 'fancy'
endif
" do not use Powerline in simple console terminals
let g:DisablePowerline = &term =~? '^linux' && 0
if g:DisablePowerline
let g:Powerline_loaded = 0
endif
if !empty($TMPDIR)
let g:Powerline_cache_file = $TMPDIR."/Powerline_".$USER."_".
\ g:Powerline_theme."_".g:Powerline_colorscheme."_".
\ g:Powerline_symbols.".cache"
else
let g:Powerline_cache_file = '/tmp/Powerline_'.$USER.'_'.
\ g:Powerline_theme.'_'.g:Powerline_colorscheme.'_'.
\ g:Powerline_symbols.'.cache'
endif
(я сюда еще правильную обработку кэша цветовой схемы Powerline добавил).
Да, и самое главное - патч для цветовой схемы solarized.vim. Без него статусная строка Powerline в консоли правильно работать не будет!
--- autoload/Powerline/Colorschemes/solarized.vim 2012-11-27 13:46:28.923529118 +0400
+++ autoload/Powerline/Colorschemes/solarized.vim.new 2012-11-27 13:35:09.794349678 +0400
@@ -3,19 +3,19 @@
" N = no focus
" 16 hex colors as defined on http://ethanschoonover.com/solarized
call Pl#Hi#Allocate({
- \ 'base03' : [8, 0x002b36],
+ \ 'base03' : [&t_Co > 8 ? 8 : '0*', 0x002b36],
\ 'base02' : [0, 0x073642],
- \ 'base01' : [10, 0x586e75],
- \ 'base00' : [11, 0x657b83],
- \ 'base0' : [12, 0x839496],
- \ 'base1' : [14, 0x93a1a1],
+ \ 'base01' : [&t_Co > 8 ? 10 : '2*', 0x586e75],
+ \ 'base00' : [&t_Co > 8 ? 11 : '6*', 0x657b83],
+ \ 'base0' : [&t_Co > 8 ? 12 : '1*', 0x839496],
+ \ 'base1' : [&t_Co > 8 ? 14 : '3*', 0x93a1a1],
\ 'base2' : [7, 0xeee8d5],
- \ 'base3' : [15, 0xfdf6e3],
+ \ 'base3' : [&t_Co > 8 ? 15 : '7*', 0xfdf6e3],
\ 'yellow' : [3, 0xb58900],
- \ 'orange' : [9, 0xcb4b16],
+ \ 'orange' : [&t_Co > 8 ? 9 : '4*', 0xcb4b16],
\ 'red' : [1, 0xdc322f],
\ 'magenta' : [5, 0xd33682],
- \ 'violet' : [13, 0x6c71c4],
+ \ 'violet' : [&t_Co > 8 ? 13 : '5*', 0x6c71c4],
\ 'blue' : [4, 0x268bd2],
\ 'cyan' : [6, 0x2aa198],
\ 'green' : [2, 0x859900],
(зафайлил баг в Powerline, надеюсь починят).