Показ дописів із міткою tips. Показати всі дописи
Показ дописів із міткою tips. Показати всі дописи

четвер, 27 грудня 2012 р.

Робота з файлами eml в Ruby

Сьогодні зіткнувся з проблемою пошуку вкладень серед багатьох файлів з розширенням eml.

Формат eml використовується багатьма клієнтами електронної пошти, включаючи Microsoft Outlook Express, Windows Mail і Mozilla Thunderbird. Це звичайний текстовий файл у форматі MIME, що містять заголовки повідомлень електронної пошти, а також вміст повідомлення та вкладення.

Відкрити його під Linux не складає труднощів, наприклад, за допомогою поштового клієнта KMail, однак таке рішення мені здалося занадто складним.

Трохи погугливши, виявилося, що бібліотека email чудово вміє розбирати такі файли.

В результаті вийшов невеликий скрипт, який вибирає всі файли з розширенням eml у поточній директорії, і відображає в консолі текстовий вміст листа, а прикріплені файли зберігає у відповідних директоріях.
require 'mail'

Dir.glob('*.eml') do |filename|
  mail = Mail.read(filename)

  puts <<EOF
  From:    #{mail.from}
  To:      #{mail.to}
  Subject: #{mail.subject}
  Date:    #{mail.date}

EOF

  charset = mail.text_part.content_type_parameters['charset']
  puts mail.text_part.body.decoded.force_encoding(charset).encode('utf-8')

  if mail.multipart?
    dir = File.basename(filename, File.extname(filename))
    Dir.mkdir(dir) if !Dir.exists?(dir)

    mail.attachments.each do |attachment|
      file = File.open(dir + '/' + attachment.filename, 'wb') { |f| f.write attachment.body.decoded }
      puts "Saving `#{attachment.filename}`"
    end
  end

  puts "===\n\n"
end

середа, 15 серпня 2012 р.

Стилізація sinatra-flash для Bootstrap

Про гем sinatra-flash, я писав у статті Flash-повідомлення і Sinatra
Задачею є створити замість стандартного styled_flash, методу-помінчника для Sinatra, який відображатиме попередження стилізовані під Bootstrap.


вівторок, 14 серпня 2012 р.

Як зробити локальий веб-сервер загальнодоступним

Сьогодні відкрив для себе чудовий сервіс, який дозволяє швидко і просто зробити локальний веб-сервер загальнодоступним в Інтернеті.

Зустрічайте ProxyLocal

Це програмне забезпечення складається з клієнтської і серверної частин. Серверна частина працює на сервері proxylocal.com, і ви можете використання його ресурси абсолютно безкоштовно. Клієнт написаний на мові Ruby і поширюється як gem, його вихідний код відкритий і доступний на GitHub.

Інсталяція

ProxyLocal - це утиліта командного рядка.

Відкрийте термінал і наберіть:
$ gem install proxylocal

Використання

Припустимо, ваш локальний веб-сервер запущений на порту 9292. Щоб зробити його загальнодоступним виконайте в терміналі:
$ proxylocal 9292
Local server on port 9292 is now publicly available via:
http://o18f.t.proxylocal.com/

Тепер ваш локальний сервер на порту 9292 доступний через:
http://o18f.t.proxylocal.com/

Також ви можете вказати бажане ім'я, яке ви хочете використовувати, наприклад:
$ proxylocal 9292 --host testhost
Local server on port 9292 is now publicly available via:
http://testhost.t.proxylocal.com/

четвер, 17 травня 2012 р.

Ведення логів у Mechanize

Для того, щоб проаналізувати, що пішло не так, коли Mechanize викликає виключення, виникає необхідність ведення логів. Mechanize може реєструвати практично будь-які події, включаючи заголовки запитів. Для цього потрібно передати екземпляр класу Logger у метод Mechanize#log.
# -*- encoding: utf-8 -*-

require 'mechanize'
require 'logger'

log = Logger.new($stderr)
log.level = Logger::DEBUG

agent = Mechanize.new do |a|
  a.log = log
end

agent.get('http://google.com')
Отриману інформацію надалі можна використати для аналізу подій, виявлення помилок та збоїв.
https://gist.github.com/2718143#file_mechanize1.log
Офіційна документація по класу Logger

Також існує менш відомий, але не менш корисний спосіб ведення логів за допомогою методу Mechanize#agent.http.debug_output:
# -*- encoding: utf-8 -*-

require 'mechanize'

agent = Mechanize.new do |a|
  a.agent.http.debug_output = $stderr
end

agent.get('http://google.com')
https://gist.github.com/2718143#file_mechanize2.log

пʼятниця, 11 травня 2012 р.

Інсталяція QtRuby з Ruby 1.9.3 на Ubuntu 12.04

  • Ubuntu 12.04 LTS
  • Остання версія Ruby 1.9.3p194 зібрана з RVM
  • Qt 4.8.1 з репозиторію
  • Остання стабільна версія QtRuby 2.2.0
sudo apt-get install cmake libqt4-dev libqwt5-qt4-dev libqscintilla2-dev libsmokeqt4-dev
wget http://rubyforge.org/frs/download.php/75633/qt4-qtruby-2.2.0.tar.gz
tar xzvf qt4-qtruby-2.2.0.tar.gz
cd qt4-qtruby-2.2.0/
cmake .
make
sudo make install
sudo ldconfig /usr/local/lib/

субота, 24 березня 2012 р.

Стилістика написання коду Ruby

Пару днів назад на GitHub створили спеціальний розділ, присвячений стилям написання коду. Доступні рекомендації для наступних мов:

Для Ruby багато що було взято з https://github.com/bbatsov/ruby-style-guide.

середа, 11 січня 2012 р.

Проблема з авторизацією ВКонтакте через OAuth2

Сьогодні стикнувся з помилкою при авторизації по OAuth ВКонтакте:
{"error":"invalid_request","error_description":"redirect_uri is incorrect"}
Виявляється, треба просто вказати правильний домен. Раніше якимось чином все працювало з невірним доменом.


неділя, 11 грудня 2011 р.

Ruby/Tk в RVM

Так як wxRuby не розвивається більше 2-ох років, а Qt4 надмірний для моїх задач. Вибір впав на бібліотеку Tk, яка поставляється разом з Ruby.

Tk (від англ. Toolkit — "набір інструментів", "інструментарій") - кросплатформна бібліотека базових елементів графічного інтерфейсу, яка розповсюджується відкритими вихідними текстами.

Для того щоб почати використовувати Tk достатньо імпортувати бібліотеку для роботи з нею:
require 'tk'
Якщо ви отримаєте помилку
LoadError: cannot load such file -- tk
значить Tk не скомпільована з вашим Ruby.
Якщо у вас RVM, ласкаво прошу під кат.

пʼятниця, 20 травня 2011 р.

Запуск текстового редактора в IRB

Якщо ви працюєте з Ruby, ви знаєте, що interactive ruby shell (або IRB для стислості) - це командна оболонка для програмування на мові Ruby. Програма запускається з командного рядка і дозволяє виконувати команди мови Ruby в реальному часі. IRB є чудовою для випробування однорядкового коду, але якщо вам потрібно написати більше блоків, вона починає не справлятися з роботою. Якщо вам потрібно змінити або додати один рядок у блок коду, доводиться повторно вводити всі команди одна за одною. Відчувається, що інтерфейс командного рядка IRB є обмеженим у порівнянні з силою вашого текстового редактора. У цьому дописі я збираюся показати, як ви можете взяти найкраще з обох світів, шляхом завантаження текстового редактора всередині IRB для редагування і подальшого виконання коду.

Існує бібліотека Interactive editor, що забезпечує цю функціональність. Вона доступна через gem:
$ gem install interactive_editor
Далі необхідно створити файл ~/.irbrc, якщо у вас його ще немає, і вставити в нього наступний рядок:
require 'interactive_editor'
Тоді можете використовувати його в irb:

$ irb                        # або його альтернатива ripl
> vi                         # (використовувати vi з тимчасовим файлом)
> vi 'filename.rb'           # (відкрити filename.rb в vi)
> ed                         # (використувуваьт змінну оточення EDITOR)
> [emacs|vim|mvim|nano|mate] # (інші редактори)

Додаткові матеріали:

четвер, 19 травня 2011 р.

Як визначити країну по IP адресі

Щоб дізнатися країну з IP адреси слід встановити geoip gem:
$ gem install geoip
Потім завантажити базу даних GeoLite Country, яка є безкоштовною за умови GPL/LGPL для API.
Розпакувати її кудись і використовувати як хочете.
Приклад:
require 'geoip'
geoip = GeoIP.new('GeoIP.dat')
country_location = geoip.country('8.8.4.4')
puts country_location.country_code2 # => "US"

вівторок, 15 березня 2011 р.

Nokogiri і XPath для розбору HTML таблиць

Вже третій місяць користуюся "Домашнім Інтернетом" від "Київстар". Система "Мій Київстар" дає змогу самостійно керувати своїми витратами в режимі онлайн. І звісно ж це вже потрібно автоматизувати. Для цього я буду використовувати наступні інструменти: Ruby, Mechanize, Nokogiri.

Аторизація на сайті Мій Київстар:

# -*- encoding: utf-8 -*-

require 'mechanize'
require 'nokogiri'

login    = '0010390***'
password = '***'

agent = Mechanize.new
agent.follow_meta_refresh = true

page = agent.get('https://my.kyivstar.ua/tbmb/login/perform.do')

login_form = page.form_with(:name => 'loginForm')
login_form.user     = login
login_form.password = password
show_page = agent.submit(login_form)

if show_page.uri.to_s == "https://my.kyivstar.ua/tbmb/disclaimer/show.do"
  puts "Login successful"
else
  puts "Login failure"
  exit
end

show_page_html = show_page.body.encode('utf-8', 'cp1251')

Розбір HTML таблиці використовуючи XPath:

doc = Nokogiri::HTML(show_page_html)
details = doc.search("//td[@id='mainContentBlock']/table/tr").collect do |row|
  title = row.at('td[1]').text.strip rescue ''
  data  = row.at('td[2]').text.strip.gsub("\n", " ") rescue ''
  {
    :title => title,
    :data  => data
  }
end

Вивід розпарсеної таблиці і поточного балансу:

pp details

balance = details.find {|e| e[:title] == "Поточний баланс:"}
puts "#{balance[:title]} #{balance[:data]}"

[{:title=>"Прізвище, ім'я, по-батькові:", :data=>"Іван Іванович"},
 {:title=>"Номер договору:", :data=>"0010390***"},
 {:title=>"Адреса підключення:", :data=>", Україна, Тернопіль"},
 {:title=>"Номер мобільного телефону:", :data=>"+38063*******"},
 {:title=>"Адреса електронної пошти:", :data=>"ivan.ivanovichlinux@gmail.com"},
 {:title=>nil, :data=>"Активуйте Вашу електронну адресу"},
 {:title=>nil, :data=>"Надіслати код активації"},
 {:title=>nil, :data=>nil},
 {:title=>"Особовий рахунок:", :data=>"0010390***"},
 {:title=>"Статус особового рахунка:", :data=>"Діючий"},
 {:title=>"Поточний баланс:", :data=>"55.09 грн."},
 {:title=>"Поріг відключення:", :data=>"0.0 грн."},
 {:title=>"Тарифний пакет:", :data=>"Турбо"},
 {:title=>"Статус послуги:", :data=>"Підключена"},
 {:title=>"Дата підключення:", :data=>"18.12.2010"}]
Поточний баланс: 55.09 грн.

субота, 4 грудня 2010 р.

Робота з неіснуючими ключами в Hash

Веду цей блог для написання безґлуздих думок (в основному шматків коду), щоб потім не гуглити їх заново.

Досить поширена задача:
Підрахувати кількість входжень кожного елементу (наприклад, IP-адрес з лог-файлу Apache). Очевидно, для цього потрібно використовувати Hash, щоб зберігати число лічильників для ключів. Можна просто виконувати операцію += 1 для членів хешу.

Варіант 1
> languages = {}
 => {}
> languages['ukrainian'] = 0
 => 0 
> languages['ukrainian'] += 1
 => 1 
> languages
 => {"ukrainian"=>1}
> languages['russian'] += 1
NoMethodError: undefined method `+' for nil:NilClass
В Ruby, ви повинні ініціалізувати змінні. Іншими словами, ви не можете використовувати зміст змінної, якщо її не існує.

Друге, що потрібно зробити - автоматично створювати пару ключ-значення, якщо ключа не існує.
> languages['russian'] = languages.fetch('russian', 0) + 1
 => 1 
> languages
 => {"ukrainian"=>1, "russian"=>1}

Всю магію тут виконує метод Hash#fetch(key [, default] ), який повертає значення з хешу для ключа key, а якщо його не знайдено, повертає значення default.

Варіант 2
Існує простіший спосіб. Встановити значення для ключа, якого не існує в хеші (по замовчуванняю це nil).
> languages = {}
 => {} 
> languages.default
 => nil 
> languages.default = 0
 => 0 
> languages['ukrainian'] += 1
 => 1 
> languages['russian'] += 1
 => 1 
> languages
 => {"ukrainian"=>1, "russian"=>1}
> languages['english']
 => 0
Зверніть увагу, якщо запитати ключ, якого не існує в хеші, то поверне значення по замовчуванню. Тут потрібно бути обережним.

Використовуйте в залежності від ваших задач. І не забувайте читати офіційну документацію.
Успіхів!

пʼятниця, 3 грудня 2010 р.

Вирішення проблем з Rack і Sinatra на Ruby 1.9.2

Оновив на веб-сервері Ruby до версії 1.9.2 і додаток на Sinatra валиться при спробі запуску.
Справа в тому, що $LOAD_PATH (він же $:) у Ruby 1.9.2 не містить шлях до поточного каталогу і require не бачить файл /.
Рішень є кілька:
  • замінити require на require_relative
  • прописати повний шлях до файлу
  • додати поточний каталог "./" до $LOAD_PATH
В моєму випадку допомогло прописати повний шлях у файлі config.ru:
require './hello'
run Sinatra::Application
І використання require_relative в hello.rb:
require 'sinatra'
require 'haml'

require_relative 'lib/api'

середа, 7 липня 2010 р.

Нові методи для роботи з масивами у Ruby 1.9.2

Робота з масивами та аналогічними об’єктами у Ruby є дуже простою. З Ruby 1.9.2 ми отримали більше цікавих можливостей :)

У файлі NEWS написано:
* Array
    * new method:
      * Array#keep_if
      * Array#repeated_combination
      * Array#repeated_permutation
      * Array#rotate
      * Array#rotate!
      * Array#select!
      * Array#sort_by!

    * extended methods:
      * Array#{uniq,uniq!,product} can take a block.
...
  * Enumerable
    * New methods:
      * Enumerable#chunk
      * Enumerable#collect_concat
      * Enumerable#each_entry
      * Enumerable#flat_map
      * Enumerable#slice_before

У цій статті коротко розглянемо ці методи.

субота, 19 червня 2010 р.

Аналог PHP функції strtr() на Ruby

В ході написання одного скрипта на Ruby, знадобився аналог PHP функції strtr().
Власне, функція повинна повертати рядок, у якому кожне входження будь-якого рядків із перелічених у from, замінюється на відповідний рядок з to. Функція приймає один аргумент, який повинен бути масивом, індекси якого трактуються як рядки пошуку, а відповідні значення - як рядки заміни. В першу чергу замінює більш довші підрядки.

class String
  def strtr(tr)
    sorted_tr = tr.sort{|a, b| b[0] <=> a[0]}
    keys = sorted_tr.map{|k, v| k}
    values = sorted_tr.map{|k, v| v}
    r = /(#{keys.map{|i| Regexp.escape(i)}.join( ')|(' )})/
    self.gsub(r){|match| values[keys.index(match)]}
  end
end

Приклад роботи:
tr1 = {'A' => '1', 'AA' => '2', 'AAA' => '3'}
tr2 = [['A', '1'],['AA', '2'],['AAA', '3']]
s = 'ABAACAAADAAAA'

puts s.strtr(tr1)
puts s.strtr(tr2)

1B2C3D31
1B2C3D31


UPD
Ще один варіант цієї функції. Коротший і зрозуміліший:
class String
  def strtr(tr)
    tr.sort{|a, b| b[0] <=> a[0]}.map.inject(self){|str, pair| str.gsub(pair[0], pair[1])}
  end
end


Але він не відповідає умові, що один і той же рядок пошуку використовується тільки один раз.

При вхідних даних:
s = "ABAACAAADAAAA"
tr = {"A"=>"AA", "AA"=>"AAAA", "AAA"=>"AAAAAA"}
s.strtr(tr)

Для першого варіанту отримаємо:
=> "AABAAAACAAAAAADAAAAAAAA"
а для другого:
=> "AABAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAA"

неділя, 14 червня 2009 р.

URL Encoding/Decoding with Ruby 1.9

Encode and decode a string for a URL with Ruby 1.9 (according to RFC 3986 and RFC 3629).

# URL encoded text:
enc_str = "http://uk.wikipedia.org/wiki/%D0%84%D0%B2%D1%80%D0%BE%D0%BF%D0%B0"

# Decode:
require 'cgi'
dec_str = CGI::unescape(enc_str)
=> http://uk.wikipedia.org/wiki/Європа
dec_str.encoding
=> #<Encoding:UTF-8>


# URL decoded text:
dec_str = "Декодований текст"

# Encode:
require 'cgi'
enc_str = CGI::escape(dec_str)
=> "%D0%94%D0%B5%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B9+%D1%82%D0%B5%D0%BA%D1%81%D1%82"
enc_str.encoding
=> #<Encoding:US-ASCII>

субота, 13 червня 2009 р.

Історія команд в irb

Якщо ви бажаєте, щоб історія введених команд зберігалася після закриття irb обов'язково додайте наступні рядки до ~/.irbrc
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb_history"

Крім того загляньте сюди: Автодоповнення в irb

понеділок, 8 червня 2009 р.

Відновлення GRUB у Ubuntu після встановлення Windows

Це допис ніяким боком не стосується основної теми блогу.
Більше того, про відновлення GRUB в інтернетах не писав мабуть тільки лінивий. Тому я не буду стояти осторонь і додам свої 5 копійок :).
Між іншим Ubuntu Linux перейшов на використання завантажувача Grub2.
На моїй машині в дуалбуті постійно мешкають Windows(зараз Windows 7) і Linux(зараз kubuntu 9.04). Сьогодні встановав Windows 7 build 7100. Як на мене система досить непогана і на перший погляд працює значно стабільніше свого попередника. Хоча я більше надаю перевагу Linux. Але це тема іншої історії.
Так от встановлювач Windows перезаписує завантажувальний розділ жорсткого диску, і встановлює туди свій завантажувач. Як тепер відновити grub, щоб можна було при старті машини звично обирати ОС для завантаження?
Розписую покрокову інстукцію для свої системи:


1. Завантажуємо графічний інсталятор kubuntu 9.04 і відкриваємо консоль.
2. Дивимось таблицю розділів:
ubuntu@ubuntu:~$ sudo fdisk -l /dev/sda

Disk /dev/sda: 250.0 GB, 250059350016 bytes
255 heads, 63 sectors/track, 30401 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x64920a32

Device Boot Start End Blocks Id System
/dev/sda1 * 1 2550 20482843+ 7 HPFS/NTFS
/dev/sda2 5101 30401 203230282+ f W95 Ext'd (LBA)
/dev/sda5 5101 11534 51681073+ 7 HPFS/NTFS
/dev/sda6 11535 18036 52227283+ 7 HPFS/NTFS
/dev/sda7 18037 19252 9767488+ 83 Linux
/dev/sda8 19253 19374 979933+ 82 Linux swap / Solaris
/dev/sda9 19375 30389 88477956 83 Linux
/dev/sda10 30390 30401 96358+ 83 Linux

де:
sda1 - розділ з windows.
sda5, sda6 - розділи де зберігається всякий хламу для windows.
sda7 - кореневий розділ ubuntu(fs ext4).
sda8 - розділ підкачки(swap) для linux.
sda10 - розділ boot.
sda9 - розділ файлосмітник для linux.

3. Далі необхідно примонтувати кореневий розділ ubuntu. Наприклад в /mnt/root.
ubuntu@ubuntu:~$ sudo mkdir /mnt/root/
ubuntu@ubuntu:~$ sudo mount -t ext4 /dev/sda7 /mnt/root/
ubuntu@ubuntu:~$ sudo mount /dev/sda10 /mnt/root/boot/
ubuntu@ubuntu:~$ sudo mount -t proc none /mnt/root/proc/
ubuntu@ubuntu:~$ sudo mount -o bind /dev/ /mnt/root/dev


4. Змінюємо кореневий розділ за допомогою chroot:
ubuntu@ubuntu:~$ sudo chroot /mnt/root/ /bin/bash
root@ubuntu:/#


5. Далі переходимо до командного рядка grub і встановлюємо завантажувач на /dev/sda:
root@ubuntu:/# grub
grub> root (hd0,9)
grub> setup (hd0)
Checking if "/boot/grub/stage1" exists... no
Checking if "/grub/stage1" exists... yes
Checking if "/grub/stage2" exists... yes
Checking if "/grub/e2fs_stage1_5" exists... yes
Running "embed /grub/e2fs_stage1_5 (hd0)"... 17 sectors are embedded.
succeeded
Running "install /grub/stage1 (hd0) (hd0)1+17 p (hd0,9)/grub/stage2 /grub/menu
.lst"... succeeded
Done.

grub>
Зверніть увагу! (hd0,9) == /dev/sda10.
Це повязане з тим, що номера розділів в Linux починаються з 1, тоді як Grub нумерує їх з 0.

6. Якщо все пройшло без помилок, то можна перевантажувати комп'ютер.

7. ???

8. PROFIT

понеділок, 9 березня 2009 р.

Eval і Ruby

У Ruby (та інших скриптових мовах) є метод eval, який отримує рядок і виконує цей рядок в поточному контексті
так (майже так), як ніби він був написана програмістом в місці виклику eval.
Власне, засоби, подібні eval, є і в компільованих мовах програмування.

Приклад для Ruby:
eval("puts 'Hello World'")

Вивід:
Hello World


Повертаючись до попереднього посту зробимо деякі зміни у коді.
Маємо метод, який повертає кількість нових повідомлень.
def new_messages
get_feed['messages']['count']
end


Аналогічно можна написати для фотографій(photos) і відео(videos)...
Керуючись філософською думкою DRY підемо іншим шляхом.
Замість того щоб писати 9 майже однакових методів, застосуємо силу eval.
[:friends, :messages, :events, :groups, :photos, :videos, :notes, :opinions, :offers].each do |type|
eval(<<-eomethod)
def new_#{type}
get_feed['#{type}']['count']
end
eomethod
end

Таким чином ми згенерували 9 нових методів для класу Vkontakte.

понеділок, 2 червня 2008 р.

Мій ~./vimrc

Цей допис не буде описувати структури конфігураційного файлу .vimrc.

Можливості:
  • ідентифікація типу файлу;
  • підстітка синтаксису;
  • заміна табуляції пробілами;
  • зміна кодування файлу для відкриття/зберігання;
  • зміна мови розкладки клавіатури;
  • перевірка орфографії;
  • статус-стрічка з інформацією про поточний файл;

Словники для перевірки орфографії можна скачати з сайту ftp://ftp.vim.org/pub/vim/runtime/spell/. Помістити необхідні файли *.spl в /usr/share/vim/vim70/spell/ .

set nocompatible          " We're running Vim, not Vi!
syntax on " Enable syntax highlighting
filetype plugin indent on " Enable filetype-specific indenting and plugging

set tabstop=2
set shiftwidth=2
set expandtab

set fileencodings=utf-8,cp1251,cp866,koi8-u
set encoding=utf-8
set termencoding=utf-8
set statusline=%<%f%h%m%r%=format=%{&fileformat}\ file=%{&fileencoding}\ spell=%{&spelllang}
set laststatus=2

" <F7> File fileformat (dos - <CR> <NL>, Unix - <NL>, mac - <CR>)
map <F7> :execute RotateFileFormat()<CR>
vmap <F7> <C-C><F7>
imap <F7> <C-O><F7>
let b:fformatindex=0

function! RotateFileFormat()
let y = -1
while y == -1
let encstring = "#unix#dos#mac#"
let x = match(encstring,"#",b:fformatindex)
let y = match(encstring,"#",x+1)
let b:fformatindex = x+1
if y == -1
let b:fformatindex = 0
else
let str = strpart(encstring,x+1,y-x-1)
return ":set fileformat=".str
endif
endwhile
endfunction

" <F8> File encoding for open
" ucs-2le - MS Windows Unicode encoding
map <F8> :execute RotateEnc()<CR>
vmap <F8> <C-C><F8>
imap <F8> <C-O><F8>
let b:encindex=0
function! RotateEnc()
let y = -1
while y == -1
let encstring = "#koi8-r#cp1251#8bit-cp866#utf-8#ucs-2le#"
let x = match(encstring,"#",b:encindex)
let y = match(encstring,"#",x+1)
let b:encindex = x+1
if y == -1
let b:encindex = 0
else
let str = strpart(encstring,x+1,y-x-1)
return ":e ++enc=".str
endif
endwhile
endfunction

" <Shift+F8> Force file encoding for open (encoding = fileencoding)
map <S-F8> :execute ForceRotateEnc()<CR>
vmap <S-F8> <C-C><S-F8>
imap <S-F8> <C-O><S-F8>
let b:encindex=0
function! ForceRotateEnc()
let y = -1
while y == -1
let encstring = "#koi8-r#cp1251#8bit-cp866#utf-8#ucs-2le#"
let x = match(encstring,"#",b:encindex)
let y = match(encstring,"#",x+1)
let b:encindex = x+1
if y == -1
let b:encindex = 0
else
let str = strpart(encstring,x+1,y-x-1)
:execute "set encoding=".str
return ":e ++enc=".str
endif
endwhile
endfunction

" <Ctrl+F8> File encoding for save (convert)
map <C-F8> :execute RotateFEnc()<CR>
vmap <C-F8> <C-C><C-F8>
imap <C-F8> <C-O><C-F8>
let b:fencindex=0
function! RotateFEnc()
let y = -1
while y == -1
let encstring = "#koi8-r#cp1251#8bit-cp866#utf-8#ucs-2le#"
let x = match(encstring,"#",b:fencindex)
let y = match(encstring,"#",x+1)
let b:fencindex = x+1
if y == -1
let b:fencindex = 0
else
let str = strpart(encstring,x+1,y-x-1)
return ":set fenc=".str
endif
endwhile
endfunction

" Russian support | CTRL+^
set keymap=russian-jcukenwin
" by default - latin keymap
set iminsert=0
" by default - latin keymap for search
set imsearch=0


" ftp://ftp.vim.org/pub/vim/runtime/spell/
if version >= 700
" По замовчуванню перевірка орфографії виключена.
setlocal spell spelllang=
setlocal nospell
function ChangeSpellLang()
if &spelllang =~ "en_us"
setlocal spell spelllang=ru
elseif &spelllang =~ "ru"
setlocal spell spelllang=uk
elseif &spelllang =~ "uk"
setlocal spell spelllang=en_us,ru,uk
elseif &spelllang =~ "en_us,ru,uk"
setlocal spell spelllang=
setlocal nospell
else
setlocal spell spelllang=en_us
endif
endfunc
" map spell on/off for English/Russian
map <F11> <Esc>:call ChangeSpellLang()<CR>
endif


Після перезапуску, Vim буде мати наступний вигляд: