1 "{{{1 Encoding
   2 scriptencoding utf-8
   3 "{{{1 Символы
   4 "
   5 " ╔═╦╤╗
   6 " ║ ╠╧╣
   7 "
   8 "
   9 "╲ ╱
  10 " ╳
  11 "
  12 " g/nr/exe "normal $Fxh\"tdt)i\"&#\<C-r>=@t+0\<C-m>;\"\<C-o>T(\<C-o>dFn\<C-o>f)\<C-o>x"
  13 if !exists("g:transsymb")
  14     let g:transsymb={
  15                 \"ru": {
  16                     \'a''а',
  17                     \'b''б',
  18                     \'c': {
  19                         \"none":   'ц',
  20                         \"'":  'ч',
  21                         \'x':  'ч',
  22                         \'h':  'ч'
  23                         \},
  24                     \'d''д',
  25                     \'e': {
  26                         \"none":   'е',
  27                         \"'":  'э',
  28                         \"x":  'э',
  29                         \'"':  'ё'
  30                         \},
  31                     \'f''ф',
  32                     \'g''г',
  33                     \'h''х',
  34                     \'i': {
  35                         \"none":   'и',
  36                         \"'"'й',
  37                         \'x''й'
  38                         \},
  39                     \'j''й',
  40                     \'k''к',
  41                     \'l''л',
  42                     \'m''м',
  43                     \'n''н',
  44                     \'o': {
  45                         \"none":   'о',
  46                         \"'"'ё',
  47                         \'x''ё'
  48                         \},
  49                     \'p''п',
  50                     \'q''я',
  51                     \'r''р',
  52                     \'s': {
  53                         \"none":   'с',
  54                         \'h''ш'
  55                         \},
  56                     \'t''т',
  57                     \'u': {
  58                         \"none":   'у',
  59                         \"'"'ю',
  60                         \'x''ю'
  61                         \},
  62                     \'v''в',
  63                     \'w': {
  64                         \"none":   'ш',
  65                         \"'"'щ',
  66                         \'x''щ',
  67                         \'h''щ'
  68                         \},
  69                     \'x': {
  70                         \"none":   'ь',
  71                         \'x''ъ',
  72                         \"options": {
  73                             \"capital""none"
  74                             \}
  75                         \},
  76                     \'X': {
  77                         \"none":   'ъ',
  78                         \"options":{
  79                             \"capital""none"
  80                             \}
  81                         \},
  82                     \'y''ы',
  83                     \'z': {
  84                         \"none"'з',
  85                         \'h':    'ж'
  86                         \},
  87                     \'''': {
  88                         \"none":   'ь',
  89                         \'''':     nr2char(0x201C),
  90                         \"options": {
  91                             \"capital""none"
  92                             \}
  93                         \},
  94                     \'"': {
  95                         \"none":   'ъ',
  96                         \"options": {
  97                             \"capital""none"
  98                             \}
  99                         \},
 100                     \'<': {
 101                         \'<''«',
 102                         \'='nr2char(0x2264)
 103                         \},
 104                     \'>': {
 105                         \'>''»',
 106                         \'='nr2char(0x2265)
 107                         \},
 108                     \'+': {
 109                         \'-'nr2char(0x00b1)
 110                         \},
 111                     \'(': {
 112                         \'c': {
 113                             \')'nr2char(0x00a9),
 114                             \"options": {
 115                                 \"capital""none"
 116                                 \}
 117                             \},
 118                         \'r': {
 119                             \')'nr2char(0x00ae),
 120                             \"options": {
 121                                 \"capital""none"
 122                                 \}
 123                             \}
 124                         \},
 125                     \'^': {
 126                         \'t': {
 127                             \')'nr2char(0x2122),
 128                             \'m'nr2char(0x2122),
 129                             \"options": {
 130                                 \"capital""none"
 131                                 \}
 132                             \}
 133                         \},
 134                     \'#''№',
 135                     \'.': {
 136                         \'.': {
 137                             \'.''…'
 138                             \}
 139                         \},
 140                     \'-': {
 141                         \'-': {
 142                             \"none"nr2char(0x2013),
 143                             \'-'nr2char(0x2014)
 144                             \}
 145                         \},
 146                     \'~'nr2char(0x00a0),
 147                     \'_': {
 148                         \'<': {
 149                             \"none"nr2char(0x2039),
 150                             \'<':    nr2char(0x226A)
 151                             \},
 152                         \'>': {
 153                             \"none"nr2char(0x203A),
 154                             \'>':    nr2char(0x226B)
 155                             \},
 156                         \'/':  nr2char(0x00F7),
 157                         \'`': {
 158                             \"none"nr2char(0x2018),
 159                             \'!':    nr2char(0x201B),
 160                             \'`':    nr2char(0x201F)
 161                             \},
 162                         \',':  nr2char(0x201A),
 163                         \''''nr2char(0x2019),
 164                         \'%':  nr2char(0x2030),
 165                         \'.':  nr2char(0x2219),
 166                         \'0':  nr2char(0x221E),
 167                         \'\':  nr2char(0x221a),
 168                         \'u':  nr2char(0x2229),
 169                         \'U':  nr2char(0x222a),
 170                         \'i':  {
 171                             \"none"nr2char(0x222b),
 172                             \'i':    nr2char(0x222c)
 173                             \},
 174                         \'o':  nr2char(0x222e),
 175                         \'~':  nr2char(0x2248),
 176                         \'n':  nr2char(0x2205),
 177                         \'c':  nr2char(0x2103)
 178                         \},
 179                     \',': {
 180                         \','nr2char(0x201E)
 181                         \},
 182                     \'`': {
 183                         \'`'nr2char(0x201D)
 184                         \},
 185                     \"checked""\<SID>"
 186                     \},
 187                 \"ru:html": {
 188                     \'a''а',
 189                     \'b''б',
 190                     \'c': {
 191                         \"none":   'ц',
 192                         \"'":  'ч',
 193                         \'x':  'ч',
 194                         \'h':  'ч'
 195                         \},
 196                     \'d''д',
 197                     \'e': {
 198                         \"none":   'е',
 199                         \"'":  'э',
 200                         \"x":  'э',
 201                         \'"':  'ё'
 202                         \},
 203                     \'f''ф',
 204                     \'g''г',
 205                     \'h''х',
 206                     \'i': {
 207                         \"none":   'и',
 208                         \"'"'й',
 209                         \'x''й'
 210                         \},
 211                     \'j''й',
 212                     \'k''к',
 213                     \'l''л',
 214                     \'m''м',
 215                     \'n''н',
 216                     \'o': {
 217                         \"none":   'о',
 218                         \"'"'ё',
 219                         \'x''ё'
 220                         \},
 221                     \'p''п',
 222                     \'q''я',
 223                     \'r''р',
 224                     \'s': {
 225                         \"none":   'с',
 226                         \'h''ш'
 227                         \},
 228                     \'t''т',
 229                     \'u': {
 230                         \"none":   'у',
 231                         \"'"'ю',
 232                         \'x''ю'
 233                         \},
 234                     \'v''в',
 235                     \'w': {
 236                         \"none":   'ш',
 237                         \"'"'щ',
 238                         \'x''щ',
 239                         \'h''щ'
 240                         \},
 241                     \'x': {
 242                         \"none":   'ь',
 243                         \'x''ъ',
 244                         \"options": {
 245                             \"capital""none"
 246                             \}
 247                         \},
 248                     \'X': {
 249                         \"none":   'ъ',
 250                         \"options":{
 251                             \"capital""none"
 252                             \}
 253                         \},
 254                     \'y''ы',
 255                     \'z': {
 256                         \"none"'з',
 257                         \'h':    'ж'
 258                         \},
 259                     \'''': {
 260                         \"none":   'ь',
 261                         \'''':     "&#8220;",
 262                         \"options": {
 263                             \"capital""none"
 264                             \}
 265                         \},
 266                     \'"': {
 267                         \"none":   'ъ',
 268                         \"options": {
 269                             \"capital""none"
 270                             \}
 271                         \},
 272                     \'<': {
 273                         \"none""&lt;",
 274                         \'<':    "&laquo;"
 275                         \},
 276                     \'>': {
 277                         \"none""&gt;",
 278                         \'>':    "&raquo;"
 279                         \},
 280                     \'+': {
 281                         \'-'"&plusmn;"
 282                         \},
 283                     \'(': {
 284                         \'c': {
 285                             \')'"&copy;",
 286                             \"options": {
 287                                 \"capital""none"
 288                                 \}
 289                             \},
 290                         \'r': {
 291                             \')'"&reg;",
 292                             \"options": {
 293                                 \"capital""none"
 294                                 \}
 295                             \}
 296                         \},
 297                     \'^': {
 298                         \'t': {
 299                             \')'"&trade;",
 300                             \'m'"&trade;",
 301                             \"options": {
 302                                 \"capital""none"
 303                                 \}
 304                             \}
 305                         \},
 306                     \'#'"&#8470;",
 307                     \'.': {
 308                         \'.': {
 309                             \'.'"&hellip;"
 310                             \}
 311                         \},
 312                     \'-': {
 313                         \'-': {
 314                             \"none""&ndash;",
 315                             \'-'"&mdash;"
 316                             \}
 317                         \},
 318                     \'&'"&amp;",
 319                     \'~'"&nbsp;",
 320                     \'['"&#91;",
 321                     \']'"&#93;",
 322                     \'_': {
 323                         \'<': {
 324                             \"none""&#8249;",
 325                             \'<':    "&#8810;"
 326                             \},
 327                         \'>': {
 328                             \"none""&#8250;",
 329                             \'>':    "&#8811;"
 330                             \},
 331                         \'/':  "&#247;",
 332                         \'`': {
 333                             \"none""&#8216;",
 334                             \'!':    "&#8219;",
 335                             \'`':    "&#8223;"
 336                             \},
 337                         \',':  "&#8218;",
 338                         \''''"&#8217;",
 339                         \'%':  "&#8240;",
 340                         \'.':  "&#8729;",
 341                         \'0':  "&#8734;",
 342                         \'\':  "&#8730;",
 343                         \'u':  "&#8745;",
 344                         \'U':  "&#8746;",
 345                         \'i':  {
 346                             \"none""&#8747;",
 347                             \'i':    "&#8748;"
 348                             \},
 349                         \'o':  "&#8750;",
 350                         \'~':  "&#8776;",
 351                         \'n':  "&#8709;",
 352                         \'c':  "&#8451;"
 353                         \},
 354                     \',': {
 355                         \','"&#8222;"
 356                         \},
 357                     \'`': {
 358                         \'`'"&#8221;"
 359                         \},
 360                     \"checked""\<SID>"
 361                     \},
 362                 \"ru:latex": {
 363                     \'a''а',
 364                     \'b''б',
 365                     \'c': {
 366                         \"none":   'ц',
 367                         \"'":  'ч',
 368                         \'x':  'ч',
 369                         \'h':  'ч'
 370                         \},
 371                     \'d''д',
 372                     \'e': {
 373                         \"none":   'е',
 374                         \"'":  'э',
 375                         \"x":  'э',
 376                         \'"':  'ё'
 377                         \},
 378                     \'f''ф',
 379                     \'g''г',
 380                     \'h''х',
 381                     \'i': {
 382                         \"none":   'и',
 383                         \"'"'й',
 384                         \'x''й'
 385                         \},
 386                     \'j''й',
 387                     \'k''к',
 388                     \'l''л',
 389                     \'m''м',
 390                     \'n''н',
 391                     \'o': {
 392                         \"none":   'о',
 393                         \"'"'ё',
 394                         \'x''ё'
 395                         \},
 396                     \'p''п',
 397                     \'q''я',
 398                     \'r''р',
 399                     \'s': {
 400                         \"none":   'с',
 401                         \'h''ш'
 402                         \},
 403                     \'t''т',
 404                     \'u': {
 405                         \"none":   'у',
 406                         \"'"'ю',
 407                         \'x''ю'
 408                         \},
 409                     \'v''в',
 410                     \'w': {
 411                         \"none":   'ш',
 412                         \"'"'щ',
 413                         \'x''щ',
 414                         \'h''щ'
 415                         \},
 416                     \'x': {
 417                         \"none":   'ь',
 418                         \'x''ъ',
 419                         \"options": {
 420                             \"capital""none"
 421                             \}
 422                         \},
 423                     \'X': {
 424                         \"none":   'ъ',
 425                         \"options":{
 426                             \"capital""none"
 427                             \}
 428                         \},
 429                     \'y''ы',
 430                     \'z': {
 431                         \"none"'з',
 432                         \'h':    'ж'
 433                         \},
 434                     \'''': {
 435                         \"none":   'ь',
 436                         \"options": {
 437                             \"capital""none"
 438                             \}
 439                         \},
 440                     \'"': {
 441                         \"none":   'ъ',
 442                         \"options": {
 443                             \"capital""none"
 444                             \}
 445                         \},
 446                     \'<': {
 447                         \'='"\\leqslant"
 448                         \},
 449                     \'>': {
 450                         \'='"\\geqslant"
 451                         \},
 452                     \'+': {
 453                         \'-'"\\pm"
 454                         \},
 455                     \'(': {
 456                         \'c': {
 457                             \')'"\\copyright",
 458                             \"options": {
 459                                 \"capital""none"
 460                                 \}
 461                             \},
 462                         \'r': {
 463                             \')'"\\textregistered",
 464                             \"options": {
 465                                 \"capital""none"
 466                                 \}
 467                             \}
 468                         \},
 469                     \'^': {
 470                         \'t': {
 471                             \')'"\\texttrademark",
 472                             \'m'"\\texttrademark",
 473                             \"options": {
 474                                 \"capital""none"
 475                                 \}
 476                             \},
 477                         \'s': {
 478                             \')'"\\textservicemark",
 479                             \'m'"\\textservicemark",
 480                             \"options": {
 481                                 \"capital""none"
 482                                 \}
 483                             \}
 484                         \},
 485                     \'#'"\\textnumero",
 486                     \'.': {
 487                         \'.': {
 488                             \'.'"\\dots"
 489                             \}
 490                         \},
 491                     \'-': {
 492                         \'+'"\\mp"
 493                         \},
 494                     \'_': {
 495                         \'<': {
 496                             \"none""\\textlangel",
 497                             \'<':    "\\ll"
 498                             \},
 499                         \'>': {
 500                             \"none""\\textrangel",
 501                             \'>':    "\\gg"
 502                             \},
 503                         \'/':  "\\div",
 504                         \'`': {
 505                             \"none"nr2char(0x2018),
 506                             \'!':    nr2char(0x201B)
 507                             \},
 508                         \',':  nr2char(0x201A),
 509                         \''''nr2char(0x2019),
 510                         \'%':  "\\textperthousand",
 511                         \'.':  "\\cdot",
 512                         \'0':  "\\infty",
 513                         \'\':  "\\sqrt",
 514                         \'u':  "\\bigcap",
 515                         \'U':  "\\bigcup",
 516                         \'i':  {
 517                             \"none""\\int",
 518                             \'i': {
 519                                 \"none""\\iint",
 520                                 \"i": {
 521                                     \"none""\\iiint",
 522                                     \"i":    "\\iiiint"
 523                                     \}
 524                                 \}
 525                             \},
 526                         \'o':  "\\oint",
 527                         \'O':  "\\textohm",
 528                         \'~':  "\\approx",
 529                         \'c':  "\\textcelsius",
 530                         \'n':  "\\varnothing"
 531                         \},
 532                     \"checked""\<SID>"
 533                     \},
 534                 \}
 535 endif
 536 "{{{1 Инициализация
 537 if !exists("g:trPluginloaded")
 538     augroup TransliterationScript
 539         autocmd!
 540         execute "autocmd FuncUndefined TransliterateString source \<sfile>"
 541         execute "autocmd FuncUndefined PrintTransTable source \<sfile>"
 542         execute "autocmd FuncUndefined InitToF source \<sfile>"
 543         execute "autocmd FuncUndefined TrShow source \<sfile>"
 544     augroup END
 545     execute "command -range=% -nargs=? TrText ".
 546                 \"execute \"source ".expand("<sfile>")."\" | ".
 547                 \"call \<SID>transCommandFunc(<line1>, <line2>, 0, <args>)"
 548     execute "command -range=% -nargs=? ".
 549                 \"TrSelection ".
 550                 \"execute \"source ".expand("<sfile>")."\" | ".
 551                 \"call \<SID>transCommandFunc(<line1>, <line2>, 1, <args>)"
 552     execute "command -nargs=? StartToF call InitToF(<args>)"
 553     execute "command -nargs=? TrShow echo TrShow(<args>)"
 554     let g:trPluginloaded=0
 555     finish
 556 endif
 557 if g:trPluginloaded
 558     finish
 559 endif
 560 augroup TransliterationScript
 561     autocmd!
 562 augroup END
 563 let g:trPluginloaded=1
 564 "{{{1 Справка
 565 "
 566 " представляет собой плагин, занимающийся переводом символов или их
 567 " последовательностей в другие символы или последовательности. Необходим
 568 " в случае отсутствия целевых символов в текущей раскладке клавиатуры или
 569 " в случае нежелания использования раскладок, в которых целевые символы
 570 " присутствуют.
 571 "
 572 " ==============================================================================
 573 " 1. Использование плагина                                     *trplugin-usage*
 574 "
 575 " Плагин предоставляет функции |TransliterateString|(string, [transsymb])
 576 " (преобразует текст), |CheckTransTable|(transsymb) (проверяет правильность
 577 " таблицы транслитерации), |InitToF|([transsymb]) (запускает и останавливает
 578 " режим транслитерации по мере ввода) и |TrShow|([transsymb], [colnum])
 579 " (возвращает таблицу транслитерации).
 580 "
 581 " Плагин также предоставляет три команды: |:TrText|, |:TrSelection|, |:StartToF|
 582 " и |:TrShow|. Первая команда преобразует заданный диапозон линий, вторая
 583 " предназначена для преобразования выделения, третья предоставляет возможность
 584 " проводить транслитерацию по мере ввода, а четвёртая выводит таблицу
 585 " транслитерации на экран.
 586 "
 587 " ==============================================================================
 588 " 2. Таблица транслитерации               *transsymb* *trplugin-translit-table*
 589 "
 590 " Таблица транслитерации представляет собой словарь, содержащий информацию
 591 " о преобразованиях символов. Ключами словаря служат одиночные символы,
 592 " а значениями — либо символы, в которые будут преобразованы клучи при
 593 " транслитерации, либо словарь с дополнительной информацией, которая может
 594 " представлять собой различные настройки, уникальные для данного символа или
 595 " последовательности, вторые символы последовательностей символов, начинающиеся
 596 " с данного, а также информация о том, как будет преобразован символ, если он не
 597 " вошел ни в одну последовательность.
 598 "
 599 " В случае, если значением, соответствующем некоторому односимвольному ключу,
 600 " является словарь, то он должен иметь структуру, идентичную исходной таблице.
 601 " Список специальных неодносимвольных ключей:
 602 "
 603 " Ключ      Значение    ~
 604 " other Если этот ключ существует, то все неизвестные символы будут заменены на
 605 "       соответствующее ему значение. При транслитерации по мере ввода ключ
 606 "       игнорируется.
 607 " none  Использование этого ключа имеет смысл только для последовательностей
 608 "       символов, если ключ находится непосредственно в корне таблицы
 609 "       транслитерации, то он будет проигнорирован. На значение этого ключа
 610 "       будет заменён символ или последовательность символов в случае, если
 611 "       следующие за последовательностью символы не входят ни в одну из
 612 "       начинающихся с данной последовательность.
 613 " options       Данный ключ предоставляет способ установки настроек, уникальных
 614 "       для данных последовательности или символа. В настоящий момент существует
 615 "       всего лишь одна такая настройка, устанавливающая невозможность перевода
 616 "       символа в верхний регистр — «capital», — принимающая только одно
 617 "       значение — «none»; все остальные возможные значения неверны.
 618 " checked       Данный ключ служит для того, чтобы скрипт мог удостовериться,
 619 "       что данная таблица транслитерации не нуждается в проверке. При
 620 "       отсутствии ключа или его неправильном значении таблица будет проверена
 621 "       и в неё будет добавлен ключ «checked» со значением „\<SID>“.
 622 "
 623 " Примеры: >
 624 "       { 's': {
 625 "           \"none": 'с',
 626 "           \'c': {
 627 "               \'h': 'щ'}
 628 "           \},
 629 "        \'c': {
 630 "           \"none": 'ц',
 631 "           \'h': 'ч'
 632 "           \},
 633 "        \'h': 'х',
 634 "        \'x': {
 635 "           \"none": 'ь',
 636 "           \"options": {
 637 "               \"capital": "none"
 638 "               \}
 639 "           \},
 640 "        \'y': 'ы',
 641 "        \'Y': 'У'
 642 "       \}
 643 "
 644 " Результат: >
 645 "        «s c h sc ch sch x X y Y» => «с ц х сц ч щ ь X ы У»
 646 "
 647 " ==============================================================================
 648 " 3. Команды                                               *trplugin-commands*
 649 "
 650 "                                                                    *:TrText*
 651 " :[range]TrText [transsymb]
 652 "               Преобразует диапозон линий [range], используя таблицу
 653 "               [transsymb]. Если таблица не указана, то используется таблица
 654 "               по умолчанию (|g:trPluginDefaultTranssymb|).
 655 " :TrSelection [transsymb]                                      *:TrSelection*
 656 "               Преобразует последнее выделение, используя таблицу [transsymb].
 657 "               Если таблица не указана, то используется таблица по умолчанию
 658 "               (|g:trPluginDefaultTranssymb|).
 659 " :StartToF [transsymb]                                            *:StartToF*
 660 "               Включает режим транслитерации по мере ввода текста
 661 "               с использованием таблицы [transsymb]. Если таблица не указана,
 662 "               то используется таблица по умолчанию
 663 "               (|g:trPluginDefaultTranssymb|). Если вместо таблицы указать
 664 "               0 или "stop", то команда полностью прекратит транслитерацию по
 665 "               мере ввода и уберёт все привязки. См. |trplugin-ToF|.
 666 " :TrShow [transsymb]                                                *:TrShow*
 667 "               Выводит на экран таблицу транслитерации [transsymb]
 668 "               в удобочитаемом виде. Если таблица не указана, то используется
 669 "               таблица по умолчанию (|g:trPluginDefaultTranssymb|).
 670 "
 671 " ==============================================================================
 672 " 4. Функции                                               *trplugin-functions*
 673 "
 674 "                                                        *TransliterateString*
 675 " TransliterateString(string, [transsymb])              *TransliterateString()*
 676 "               Преобразует строку «string», используя таблицу [transsymb]. Если
 677 "               таблица не указана, то используется таблица по умолчанию
 678 "               (|g:trPluginDefaultTranssymb|). Возвращает преобразованную
 679 "               строку или пустую строку, если возникли ошибки.
 680 "
 681 "               Пример использования: >
 682 "                        TransliterateString(input("Translit: "))
 683 "
 684 " CheckTransTable(transsymb)              *CheckTransTable* *CheckTransTable()*
 685 "               Производит проверку таблицы [transsymb]. Запускается
 686 "               автоматически всеми остальными функциями, если в таблице
 687 "               отсутствует ключ «checked» со значением „\<SID>“.
 688 "
 689 " InitToF([transsymb])                                    *InitToF* *InitToF()*
 690 "               Включает режим транслитерации по мере ввода (|trplugin-ToF|).
 691 "               При этом используется таблица [transsymb]. Если вместо таблицы
 692 "               указать 0 или "stop", то функция полностью прекратит
 693 "               транслитерацию по мере ввода и уберёт все привязки. Если таблица
 694 "               не указана, то используется таблица по умолчанию
 695 "               (|g:trPluginDefaultTranssymb|).
 696 "
 697 " TrShow([transsymb], [colnum])                             *TrShow* *TrShow()*
 698 "               Возвращает таблицу транслитерации [transsymb] в удобочитаемом
 699 "               виде в [colnum] столбцов. Если таблица не указана, или вместо
 700 "               таблицы указано клучевое слово «default» то используется таблица
 701 "               по умолчанию (|g:trPluginDefaultTranssymb| или |b:transsymb|).
 702 "               Если не указано количество столбцов, то таблица по ширине будет
 703 "               соответствовать ширине текущего окна.
 704 "
 705 " ==============================================================================
 706 " 5. Настройки                                               *trplugin-options*
 707 "
 708 " g:trPluginBrkSeqSymbs                                 *g:trPluginBrkSeqSymbs*
 709 "               Отвечает за то, какая последовательность символов прерывает
 710 "               последовательность преобразуемых символов. Нужна в случае, если
 711 "               вам требуется, чтобы части последовательности преобразовывались
 712 "               отдельно. Последовательность не печатается даже если не
 713 "               существует последовательности, которую она могла бы прервать.
 714 "               Допустимые значения — любой |List|, содержащий список
 715 "               односимвольных строк. Значение по умолчанию — ['@'].
 716 "
 717 "               Примеры: >
 718 "                         «ch» => «ч»
 719 "                        «c@h» => «цх»
 720 "                        «@@@» => «»
 721 "
 722 " g:trPluginEscNext                                         *g:trPluginEscNext*
 723 "               Содержит последовательность символов, которые экранируют
 724 "               следующий за ею символ, предотвращая его преобразование. Также,
 725 "               как и в предыдухшем случае допустимое значение — |List|,
 726 "               содержащий список односимвольных строк. Игнорируется при
 727 "               транслитерации по мере ввода.
 728 "               Значение по умолчанию — ['\'].
 729 "
 730 "               Пример: >
 731 "                         «sh» => «ш»
 732 "                        «\sh» => «sх»
 733 "
 734 " g:trPluginStopStartTrSymbs                      *g:trPluginStopStartTrSymbs*
 735 "               Содержит две последовательности, первая из которых представляет
 736 "               из себя условие прекращения преобразований (тем не менее,
 737 "               экранирующая последовательность работает), а второе — условие
 738 "               возобновления после прекращения. Представляет из себя |List|,
 739 "               содержащий ещё два вложенных списка односимвольных строк.
 740 "               В режиме транслитерации по мере ввода игнорируется.
 741 "               Значение по умолчанию — [['%'], ['%']].
 742 "
 743 "               Примеры: >
 744 "                           «shwh» => «шщ»
 745 "                         «s%hw%h» => «сhwх»
 746 "                        «s%hw\%h» => «сhw%h»
 747 "
 748 " g:trPluginDefaultTranssymb                      *g:trPluginDefaultTranssymb*
 749 "               Содержит таблицу транслитерации по умолчанию. Эта таблица не
 750 "               проверяется при вызове функций.
 751 "
 752 " g:trPluginStopTrSymbs                                *g:trPluginStopTrSymbs*
 753 "               Содержит словарь, в котором ключами являются символы,
 754 "               прекращающие транслитерацию по мере ввода, а значениями —
 755 "               символы, выводящиеся при вводе ключей. Такая конструкция нужна,
 756 "               чтобы можно было, к примеру, автоматически менять состояние
 757 "               транслитерации по мере ввода и вводить, скажем, тёги HTML, не
 758 "               заставляя пользователя тратить время на переключение статуса
 759 "               транслитерации.
 760 "               Значение по умолчанию — {'%':'','\':'\','<':'<'}
 761 "
 762 "               Примеры: >
 763 "                          «zam<b>o</b>k» => «зам<b>о</b>к»
 764 "                                   «s%h» => «сh»
 765 "                        «\textbf{mnogo}» => «\textbf{много}»
 766 "
 767 " g:trPluginStartTrSymbs                              *g:trPluginStartTrSymbs*
 768 "               Содержит словарь, в котором ключами являются символы,
 769 "               возобновляющие транслитерацию по мере ввода, а значениями —
 770 "               символы, выводящиеся при вводе ключей. Такая конструкция нужна,
 771 "               чтобы можно было, к примеру, автоматически менять состояние
 772 "               транслитерации по мере ввода и вводить, скажем, тёги HTML, не
 773 "               заставляя пользователя тратить время на переключение статуса
 774 "               транслитерации.
 775 "               Значение по умолчанию — {'%':'','{':'{','>':'>'}
 776 "
 777 "               Примеры: см выше.
 778 "
 779 "                                            *b:transsymb* *trplugin-ToF-local*
 780 " Помимо упомянутых выше настроек существуют локальные версии —
 781 " b:trPluginStopTrSymbs, b:trPluginStartTrSymbs, b:trPluginBrkSeqSymbs
 782 " и b:transsymb. Если существуют первые три переменные, то используются именно
 783 " они вместо соответствующих глобальных настроек. Значение b:transsymb
 784 " используется вместо настройки |g:trPluginDefaultTranssymb|.
 785 "
 786 " ==============================================================================
 787 " 6. Транслитерация по мере ввода.                               *trplugin-ToF*
 788 "
 789 " Вызывается и убирается командой |:StartToF|, либо функцией |InitToF()|. Идея
 790 " заключается в том, чтобы преобразование производилось в реальном времени, а не
 791 " после того, как были введены символы и запущен plugin. Отличается от обычной
 792 " транслитерации тем, что игнорируется ключ «other» таблицы транслитерации
 793 " и настройки |g:trPluginEscNext| и |g:trPluginStopStartTrSymbs|, а символы из
 794 " настройки |g:trPluginBrkSeqSymbs| должны вводится как привязки, то есть, если
 795 " настройка содержит несколько символов, то при медленном вводе вы рискуете
 796 " получить не прерывание последовательности, а эти символы.
 797 "
 798 " Транслитерация по мере ввода устанавливается локально, то есть состояние
 799 " буферов, отличных от текущего, не затрагивается.
 800 "
 801 " Отмечу, что изменение настроек не сказывается на работающей транслитерации по
 802 " мере ввода. Чтобы изменения вступили в силу, запустите транслитерацию по мере
 803 " ввода ещё раз. При повторном запуске транслитерации по мере ввода сначала
 804 " завершается предыдущая транслитерация по мере ввода, а затем запускается
 805 " новая.
 806 "
 807 " Все используемые настройки транслитерации на лету хранятся в словаре
 808 " b:trPluginToFMainDict. Не изменяйте его содержимое, это может привести
 809 " к неправильно работающей транслитерации.
 810 "
 811 " Также необходимо отметить, что привязки, соответствующие односимвольным ключам
 812 " самой корня таблицы транслитерации и вложенных в неё таблиц, ключам настроек
 813 " |g:trPluginStopTrSymbs| и |g:trPluginStartTrSymbs|, и символам из
 814 " |g:trPluginBrkSeqSymbs| теряются во время транслитерации по мере ввода. После
 815 " прекращения транслитерации функция попробует вернуть имевшие место привязки на
 816 " место, однако она возвращает их в виде «inoremap …», что в некоторых случаях
 817 " может работать не так, как предполагалось при создании. При временном
 818 " прекращении транслитерации (см. |g:trPluginStopTrSymbs|) привязки временно
 819 " возвращаются, однако с теми же замечаниями, что и при завершении
 820 " транслитерации по мере ввода привязки к символам, находящимся
 821 " в |g:trPluginStartTrSymbs|, не возвращаются. На самом деле привязки не
 822 " возвращаются, а имитируются.
 823 "
 824 "{{{1 стандартные настройки
 825 if !exists("g:trPluginBrkSeqSymbs")
 826     let g:trPluginBrkSeqSymbs=['@']
 827 endif
 828 if !exists("g:trPluginEscNext")
 829     let g:trPluginEscNext=['\']
 830 endif
 831 if !exists("g:trPluginStopStartTrSymbs")
 832     let g:trPluginStopStartTrSymbs=[['%'], ['%']]
 833 endif
 834 if !exists("g:trPluginDefaultTranssymb")
 835     let g:trPluginDefaultTranssymb=g:transsymb["ru"]
 836 endif
 837 " " {{{2 TODO:
 838 " " Настройка, позволяющая определить поведение в случае, если регистр букв
 839 " " в последовательности не соответствует друг другу. Представляет из себя
 840 " " словарь, имеющий два ключа: «upper» и «break». Первый ключ отвечает за то,
 841 " " в каких случаях символ будет преобразован в верхний регистр. Второй ключ
 842 " " отвечает за то, в каких случаях последовательность будет разорвана. Возможные
 843 " " случаи:
 844 " " Для «upper»:
 845 " " '1'     Первый символ находится в верхнем регистре, об остальных символах
 846 " "         ничего не известно.
 847 " " '.'     Первый символ находится в нижнем регистре, об остальных символах
 848 " "         ничего не известно.
 849 " " 'U'     Все символы находятся в верхнем регистре. Является частным
 850 " "         случаем '1'.
 851 " " 'L'     Все символы имеют нижний регистр.
 852 " " 'u'     В последовательности имеется хотя бы один символ в верхнем регистре.
 853 " " 'l'     В последовательности имеется хотя бы один символ в нижнем регистре.
 854 " " "lu"    Первый символ находится в нижнем регистре, а второй --- в верхнем.
 855 " " "ul"    Тоже самое, только теперь в нижнем регистре второй символ, а в
 856 " "         верхнем --- первый. Является частным случаем '1'.
 857 " " "c!c"   В последовательности из трёх и более символов один из символов
 858 " "         находится не в том же регистре, что и соседние. Случай, когда регистр,
 859 " "         отличный от соседних, имеет первый символ не рассматривается. Символ
 860 " "         после последнего можно считать имеющим тот же регистр, что
 861 " "         и предпоследний символ.
 862 " " 'U','ul' => '1'
 863 " " '1','c!c'=> 'u'
 864 " " 'L','lu' => '.'
 865 " " '.','c!c'=> 'l'
 866 " "
 867 " " S — Значение по умолчанию
 868 " " N — Что делать, если встретилось значение «N». N==a означает «в любом
 869 " "     случае»
 870 " " l — На что изменить значение «isupper» в случае, если встретилась маленькая
 871 " "     буква
 872 " " U — Тоже самое, если большая
 873 " " a — На что изменить значение «isupper» в случае, если встретилось значение
 874 " "     «N». Соответствует случаю, когда в обе колонки «l» и «U» вписаны
 875 " "     одинаковые значения
 876 " "
 877 " "        S  N   l a U |
 878 " " '1'  : 0  a   0   1 |
 879 " " ====================+
 880 " " '.'  : 0  a   1   0 |
 881 " " ====================+
 882 " " 'U'  : 1  a       I |
 883 " "           1   0     |
 884 " "           0     I   |
 885 " " ====================+
 886 " " 'L'  : 1  a   I     |
 887 " "           1       0 |
 888 " "           0     I   |
 889 " " ====================+
 890 " " 'u'  : 0  a   I   1 |
 891 " " ====================+
 892 " " 'l'  : 0  a   1   I |
 893 " " ====================+
 894 " " 'lu' : 0  0   1   I |
 895 " "           1   4   2 |
 896 " "           2     I   |
 897 " "           4   I   0 |
 898 " " ====================+
 899 " " 'ul' : 0  0   I   1 |
 900 " "           1   2   4 |
 901 " "           2     I   |
 902 " "           4   I   0 |
 903 " " ====================+
 904 " " 'c!c': 0  0   4   2 |
 905 " "           1     I   |
 906 " "           2   1   6 |
 907 " "           4   1   8 |
 908 " "           6   4   I |
 909 " "           8   I   2 |
 910 " if !exists("g:trPluginUpperCaseHolding")
 911     " let g:trPluginUpperCaseHolding={
 912                 " \"upper": ['1'],
 913                 " \"break": ["lu","c!c"]}
 914 " endif
 915 "{{{1 функция
 916 "{{{2 транслитерация
 917 " возвращяет словарь с:
 918 "   "exitstatus": статус выхода:
 919 "       "trsuc" : транслитерация прошла успешно
 920 "       "trerr" : не удалось транслитерировать
 921 "   "trans"     : результат транслитерации
 922 "   "deltai"    : количество обработанных символов
 923 "   "upper"     : символ является большой буквой
 924 " В качестве аргументов принимает словарь с символами для транслитерации и
 925 " строку, начинающуюся с символа, подлежащего обработке. Словарь с символами для
 926 " транслитерации может содержать только ту часть, что относится к первому
 927 " символу.
 928 function s:transGetChar(transsymb, string, brkseq)
 929     "{{{3 объявление переменных
 930     let l:i=0
 931     let l:isupper=0
 932     let l:string=a:string
 933     "{{{3 основная часть
 934     "{{{4 буква является заглавной
 935     if l:string[0]=~"\\u" && !has_key(a:transsymb, l:string[0]) &&
 936                 \has_key(a:transsymb, tolower(l:string[0])) &&
 937                 \!(type(a:transsymb[tolower(l:string[0])])==type({}) &&
 938                     \has_key(a:transsymb[tolower(l:string[0])],"options") &&
 939                     \has_key(a:transsymb[tolower(l:string[0])]["options"],
 940                         \"capital") &&
 941                     \a:transsymb[tolower(l:string[0])]["options"]["capital"]==
 942                         \"none")
 943         let l:isupper=1
 944         let l:string[0]=tolower(l:string[0])
 945     endif
 946     "{{{4 есть варианты транслитерации
 947     if has_key(a:transsymb, l:string[0])
 948         "{{{5 нет последовательности
 949         "транслитерация не зависит от следующих символов
 950         if type(a:transsymb[l:string[0]])==type('')
 951             let l:i=1
 952             if DoesListBeginWith(l:string[1:-1], a:brkseq)
 953                 let l:i+=len(a:brkseq)
 954             endif
 955             return {
 956                     \"exitstatus": "trsuc",
 957                     \"trans":     a:transsymb[l:string[0]],
 958                     \"deltai":    l:i,
 959                     \"upper":     l:isupper
 960                     \}
 961         "{{{5 Есть последовательность
 962         elseif type(a:transsymb[l:string[0]])==type({})
 963             "{{{6 Инициализация
 964             if len(l:string)>1 && !DoesListBeginWith(l:string[1:-1],
 965                         \a:brkseq)
 966             "{{{7 Рекурсия
 967                 let l:lastreturnedstatus=s:transGetChar(
 968                             \a:transsymb[l:string[0]], l:string[1:-1], a:brkseq)
 969                 if l:lastreturnedstatus["upper"] && !l:isupper
 970                     let l:lastreturnedstatus["exitstatus"]="trerr"
 971                 endif
 972                 let l:i=1
 973             else
 974             "{{{7 Нет альтернативных вариантов транслитерации
 975                 let l:lastreturnedstatus={
 976                             \"exitstatus": "trerr",
 977                             \"trans":      "",
 978                             \"deltai":      0,
 979                             \"upper":      l:isupper
 980                             \}
 981             endif
 982             "{{{6 если рекурсия вернула ошибку транслитерации
 983             if l:lastreturnedstatus["exitstatus"]=="trerr"
 984                 "{{{7 инициализация
 985                 let l:i=0
 986                 "{{{7 нет последовательности, но есть транслитерация одной буквы
 987                 if has_key(a:transsymb[l:string[0]], "none")
 988                     let l:lastreturnedstatus={
 989                                \"exitstatus": "trsuc",
 990                                \"trans":     a:transsymb[l:string[0]]["none"],
 991                                \"deltai":     1,
 992                                \"upper":     l:isupper
 993                                \}
 994                     if DoesListBeginWith(l:string[1:-1], a:brkseq)
 995                         let l:i+=len(a:brkseq)
 996                     endif
 997                 "{{{7 варианты транслитерации отсутствуют
 998                 else
 999                     let l:lastreturnedstatus={
1000                                 \"exitstatus": "trerr",
1001                                 \"trans":     l:string[0],
1002                                 \"deltai":     1,
1003                                 \"upper":     l:isupper
1004                                 \}
1005                 endif
1006             endif
1007         endif
1008         "{{{6 в любом случае
1009         return {
1010                 \"exitstatus": l:lastreturnedstatus["exitstatus"],
1011                 \"trans":      l:lastreturnedstatus["trans"],
1012                 \"deltai":     l:lastreturnedstatus["deltai"]+l:i,
1013                 \"upper":      l:isupper
1014                 \}
1015     "{{{4 варианты транслитерации отсутствуют
1016     else
1017         if DoesListBeginWith(l:string, a:brkseq)
1018             return {
1019                     \"exitstatus": "trerr",
1020                     \"trans":      "",
1021                     \"deltai":     len(a:brkseq),
1022                     \"upper":      0
1023                     \}
1024         endif
1025         if !has_key(a:transsymb, "other")
1026             return {
1027                     \"exitstatus":  "trerr",
1028                     \"trans":      l:string[0],
1029                     \"deltai":      1,
1030                     \"upper":      l:isupper
1031                     \}
1032         else
1033             return {
1034                     \"exitstatus": "trsuc",
1035                     \"trans":     a:transsymb["other"],
1036                     \"deltai":     1,
1037                     \"upper":      0
1038                     \}
1039         endif
1040     endif
1041 endfunction
1042 "{{{2 Превращение строки в массив (List)
1043 "     Нужно для поддержки UTF-8
1044 function StringToList(string)
1045     let l:returnedlist=[]
1046     let l:i=0
1047     while l:i!=len(a:string)
1048         call add(l:returnedlist, matchstr(a:string[(l:i):-1], '.'))
1049         let l:i+=len(l:returnedlist[-1])
1050     endwhile
1051     return l:returnedlist
1052 endfunction
1053 "{{{2 Проверка, совпадает ли начало у двух массивов
1054 function DoesListBeginWith(list, beginning)
1055     if type(a:beginning)!=type([])
1056         if !len(a:list)
1057             return 0
1058         endif
1059         if a:list[0]==a:beginning
1060             return 1
1061         endif
1062         return 0
1063     endif
1064     if len(a:list)<len(a:beginning)
1065         return 0
1066     endif
1067     if a:list[0:(len(a:beginning)-1)]==a:beginning
1068         return 1
1069     endif
1070     return 0
1071 endfunction
1072 "{{{2 основная функция
1073 function TransliterateString(string, ...)
1074     "{{{3 Объявление переменных
1075     "{{{4 Проверка аргументов
1076     if len(a:000)
1077         if type(a:000[0])==type({})
1078             let l:transsymb=a:000[0]
1079             "{{{4 Проверка словаря
1080             if !has_key(l:transsymb, "checked") ||
1081                         \l:transsymb["checked"]!="\<SID>"
1082                 silent! if CheckTransTable(l:transsymb)
1083                     echoerr "В таблице транслитерации обнаружены ошибки!"
1084                     return ""
1085                 else
1086                     call extend(l:transsymb, {"checked": "\<SID>"}, "force")
1087                 endif
1088             endif
1089         else
1090             echoerr "Не является словарём!"
1091             return ""
1092         endif
1093     else
1094         if !exists("b:transsymb")
1095             let l:transsymb=g:trPluginDefaultTranssymb
1096         else
1097             let l:transsymb=b:transsymb
1098         endif
1099     endif
1100     if type(a:string)!=type("")
1101         echoerr "В качестве первого аргумента должна быть указана строка!"
1102         return ""
1103     endif
1104     "}}}
1105     if !exists("b:trPluginBrkSeqSymbs")
1106         let l:brkseq=g:trPluginBrkSeqSymbs
1107     else
1108         let l:brkseq=b:trPluginBrkSeqSymbs
1109     endif
1110     let l:returnedstring=""
1111     let l:i=0
1112     let l:string=StringToList(a:string)
1113     "{{{3 Основной цикл: транслитерация и т.д.
1114     while l:i<len(l:string)
1115         let l:trsymb=s:transGetChar(l:transsymb, l:string[(l:i):-1], l:brkseq)
1116         "{{{4 Транслитерировано успешно
1117         " Транслитерация имеет приоритет больший, чем всё остальное, поэтому
1118         " возможный конфликт между настройками и словарём транслитерации
1119         " разрешается в пользу последнего.
1120         if l:trsymb["exitstatus"]=="trsuc"
1121             if l:trsymb["upper"]
1122                 let l:trsymb["trans"]=toupper(l:trsymb["trans"])
1123             endif
1124             let l:returnedstring.=l:trsymb["trans"]
1125             let l:i+=l:trsymb["deltai"]
1126             continue
1127         endif
1128         "{{{4 Комбинации из настроек
1129         "{{{5 Следующий символ будет добавлен без транслитерации
1130         if DoesListBeginWith(l:string[(l:i):-1],g:trPluginEscNext)
1131             let l:i+=len(g:trPluginEscNext)
1132             if l:i>=len(l:string)
1133                 let l:returnedstring.=join(g:trPluginEscNext, "")
1134                 break
1135             endif
1136             let l:returnedstring.=l:string[l:i]
1137             let l:i+=1
1138             continue
1139         "{{{5 Следующие символы транслитерированы не будут
1140         elseif DoesListBeginWith(l:string[(l:i):-1],
1141                     \g:trPluginStopStartTrSymbs[0])
1142             let l:i+=len(g:trPluginStopStartTrSymbs[0])
1143             while !DoesListBeginWith(l:string[(l:i):-1],
1144                         \g:trPluginStopStartTrSymbs[1]) &&
1145                         \l:i<len(l:string)
1146                 "{{{6 Добавить след. символ без изменений
1147                 if DoesListBeginWith(l:string[(l:i):-1], g:trPluginEscNext)
1148                     let l:i+=len(g:trPluginEscNext)
1149                     if l:i>=len(l:string)
1150                         let l:returnedstring.=join(g:trPluginEscNext, "")
1151                         break
1152                     endif
1153                     let l:returnedstring.=l:string[l:i]
1154                     let l:i+=1
1155                     continue
1156                 endif
1157                 "}}}
1158                 let l:returnedstring.=l:string[l:i]
1159                 let l:i+=1
1160             endwhile
1161             let l:i+=len(g:trPluginStopStartTrSymbs[1])
1162             continue
1163         endif
1164         "{{{4 Если символ транслитерировать не удалось
1165         if l:trsymb["exitstatus"]=="trerr"
1166             if l:trsymb["upper"]
1167                 let l:trsymb["trans"]=toupper(l:trsymb["trans"])
1168             endif
1169             let l:returnedstring.=l:trsymb["trans"]
1170             let l:i+=l:trsymb["deltai"]
1171             continue
1172         endif
1173         let l:i+=1
1174     endwhile
1175     return l:returnedstring
1176 endfunction
1177 "{{{1 Команда
1178 execute "command! -range=% -nargs=? TrText ".
1179             \"call \<SID>transCommandFunc(<line1>, <line2>, 0, <args>)"
1180 execute "command! -range=% -nargs=? ".
1181             \"TrSelection ".
1182             \"call \<SID>transCommandFunc(<line1>, <line2>, 1, <args>)"
1183 let s:transTable={}
1184 "{{{2 Функция для команды
1185 function s:transCommandFunc(linestart, lineend, isVisual, ...)
1186     "{{{3 Объявление переменных
1187     let  l:lastMot =""
1188     let l:firstMot =""
1189     let l:linecount=0
1190     let l:linestart=0
1191     let l:savedwin=winsaveview()
1192     let l:savedpaste=&paste
1193     set paste
1194     "{{{4 Диапозоны транслитерации
1195     "{{{5 Если функция была вызвана из визуального режима
1196     if a:isVisual
1197         let l:linestart=line("'<")
1198         let l:linecount=line("'>")-l:linestart
1199         let l:firstMot = virtcol("'<")
1200         if visualmode()=="\<C-v>"
1201             let l:lastMot=(virtcol("'>")-((&selection=="exclusive")?(1):(0))-
1202                         \l:firstMot+1)
1203             if l:lastMot<0
1204                 let l:firstMot+=l:lastMot
1205                 let l:lastMot =-l:lastMot
1206             endif
1207             let l:lastMot .= 'l'
1208             let l:firstMot.= '|'
1209         elseif visualmode()=='V'
1210             let l:firstMot = '0'
1211             let l:lastMot  = '$'
1212         elseif visualmode()=='v'
1213             let l:firstMot ="gv"
1214         endif
1215     "{{{5 Если не из визуального
1216     else
1217         let l:linestart=a:linestart
1218         let l:linecount=a:lineend-l:linestart
1219         let l:firstMot ='0'
1220         let l:lastMot  ='$'
1221     endif
1222     "{{{5 Если первой строкой идёт нижняя
1223     if l:linecount<0
1224         let l:linestart+=l:linecount
1225         let l:linecount=-l:linecount
1226     endif
1227     "{{{4 Остальные переменные
1228     let l:i=0
1229     let l:savedtReg=@t
1230     execute "normal! ".l:linestart."gg"
1231     "{{{3 Убрать «formatoptions=a»
1232     let l:savedformatoptions=&formatoptions
1233     set formatoptions-=a
1234     "{{{4 Таблица транслитерации
1235     if len(a:000)
1236         " В качестве аргумента дана таблица
1237         let s:transTable=a:000[0]
1238         if type(s:transTable)!=type({})
1239             echoerr "Аргумент не является словарем!"
1240             return 2
1241         else
1242             silent! if CheckTransTable(s:transTable)
1243                 echoerr "Таблица транслитерации не прошла проверку!"
1244                 return 1
1245             else
1246                 call extend(l:transsymb, {"checked": "\<SID>"}, "force")
1247             endif
1248         endif
1249     else
1250         " Иначе используем таблицу по умолчанию
1251         if !exists("b:transsymb")
1252             let s:transTable=g:trPluginDefaultTranssymb
1253         else
1254             let s:transTable=b:transsymb
1255         endif
1256     endif
1257     "{{{3 Собственно, транслитерация
1258     while l:i<=l:linecount
1259         execute "normal! ".l:firstMot."\"tc".l:lastMot.
1260                     \"\<C-r>=TransliterateString(@t,s:transTable)\<C-m>\<ESC>j"
1261         let l:i+=1
1262     endwhile
1263     "{{{3 Завершение работы
1264     let @t=l:savedtReg
1265     let &formatoptions=l:savedformatoptions
1266     let &paste=l:savedpaste
1267     call winrestview(l:savedwin)
1268     return 0
1269 endfunction
1270 "{{{1 Проверка таблицы транслитерации
1271 function CheckTransTable(transsymb)
1272     "{{{2 Начало работы
1273     echohl Error
1274     let l:errcount_r=0
1275     for l:key in keys(a:transsymb)
1276         "{{{2 Проверка типа ключа
1277         if type(l:key)!=type("")
1278             echo "Найдено неправильное значение ключа:"
1279             echo "«".strtrans(string(l:key))."»."
1280             echo "Ключ словаря должен иметь тип «String»"
1281             let l:errcount_r+=1
1282             continue
1283         endif
1284         "{{{2 Проверка длины ключа
1285         " Есть всего три варианта: нулевая длина ключа, ключ, состоящий из
1286         " одного символа, а также ключ, имеющий длину, большую единицы.
1287         " В последнем случае длина ключа нам безразлична, поэтому замены только
1288         " первого символа на точку, имеющую длину, равную единице, будет
1289         " достаточно для того, чтобы можно было различить эти случаи.
1290         let l:keyLength=strlen(substitute(l:key, '.', '.', ''))
1291         "{{{3 Нулевая длина
1292         if !l:keyLength
1293             echo "Найдено неправильное значение ключа:"
1294             echo "ключ словаря не может иметь нулевую длину."
1295             let l:errcount_r+=1
1296         "{{{3 Длина, превышающая единицу
1297         elseif l:keyLength>1
1298             "{{{4 Ключ «none»
1299             if l:key=="none"
1300                 if type(a:transsymb[l:key])!=type("")
1301                     echo "Найдено неправильное значение:"
1302                     echo "«„".l:key."“: „".
1303                                 \strtrans(string(a:transsymb[l:key])).
1304                                 \"“»."
1305                     echo "Значение, соответствующее ключу \"none\""
1306                     echo "должно иметь тип «String»."
1307                     let l:errcount_r+=1
1308                     continue
1309                 endif
1310             "{{{4 Ключ «options»
1311             elseif l:key=="options"
1312                 "{{{5 Проверка типа значения
1313                 if type(a:transsymb[l:key])!=type({})
1314                     echo "Найдено неправильное значение:"
1315                     echo "«„".l:key."“: „".
1316                                 \strtrans(string(a:transsymb[l:key])).
1317                                 \"“»."
1318                     echo "Значение, соответствующее ключу \"options\""
1319                     echo "должно иметь тип «Dictionary»."
1320                     let l:errcount_r+=1
1321                     continue
1322                 endif
1323                 "{{{5 Проверка содержания словаря
1324                 for l:key_p in keys(a:transsymb[l:key])
1325                     "{{{6 Проверка типа ключа
1326                     if type(l:key_p)!=type("")
1327                         echo "Найдено неправильное значение ключа:"
1328                         echo "«„".l:key."“: „"
1329                                     \strtrans(string(l:key))."“»."
1330                         echo "Ключ словаря должен иметь тип «String»"
1331                         let l:errcount_r+=1
1332                         continue
1333                     endif
1334                     "{{{6 Ключ «capital»
1335                     if l:key_p=="capital"
1336                         "{{{7 Проверка типа значения
1337                         if type(a:transsymb[l:key][l:key_p])!=type("")
1338                             echo "Найдено неправильное значение:"
1339                             echo "«„".l:key."“: „".l:key_p."“: „".
1340                                         \strtrans(
1341                                             \string(
1342                                                 \a:transsymb[l:key][l:key_p]
1343                                             \)
1344                                         \)."“»."
1345                             echo "Значение, соответствующее ключу ".
1346                                 \"\"capital\""
1347                             echo "в словаре, соответствующем ключу ".
1348                                         \"\"options\","
1349                             echo "должно иметь тип «String»"
1350                             let l:errcount_r+=1
1351                             continue
1352                         endif
1353                         "{{{7 Проверка самого значения
1354                         if a:transsymb[l:key][l:key_p]!="none"
1355                             echo "Найдено неправильное значение:"
1356                             echo "«„".l:key."“: „".l:key_p."“: „".
1357                                         \strtrans(
1358                                             \string(
1359                                                 \a:transsymb[l:key][l:key_p]
1360                                             \)
1361                                         \)."“»."
1362                             echo "Значение, соответствующее ключу ".
1363                                 \"\"capital\""
1364                             echo "в словаре, соответствующем ключу ".
1365                                         \"\"options\","
1366                             echo "неверно."
1367                             let l:errcount_r+=1
1368                             continue
1369                         endif
1370                     "{{{6 Неверный ключ
1371                     else
1372                         echo "Найден неправильный ключ:"
1373                         echo "«„".l:key."“: „".l:key_p."“»."
1374                         echo "Такой настройки не существует."
1375                         let l:errcount_r+=1
1376                     endif
1377                 endfor
1378             "{{{4 Ключ «other»
1379             elseif l:key=="other"
1380                 "{{{5 Проверка типа значения
1381                 if type(a:transsymb[l:key])!=type("")
1382                     echo "Найдено неправильное значение:"
1383                     echo "«„".l:key."“: „".
1384                                 \strtrans(string(a:transsymb[l:key])).
1385                                 \"“»."
1386                     echo "Значение, соответствующее ключу \"other\""
1387                     echo "должно иметь тип «String»."
1388                     let l:errcount_r+=1
1389                     continue
1390                 endif
1391             "{{{4 Ключ «checked»
1392             elseif l:key=="checked"
1393                 "{{{5 Проверка типа значения
1394                 if type(a:transsymb[l:key])!=type("")
1395                     echo "Найдено неправильное значение:"
1396                     echo "«„".l:key."“: „".
1397                                 \strtrans(string(a:transsymb[l:key])).
1398                                 \"“»."
1399                     echo "Значение, соответствующее ключу \"checked\""
1400                     echo "должно иметь тип «String»."
1401                     let l:errcount_r+=1
1402                     continue
1403                 endif
1404             "{{{4 Ключ неизвестен
1405             else
1406                 echo "Неизвестный длинный ключ:"
1407                 echo "«".l:key."»."
1408                 let l:errcount_r+=1
1409             endif
1410         "{{{3 Длина ключа равна единице
1411         else
1412             "{{{4 Проверка типа значения
1413             if type(a:transsymb[l:key])!=type("") &&
1414                         \type(a:transsymb[l:key])!=type({})
1415                 echo "Найдено неправильное значение:"
1416                 echo "«„".l:key."“: „".
1417                             \strtrans(string(a:transsymb[l:key])).
1418                             \"“»."
1419                 echo "Значение, соответствующее односимвольному ключу"
1420                 echo "должно иметь тип «String» или «Dictionary»."
1421                 let l:errcount_r+=1
1422                 continue
1423             endif
1424             "{{{4 Проверка значения, если его тип --- словарь
1425             if type(a:transsymb[l:key])==type({})
1426                 echohl None
1427                 echo "Проверка словаря, соответствующего символу «".l:key."»."
1428                 let l:errcount_r+=CheckTransTable(a:transsymb[l:key])
1429                 echohl Error
1430             endif
1431         endif
1432     endfor
1433     "{{{2 Завершение работы  функции
1434     echohl None
1435     return l:errcount_r
1436 endfunction
1437 "{{{1 Транслитерация по мере ввода
1438 "{{{2 Настройки:
1439 if !exists("g:trPluginStopTrSymbs")
1440     let g:trPluginStopTrSymbs={
1441                 \ '%''',
1442                 \ '\''\',
1443                 \ '<''<'}
1444 endif
1445 if !exists("g:trPluginStartTrSymbs")
1446     let g:trPluginStartTrSymbs={
1447                 \'%''',
1448                 \'{''{',
1449                 \'>''>'}
1450 endif
1451 "{{{2 Инициализация
1452 "{{{3 Создание привязок
1453 function s:CreatMapToF(mapkey)
1454     if a:mapkey==''''
1455         execute "inoremap <expr> <buffer> ' \<SID>AddSymbToF('''')"
1456         return 0
1457     endif
1458     execute "inoremap <expr> <buffer> ".a:mapkey." \<SID>AddSymbToF('".a:mapkey.
1459                 \"')"
1460     return 0
1461 endfunction
1462 function s:CreatMapsToF(transsymb, crntrs)
1463     for key in keys(a:transsymb)
1464         if key!~"^.$"
1465             continue
1466         endif
1467         if !has_key(b:trPluginToFMainDict["maps"], key)
1468             call extend(b:trPluginToFMainDict["maps"],
1469                         \{ key : maparg(key, "i") })
1470             call s:CreatMapToF(key)
1471         endif
1472         if key=~"\\l" && !has_key(b:trPluginToFMainDict["maps"], toupper(key))&&
1473                     \!( type(a:transsymb[key])==type({}) &&
1474                     \has_key(a:transsymb[key],"options") &&
1475                     \has_key(a:transsymb[key]["options"],"capital") &&
1476                     \        a:transsymb[key]["options"]["capital"]=="none")
1477             call extend(b:trPluginToFMainDict["maps"],
1478                         \{ toupper(key) : maparg(toupper(key), "i") })
1479             call s:CreatMapToF(toupper(key))
1480         endif
1481         if type(a:transsymb[key])==type({})
1482             call s:CreatMapsToF(a:transsymb[key], 0)
1483         endif
1484     endfor
1485     if a:crntrs
1486         for key in keys(b:trPluginToFMainDict["StopTrSymbs"])
1487             call extend(b:trPluginToFMainDict["maps"],
1488                         \{ key : maparg(key, "i") }, "keep")
1489             call s:CreatMapToF(key)
1490         endfor
1491         for key in keys(b:trPluginToFMainDict["StartTrSymbs"])
1492             call extend(b:trPluginToFMainDict["maps"],
1493                         \{ key : maparg(key, "i") }, "keep")
1494             call s:CreatMapToF(key)
1495         endfor
1496         call extend(b:trPluginToFMainDict["maps"], {
1497                     \join(b:trPluginToFMainDict["BrkSeqSymbs"], ""):
1498                         \maparg(join(b:trPluginToFMainDict["BrkSeqSymbs"], ""),
1499                             \"i") }, "keep")
1500         execute "inoremap <expr> <buffer> ".
1501                     \join(b:trPluginToFMainDict["BrkSeqSymbs"], "").
1502                     \" \<SID>ClrSeq()"
1503     endif
1504     return b:trPluginToFMainDict["maps"]
1505 endfunction
1506 "{{{3 Основная функция
1507 function InitToF(...)
1508     "{{{4 Локальные переменные
1509     if exists("b:trPluginToFMainDict") &&
1510                 \has_key(b:trPluginToFMainDict, "transsymbseq") &&
1511                 \b:trPluginToFMainDict["transsymbseq"]!=[]
1512         call s:StopToF()
1513     endif
1514     let b:trPluginToFMainDict={
1515                 \"maps":         {},
1516                 \"lastpos":      [line('.'), col('.')],
1517                 \"transsymbseq": [],
1518                 \"trseq":        [],
1519                 \"dotranslit":    0,
1520                 \"lastupper":    -1,
1521                 \"StopTrSymbs":  "",
1522                 \"StartTrSymbs": "",
1523                 \"BrkSeqSymbs":  ""
1524                 \}
1525     "{{{4 Загрузить таблицу транслитерации
1526     if len(a:000)
1527         if type(a:000[0])==type({})
1528             let l:transsymb=a:000[0]
1529             if !has_key(l:transsymb, "checked") ||
1530                         \l:transsymb["checked"]!="\<SID>"
1531                 silent! if CheckTransTable(l:transsymb)
1532                     echoerr "Таблица транслитерации не прошла проверку!"
1533                     return 1
1534                 else
1535                     call extend(l:transsymb, {"checked": "\<SID>"}, "force")
1536                 endif
1537             endif
1538         elseif type(a:000[0])==type("")
1539             if a:000[0]=="stop"
1540                 return s:StopToF()
1541             elseif a:000[0]=="default"
1542                 let l:transsymb=g:trPluginDefaultTranssymb
1543             elseif a:000[0]=="i" || a:000[0]=="l" || a:000[0]=="c" ||
1544                         \a:000[0]=="!"
1545                 " let s:mapmode=a:000[0]
1546                 echoerr "Транслитерация по мере ввода для других режимов".
1547                             \" не сделана!"
1548                 if len(a:000)>1
1549                     return InitToF(a:000[1])
1550                 endif
1551             else
1552                 if exists(a:000[0])
1553                     execute "let l:transsymb=".a:000[0]
1554                     if type(l:transsymb)!=type({})
1555                         echoerr "Не удалось загрузить табилцу транслитерации!"
1556                         return 2
1557                     else
1558                         silent! if CheckTransTable(l:transsymb)
1559                             echoerr "Таблица транслитерации не прошла проверку!"
1560                             return 1
1561                         else
1562                             call extend(l:transsymb, {"checked": "\<SID>"},
1563                                         \"force")
1564                         endif
1565                     endif
1566                 else
1567                     echoerr "Указанное имя переменной не существует!"
1568                     return 4
1569                 endif
1570             endif
1571         elseif type(a:000[0])==type(0) && a:000[0]==0
1572             return s:StopToF()
1573         else
1574             echoerr "Неправильный аргумент!"
1575             return 3
1576         endif
1577     else
1578         let l:transsymb=g:trPluginDefaultTranssymb
1579     endif
1580     "{{{4 Локальные настройки
1581     if !exists("b:trPluginStartTrSymbs")
1582         let b:trPluginToFMainDict["StartTrSymbs"]=g:trPluginStartTrSymbs
1583     else
1584         let b:trPluginToFMainDict["StartTrSymbs"]=b:trPluginStartTrSymbs
1585     endif
1586     if !exists("b:trPluginStopTrSymbs")
1587         let b:trPluginToFMainDict["StopTrSymbs"]=g:trPluginStopTrSymbs
1588     else
1589         let b:trPluginToFMainDict["StopTrSymbs"]=b:trPluginStopTrSymbs
1590     endif
1591     if !exists("b:trPluginBrkSeqSymbs")
1592         let b:trPluginToFMainDict["BrkSeqSymbs"]=g:trPluginBrkSeqSymbs
1593     else
1594         let b:trPluginToFMainDict["BrkSeqSymbs"]=b:trPluginBrkSeqSymbs
1595     endif
1596     "{{{4 Основная часть
1597     let b:trPluginToFMainDict["transsymbseq"]=[l:transsymb]
1598     let b:trPluginToFMainDict["lastupper"]=-1
1599     let b:trPluginToFMainDict["trseq"]=[]
1600     call s:CreatMapsToF(b:trPluginToFMainDict["transsymbseq"][0], 1)
1601     let b:trPluginToFMainDict["dotranslit"]=1
1602     return 0
1603 endfunction
1604 "{{{3 Завершение работы
1605 function s:StopToF()
1606     let b:trPluginToFMainDict["transsymbseq"]=[]
1607     let b:trPluginToFMainDict["trseq"]=[]
1608     let b:trPluginToFMainDict["dotranslit"]=0
1609     let b:trPluginToFMainDict["lastupper"]=-1
1610     call s:DeleteMaps()
1611     return 0
1612 endfunction
1613 "{{{2 Последовательность \<BS>
1614 function s:BSSeq()
1615     let l:returnedSeq=""
1616     if len(b:trPluginToFMainDict["trseq"])>1
1617         let l:i=len(substitute(b:trPluginToFMainDict["trseq"][-2],
1618                     \".", ".", "g"))
1619         while l:i>0
1620             let l:returnedSeq.="\<BS>"
1621             let l:i-=1
1622         endwhile
1623     endif
1624     return l:returnedSeq
1625 endfunction
1626 "{{{2 Транслитерировать символ
1627 function s:TransToF(symb, transsymb)
1628     let l:symb=a:symb
1629     "{{{3 Большая буква
1630     if b:trPluginToFMainDict["lastupper"]!=0 && l:symb=~"\\u" &&
1631                 \!has_key(a:transsymb, l:symb) &&
1632                 \ has_key(a:transsymb, tolower(l:symb)) &&
1633                 \  !(type(a:transsymb[tolower(l:symb)])==type({}) &&
1634                     \has_key(a:transsymb[tolower(l:symb)],"options") &&
1635                     \has_key(a:transsymb[tolower(l:symb)]["options"],
1636                         \"capital") &&
1637                     \a:transsymb[tolower(l:symb)]["options"]["capital"]=="none")
1638         let b:trPluginToFMainDict["lastupper"]=1
1639         let l:symb=tolower(l:symb)
1640     endif
1641     if b:trPluginToFMainDict["lastupper"]==-1 && l:symb!~"\\u"
1642         let b:trPluginToFMainDict["lastupper"]=0
1643     endif
1644     "{{{3 Есть варианты транслитерации
1645     if has_key(a:transsymb, l:symb)
1646         "{{{4 Вариант транслитерации единственный
1647         if type(a:transsymb[l:symb])==type("")
1648             call add(b:trPluginToFMainDict["trseq"],
1649                         \((b:trPluginToFMainDict["lastupper"]==1)?
1650                                     \(toupper(a:transsymb[l:symb])
1651                                     \):      (a:transsymb[l:symb])))
1652             if b:trPluginToFMainDict["lastupper"]==1
1653                 let l:symb=toupper(a:transsymb[l:symb])
1654             else
1655                 let l:symb=a:transsymb[l:symb]
1656             endif
1657             let l:symb=s:BSSeq().l:symb
1658             call s:ClrSeq()
1659         "{{{4 Есть словарь с вариантами
1660         else
1661             call add(b:trPluginToFMainDict["transsymbseq"],
1662                         \b:trPluginToFMainDict["transsymbseq"][-1][l:symb])
1663             if has_key(b:trPluginToFMainDict["transsymbseq"][-1], "none")
1664                 call add(b:trPluginToFMainDict["trseq"],
1665                     \((b:trPluginToFMainDict["lastupper"]==1)?
1666                     \(toupper(b:trPluginToFMainDict["transsymbseq"][-1]["none"])
1667                     \):(b:trPluginToFMainDict["transsymbseq"][-1]["none"])))
1668                 let l:symb=((b:trPluginToFMainDict["lastupper"]==1)?
1669                     \(toupper(b:trPluginToFMainDict["transsymbseq"][-1]["none"])
1670                     \):(b:trPluginToFMainDict["transsymbseq"][-1]["none"]))
1671                 let l:symb=s:BSSeq().l:symb
1672             else
1673                 " call add(b:trPluginToFMainDict["trseq"],
1674                 if !len(b:trPluginToFMainDict["trseq"])
1675                     call add(b:trPluginToFMainDict["trseq"], "")
1676                 endif
1677                 let b:trPluginToFMainDict["trseq"][-1].=l:symb
1678             endif
1679         endif
1680     "{{{3 Вариантов нет
1681     else
1682         return 0
1683     endif
1684     "{{{3 Завершение работы
1685     return l:symb
1686 endfunction
1687 "{{{2 Удалить последовательность
1688 function s:ClrSeq()
1689     let b:trPluginToFMainDict["trseq"]=[]
1690     let b:trPluginToFMainDict["transsymbseq"]=
1691                 \b:trPluginToFMainDict["transsymbseq"][0:0]
1692     let b:trPluginToFMainDict["lastupper"]=-1
1693     return ""
1694 endfunction
1695 "{{{2 Добавить символ
1696 function AddSymbToF(symb)
1697     return s:AddSymbToF(a:symb)
1698 endfunction
1699 function s:AddSymbToF(symb)
1700     let l:curpos=[line('.'), col('.')]
1701     "{{{3 Символы возобновления транслитерации
1702     if !b:trPluginToFMainDict["dotranslit"]
1703         if has_key(b:trPluginToFMainDict["StartTrSymbs"], a:symb)
1704             let b:trPluginToFMainDict["dotranslit"]=1
1705             let b:trPluginToFMainDict["lastpos"]=l:curpos
1706             return b:trPluginToFMainDict["StartTrSymbs"][a:symb]
1707         else
1708             if has_key(b:trPluginToFMainDict["maps"], a:symb) &&
1709                         \b:trPluginToFMainDict["maps"][a:symb]!=""
1710                 execute "return \"".
1711                             \escape(b:trPluginToFMainDict["maps"][a:symb],
1712                                 \"\\\"<")."\""
1713             endif
1714             return a:symb
1715         endif
1716     endif
1717     "{{{3 Символы прекращения транслитерации
1718     if has_key(b:trPluginToFMainDict["StopTrSymbs"], a:symb)
1719         call s:ClrSeq()
1720         let b:trPluginToFMainDict["dotranslit"]=0
1721         let b:trPluginToFMainDict["lastpos"]=l:curpos
1722         return b:trPluginToFMainDict["StopTrSymbs"][a:symb]
1723     endif
1724     "{{{3 Проверка позиции
1725     if l:curpos[0]!=b:trPluginToFMainDict["lastpos"][0] || (
1726                 \l:curpos[1]!=b:trPluginToFMainDict["lastpos"][1])
1727         call s:ClrSeq()
1728     endif
1729     "{{{3 Транслитерация
1730     let l:returnedTrans=s:TransToF(a:symb,
1731                 \b:trPluginToFMainDict["transsymbseq"][-1])
1732     let l:symb=""
1733     if type(l:returnedTrans)==type(0)
1734         call s:ClrSeq()
1735         let l:returnedTrans=s:TransToF(a:symb,
1736                     \b:trPluginToFMainDict["transsymbseq"][-1])
1737         if type(l:returnedTrans)!=type(0)
1738             let l:symb=l:returnedTrans
1739         else
1740             let l:symb=a:symb
1741         endif
1742     else
1743         let l:symb=l:returnedTrans
1744     endif
1745     "{{{3 Завершение работы
1746     if len(b:trPluginToFMainDict["trseq"])
1747         let b:trPluginToFMainDict["lastpos"]=[line('.'), col('.')+len(l:symb)]
1748         if len(b:trPluginToFMainDict["trseq"])>1
1749             let b:trPluginToFMainDict["lastpos"][1]-=
1750                         \len(b:trPluginToFMainDict["trseq"][-2])*
1751                             \(len("\<BS>")+1)
1752         endif
1753     endif
1754     return l:symb
1755 endfunction
1756 "{{{2 Удаление привязок
1757 function s:DeleteMaps()
1758     for key in keys(b:trPluginToFMainDict["maps"])
1759         if b:trPluginToFMainDict["maps"][key]!=""
1760             silent! execute "inoremap <buffer> ".key." ".
1761                         \b:trPluginToFMainDict["maps"][key]
1762         else
1763             silent! execute "iunmap <buffer> ".key
1764         endif
1765     endfor
1766     let b:trPluginToFMainDict["maps"]={}
1767 endfunction
1768 "{{{1 Отображение таблицы транслитерации
1769 "{{{2 Напечатать не менее N символов
1770 function s:PrintN(string, n)
1771     let l:len=a:n-len(StringToList(a:string))
1772     if l:len<=0
1773         return a:string
1774     endif
1775     let l:returnedstring=a:string
1776     while l:len>0
1777         let l:returnedstring.=" "
1778         let l:len-=1
1779     endwhile
1780     return l:returnedstring
1781 endfunction
1782 function s:PrintL(list, counts)
1783     return s:PrintN(a:list[0], a:counts[0])." ".
1784                 \s:PrintN(a:list[1], a:counts[1])." ".
1785                 \a:list[2]
1786 endfunction
1787 "{{{2 Основная функция
1788 function s:TrShow(transsymb, ...)
1789     "{{{3 Отступ
1790     let l:indent=""
1791     if len(a:000)
1792         let l:indent=a:000[0]
1793     endif
1794     "{{{3 Цикл
1795     "{{{4 Объявление переменных
1796     let l:returnedlist=[]
1797     let l:skipindent=0
1798     "{{{4 none
1799     if has_key(a:transsymb, "none")
1800         let l:endl=" "
1801         if has_key(a:transsymb, "options") &&
1802                     \has_key(a:transsymb["options"], "capital") &&
1803                     \a:transsymb["options"]["capital"]=="none"
1804             let l:endl="c"
1805         endif
1806         call add(l:returnedlist, [l:indent, a:transsymb["none"], l:endl])
1807     endif
1808     "{{{4 Односимвольные ключи
1809     for key in keys(a:transsymb)
1810         if key=~"^.$"
1811             if type(a:transsymb[key])==type("")
1812                 call add(l:returnedlist, [l:indent.key, a:transsymb[key], " "])
1813                 continue
1814             elseif type(a:transsymb[key])==type({})
1815                 call extend(l:returnedlist,
1816                             \s:TrShow(a:transsymb[key], l:indent.key))
1817             endif
1818         endif
1819     endfor
1820     "{{{4 other
1821     if has_key(a:transsymb, "other")
1822         call add(l:returnedlist, [l:indent, a:transsymb["other"], "0"])
1823     endif
1824     "{{{3 Завершение работы
1825     return l:returnedlist
1826 endfunction
1827 "{{{2 Отображение в колонках
1828 function TrShow(...)
1829     let l:columns=0
1830     if len(a:000)
1831         if type(a:000[0])==type({})
1832             let l:transsymb=a:000[0]
1833             if !has_key(l:transsymb, "checked") ||
1834                        \l:transsymb["checked"]!="\<SID>"
1835                 silent! if CheckTransTable(l:transsymb)
1836                     echoerr "Таблица транслитерации не прошла проверку!"
1837                     return 1
1838                 else
1839                     call extend(l:transsymb, {"checked": "\<SID>"}, "force")
1840                 endif
1841             endif
1842         elseif type(a:000[0])==type("") && a:000[0]=="default"
1843             if !exists("b:transsymb")
1844                 let l:transsymb=g:trPluginDefaultTranssymb
1845             else
1846                 let l:transsymb=b:transsymb
1847             endif
1848         else
1849             echoerr "Неправильный аргумент!"
1850             return 3
1851         endif
1852         if len(a:000)>1
1853             if type(a:000[1])==type(0) || type(a:000[1])==type("")
1854                 if a:000[1]>0
1855                     let l:columns=a:000[1]
1856                 else
1857                     echoerr "Неверное количество столбцов!"
1858                     return 4
1859                 endif
1860             else
1861                 echoerr "Количество столбцов должно быть числом!"
1862                 return 5
1863             endif
1864         endif
1865     else
1866         if !exists("b:transsymb")
1867             let l:transsymb=g:trPluginDefaultTranssymb
1868         else
1869             let l:transsymb=b:transsymb
1870         endif
1871     endif
1872     let l:gotlist=s:TrShow(l:transsymb)
1873     let l:counts=[0, 0]
1874     for item in l:gotlist
1875         let l:len=len(substitute(item[0], ".", ".", "g"))
1876         if l:len>l:counts[0]
1877             let l:counts[0]=l:len
1878         endif
1879         let l:len=len(substitute(item[1], ".", ".", "g"))
1880         if l:len>l:counts[1]
1881             let l:counts[1]=l:len
1882         endif
1883     endfor
1884     if !l:columns
1885         " Если указать «+3» вместо  «+2», то если последний символ оказывается
1886         " в конце строки, то образуется лишняя пустая строка между каждой
1887         " строчкой. Значение «3» соответствует длине « ║ », значение «6»
1888         " соответствует «3+len(" ║ ")». Прибавление необходимо, так как в конце
1889         " строки « ║ » отсутствует. Значение «3» равно количеству столбцов минус
1890         " один (количеству промежутков между столбцами) плюс длине третьего
1891         " столбца, всегда равной единице.
1892         let l:columns=(winwidth(0)+2)/(l:counts[0]+l:counts[1]+6)
1893     endif
1894     let l:i=0
1895     let l:returnedstring=""
1896     let l:len=len(l:gotlist)
1897     let l:lnum=l:len/l:columns
1898     if !l:lnum
1899         let l:lnum=1
1900     endif
1901     " Условие проверяется дальше
1902     while 1
1903         let l:returnedstring.=
1904                     \s:PrintL(l:gotlist[(l:i/l:columns+(l:i%l:columns)*l:lnum)],
1905                         \l:counts)
1906         " Условие выхода из цикла
1907         if l:i==l:len-1
1908             break
1909         elseif l:i%l:columns==l:columns-1
1910             let l:returnedstring.="\n"
1911         else
1912             let l:returnedstring.=" ║ "
1913         endif
1914         let l:i+=1
1915     endwhile
1916     return l:returnedstring
1917 endfunction
1918 "{{{1 vim: ft=vim:ts=8:fdm=marker:fenc=utf-8:formatoptions-=a
1919
Hosted by uCoz