Loading..

2014-05-27 @ 13:05

Manage Your Vim Plugins Using Pathogen and Git Submodules

If you use Vim for your everyday work, then you probably have some vim plugins too. There are tons of plugins out there to make Vim even more productive and enjoyable tool. I'm not going recommend you plugins I use on this place, but I will help you to manage yours.

Vim plugin management includes:

  • adding
  • removing
  • updating
  • installing on other machine
  • storing (in GitHub repository)

Before we start make sure you have Vim installed on your machine. Here is the way to install Vim on Debian based system. Mac users prefers MacVim and windows guys should consider to change their OS trollface or follow this guide.

Install git version control system and create an empty repository on GitHub. Optionally install Ruby for quick&easy installation of your vimfiles on your system.

I lied when I said "I'm not going recommend you plugins I use", because pathogen is must-have plugin for all Vim users! Pathogen allows us to save containing folder of a plugin in ~/.vim/bundle/ path and pathogen will manage the rest. For installation of pathogen follow the instructions in pathogen's repository.

File Structure

We will start by creating following file-structure:

mkdir -p vimfiles/vim vimfiles/vim/bundle vimfiles/vim/autoload
cp ~/.vimrc vimfiles/vimrc # or `touch vimfiles/vimrc`
wget https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim \
  -O vimfiles/autload/pathogen.vim
touch vimfiles/README.markdown

this is what we have so far:

vimfiles
|-- README.markdown
|-- vim
|   |-- autoload
|   `-- bundle
`-- vimrc

Make sure you have following lines in vimfiles/vimrc file:

execute pathogen#infect()
syntax on
filetype plugin indent on

Plugins as a Git Submodules

Now it's time to put our vim-files under version control and add our first plugin as a git submodule. I choosed vim-easymotion, but you can choose whatever plugin you like.

cd vimfiles
git init
git submodule add git@github.com:Lokaltog/vim-easymotion.git vim/bundle/vim-easymotion
git add --all
git commit -m "My awesome vimfiles"
# make sure you have GitHub respository and `git remote` is set
# git remote add origin git@github.com:user_name/vimfiles.git
git push origin -u master

Cool, now we have our vimfiles in remote repository. Let's delete them locally and install again:

cd ..
rm -rf vimfiles
# correct the url to point to you repository
git clone git@github.com:user_name/vimfiles.git
cd vimfiles

Now you may noticed that vimfiles/vim/bundle/vim-easymotion is empty. We have to some more steps to fetch that submodule:

git submodule init
git submodule update

You may also clone your vimfiles with --recursive option and git will do submodule init and submodule update for you:

git clone --recursive git@github.com:user_name/vimfiles.git

Yay! You have now current version of vim-easymotion plugin.

Updating Plugins

Let's now imagine we have added bunch of plugins using the system described above. How do we update them to the current version confused? Easy enough:

git submodule foreach git pull origin master
# if you want git to stfu:
# git submodule -q foreach git pull -q origin master

Very useful, isn't it?!

Remove plugins

You can do following in order to remove a plugin:

git submodule deinit vim/bundle/vim-easymotion
git rm vim/bundle/vim-easymotion
git rm --cached vim/bundle/vim-easymotion

This will work only with git1.8.3 (April 22d, 2013) and above. Please check this thread for more information on removing submodules.

We have now bunch of plugins, but Vim does not lunch them. We need a way to copy or symlink our vimfiles to the right place in our home directory (~/.vimrc and ~/.vim/):

ln -s $PWD/vim ~/.vim
ln -s $PWD/vimrc ~/.vimrc

works quite well in our case, but if you need a general way to install dotfiles into your home directory, then this script may be handy for you:

# Rakefile
require 'rake'

skip_files = %w[
  Rakefile
  README.markdown
]

desc "install vim files into user's home directory"
task :install do
  replace_all = false

  Dir['*'].each do |file|
    next if skip_files.include?(file)

    file_path = File.join(ENV['HOME'], ".#{file}")

    if File.exists?(file_path)
      if File.identical?(file, file_path)
        puts("identical #{file_path}")
      elsif replace_all
        replace_file(file, file_path)
      else
        print "overwrite #{file_path}? [ynaq]"
        case $stdin.gets.chomp
        when 'a'
          replace_all = true
          replace_file(file, file_path)
        when 'y'
          replace_file(file, file_path)
        when 'q'
          exit
        else
          puts "skipping #{file_path}"
        end
      end
    else
      link_file(file, file_path)
    end
  end
end

def replace_file(file, file_path)
  system "rm -rf #{file_path}"
  link_file(file, file_path)
end

def link_file(file, file_path)
  puts "linking #{file_path}"
  system %Q{ln -s "$PWD/#{file}" "#{file_path}"}
end

You have to install ruby and rake in order to get this to work. Afterwards you can just type rake install and all files|folders in the same directory like Rakefile will be symlinked to your $HOME prefixed with ..

show more »

2014-05-03 @ 15:20

i3 is awesome

It has been a while since I moved to i3. i3 is a fast, stable and overall very powerful tiling window manager, but "With great power comes great responsibility" and it could take bit time to adapt yourself to it. In this article I am going through my configuration to help you get more productive and have more fun with i3. Before you start reading make sure to check i3 User's Guide.

Name your workspaces

It is good idea to organize your applications instances within i3. You should constantly use the same workspace number for a certain type of an application. This way you don't have to search through your workspaces to find that god damn app. It may be quite hard to remember the number of workspace where is your wanted application located, that's why I recommend to name your workspaces. You can achieve that by adjusting this in your ~/.i3/config:

# workspace definitions
set $ws1 1: console
set $ws2 2: vim
set $ws3 3: logs
set $ws4 4: browser
set $ws5 5: mail
set $ws6 6: graphics
set $ws7 7: misc
set $ws8 8: misc
set $ws9 9: misc
set $ws10 10: misc

# switch to workspace
bindsym $mod+plus workspace $ws1
bindsym $mod+ecaron workspace $ws2
bindsym $mod+scaron workspace $ws3
bindsym $mod+ccaron workspace $ws4
bindsym $mod+rcaron workspace $ws5
bindsym $mod+zcaron workspace $ws6
bindsym $mod+yacute workspace $ws7
bindsym $mod+aacute workspace $ws8
bindsym $mod+iacute workspace $ws9
bindsym $mod+eacute workspace $ws10

# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace $ws1
bindsym $mod+Shift+2 move container to workspace $ws2
bindsym $mod+Shift+3 move container to workspace $ws3
bindsym $mod+Shift+4 move container to workspace $ws4
bindsym $mod+Shift+5 move container to workspace $ws5
bindsym $mod+Shift+6 move container to workspace $ws6
bindsym $mod+Shift+7 move container to workspace $ws7
bindsym $mod+Shift+8 move container to workspace $ws8
bindsym $mod+Shift+9 move container to workspace $ws9
bindsym $mod+Shift+0 move container to workspace $ws10

Make it Vim like

i3 comes with little strange mappings for switching between the windows. If your are used to vim's h j k l than it will drive you crazy - that's why this is necessary:

# change focus
bindsym $mod+h focus left
bindsym $mod+j focus down
bindsym $mod+k focus up
bindsym $mod+l focus right

# move focused window
bindsym $mod+Shift+h move left
bindsym $mod+Shift+j move down
bindsym $mod+Shift+k move up
bindsym $mod+Shift+l move right

# split in horizontal orientation
bindsym $mod+o split h

# split in vertical orientation
bindsym $mod+p split v

Get media buttons to work

# screenshot
bindsym Print exec scrot  ~/Pictures/Screenshots/screenshot_%Y_%m_%d_%H_%M_%S.png

# volume controls
bindsym XF86AudioRaiseVolume exec amixer -q -D pulse set Master playback 2%+ unmute
bindsym XF86AudioLowerVolume exec amixer -q -D pulse set Master playback 2%- unmute
bindsym XF86AudioMute exec amixer -q -D pulse set Master mute

# browser
bindsym XF86HomePage exec google-chrome

# mail
bindsym XF86Mail exec thunderbird

Multiple monitors

I mostly use 2 monitors - laptop monitor on the left side and additional monitor on the right side. I like to use odd workspace-numbers on the left monitor and even numbers on the right side. You can get monitors connected to you machine use the xrandr command (source) and then you can do something like this:

workspace "$ws1"  output LVDS
workspace "$ws2"  output CRT1
workspace "$ws3"  output LVDS
workspace "$ws4"  output CRT1
workspace "$ws5"  output LVDS
workspace "$ws6"  output CRT1
workspace "$ws7"  output LVDS
workspace "$ws8"  output CRT1
workspace "$ws9"  output LVDS
workspace "$ws10" output CRT1

Assigns some applications to a certain workspace

If you want to automatically start your applications on selected workspace. This feature is nicely described in User's guide. I recommend you to familiarize with xprop command.

assign [window_role="^browser$"] → $ws4
assign [class="^Mail$"] → $ws5
assign [class="^Gimp$"] → $ws8

Start applications in floating mode

for_window [window_role="pop-up"] floating enable
for_window [class="dosbox"] floating enable

Setup your wallpaper and get wi-fi applet to work

exec --no-startup-id feh --bg-fill ~/Copy/mutants.jpg
exec --no-startup-id nm-applet

Conclusion

As you can see i3 is really easy to setup. With little bit of effort you can adjust it to your longed-for needs.

show more »

2014-04-29 @ 19:56

Assignment methods in Ruby

You Rubyists probably know assignment methods. You can define one like this:

class Foo
  def foo=(x)
    @foo = x
  end
end

and then call it:

foo = Foo.new
# now calling the foo=() method
foo.foo = "foo"
# check if that worked
foo.instance_variable_get(:@foo) # => "foo"

, but do you know what are assignment methods returning? Are you sure? Let me show you a little bit remarkable example:

class AssignmentMethodsTester
  class << self
    def test=(x)
      return "Hello World"
    end
  end
end

AssignmentMethodsTester.test = 50 #=> 50
AssignmentMethodsTester.test=(50) #=> 50
AssignmentMethodsTester.send(:test=, 50) #=> "Hello World"

As you can see assignment like methods in Ruby are returning assigned value unless you invoke them using Object#send method.

show more »

About

Jiri Chara My name is Jiří Chára and I am an intermediate Ruby and JavaScript developer. I was born in Plzeň the home of the Pilsner Beer. I currently live in Karlsruhe, Germany together with my wife and my daughter. I work as a web developer at OrganisedMinds.

see more »



Copyright © 2014 Jiří Chára. All Rights Reserved.